1 //===- HexagonShuffler.h - Instruction bundle shuffling ---------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This implements the shuffling of insns inside a bundle according to the
10 // packet formation rules of the Hexagon ISA.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONSHUFFLER_H
15 #define LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONSHUFFLER_H
17 #include "MCTargetDesc/HexagonMCInstrInfo.h"
18 #include "MCTargetDesc/HexagonMCTargetDesc.h"
19 #include "llvm/ADT/DenseMap.h"
20 #include "llvm/ADT/SmallVector.h"
21 #include "llvm/ADT/StringRef.h"
22 #include "llvm/Support/MathExtras.h"
23 #include "llvm/Support/SMLoc.h"
32 class MCSubtargetInfo
;
35 class HexagonResource
{
36 // Mask of the slots or units that may execute the insn and
37 // the weight or priority that the insn requires to be assigned a slot.
38 unsigned Slots
, Weight
;
41 HexagonResource(unsigned s
) { setUnits(s
); }
43 void setUnits(unsigned s
) {
44 Slots
= s
& ((1u << HEXAGON_PACKET_SIZE
) - 1);
48 unsigned setWeight(unsigned s
);
50 unsigned getUnits() const { return (Slots
); }
51 unsigned getWeight() const { return (Weight
); }
53 // Check if the resources are in ascending slot order.
54 static bool lessUnits(const HexagonResource
&A
, const HexagonResource
&B
) {
55 return (countPopulation(A
.getUnits()) < countPopulation(B
.getUnits()));
58 // Check if the resources are in ascending weight order.
59 static bool lessWeight(const HexagonResource
&A
, const HexagonResource
&B
) {
60 return (A
.getWeight() < B
.getWeight());
64 // HVX insn resources.
65 class HexagonCVIResource
: public HexagonResource
{
67 using UnitsAndLanes
= std::pair
<unsigned, unsigned>;
68 using TypeUnitsAndLanes
= DenseMap
<unsigned, UnitsAndLanes
>;
71 // Available HVX slots.
81 // Count of adjacent slots that the insn requires to be executed.
83 // Flag whether the insn is a load or a store.
85 // Flag whether the HVX resources are valid.
88 void setLanes(unsigned l
) { Lanes
= l
; }
89 void setLoad(bool f
= true) { Load
= f
; }
90 void setStore(bool f
= true) { Store
= f
; }
93 HexagonCVIResource(TypeUnitsAndLanes
*TUL
, MCInstrInfo
const &MCII
,
94 unsigned s
, MCInst
const *id
);
96 static void SetupTUL(TypeUnitsAndLanes
*TUL
, StringRef CPU
);
98 bool isValid() const { return Valid
; }
99 unsigned getLanes() const { return Lanes
; }
100 bool mayLoad() const { return Load
; }
101 bool mayStore() const { return Store
; }
104 // Handle to an insn used by the shuffling algorithm.
106 friend class HexagonShuffler
;
109 MCInst
const *Extender
;
110 HexagonResource Core
;
111 HexagonCVIResource CVI
;
114 HexagonInstr(HexagonCVIResource::TypeUnitsAndLanes
*T
,
115 MCInstrInfo
const &MCII
, MCInst
const *id
,
116 MCInst
const *Extender
, unsigned s
)
117 : ID(id
), Extender(Extender
), Core(s
), CVI(T
, MCII
, s
, id
) {}
119 MCInst
const &getDesc() const { return *ID
; }
120 MCInst
const *getExtender() const { return Extender
; }
122 // Check if the handles are in ascending order for shuffling purposes.
123 bool operator<(const HexagonInstr
&B
) const {
124 return (HexagonResource::lessWeight(B
.Core
, Core
));
127 // Check if the handles are in ascending order by core slots.
128 static bool lessCore(const HexagonInstr
&A
, const HexagonInstr
&B
) {
129 return (HexagonResource::lessUnits(A
.Core
, B
.Core
));
132 // Check if the handles are in ascending order by HVX slots.
133 static bool lessCVI(const HexagonInstr
&A
, const HexagonInstr
&B
) {
134 return (HexagonResource::lessUnits(A
.CVI
, B
.CVI
));
139 class HexagonShuffler
{
140 using HexagonPacket
=
141 SmallVector
<HexagonInstr
, HEXAGON_PRESHUFFLE_PACKET_SIZE
>;
143 // Insn handles in a bundle.
144 HexagonPacket Packet
;
145 HexagonPacket PacketSave
;
147 HexagonCVIResource::TypeUnitsAndLanes TUL
;
152 MCInstrInfo
const &MCII
;
153 MCSubtargetInfo
const &STI
;
156 std::vector
<std::pair
<SMLoc
, std::string
>> AppliedRestrictions
;
157 void applySlotRestrictions();
158 void restrictSlot1AOK();
159 void restrictNoSlot1Store();
162 using iterator
= HexagonPacket::iterator
;
164 HexagonShuffler(MCContext
&Context
, bool ReportErrors
,
165 MCInstrInfo
const &MCII
, MCSubtargetInfo
const &STI
);
167 // Reset to initial state.
169 // Check if the bundle may be validly shuffled.
171 // Reorder the insn handles in the bundle.
174 unsigned size() const { return (Packet
.size()); }
176 bool isMemReorderDisabled() const {
177 return (BundleFlags
& HexagonMCInstrInfo::memReorderDisabledMask
) != 0;
180 iterator
begin() { return (Packet
.begin()); }
181 iterator
end() { return (Packet
.end()); }
183 // Add insn handle to the bundle .
184 void append(MCInst
const &ID
, MCInst
const *Extender
, unsigned S
);
186 // Return the error code for the last check or shuffling of the bundle.
187 void reportError(Twine
const &Msg
);
190 } // end namespace llvm
192 #endif // LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONSHUFFLER_H