15 #define DEBUG_TYPE "hexagon-shuffle"
36 enum { MAX = 360360 };
40 HexagonBid() : Bid(0){};
44 bool isSold()
const {
return (Bid >= MAX); };
53 class HexagonUnitAuction {
59 HexagonUnitAuction() : isSold(0){};
62 bool bid(
unsigned B) {
64 unsigned b = B & ~isSold;
69 Scores[
i] += HexagonBid(b);
70 isSold |= Scores[
i].isSold() <<
i;
82 const unsigned SlotWeight = 8;
83 const unsigned MaskWeight = SlotWeight - 1;
87 assert(SlotWeight * s < 32 &&
"Argument to setWeight too large.");
100 UnitsAndLanes(CVI_XLANE | CVI_SHIFT | CVI_MPY0 | CVI_MPY1, 1);
109 UnitsAndLanes(CVI_XLANE | CVI_SHIFT | CVI_MPY0 | CVI_MPY1, 1);
112 UnitsAndLanes(CVI_XLANE | CVI_SHIFT | CVI_MPY0 | CVI_MPY1, 1);
115 UnitsAndLanes(CVI_XLANE | CVI_SHIFT | CVI_MPY0 | CVI_MPY1, 1);
131 setLanes((*TUL)[T].second);
146 : MCII(MCII), STI(STI) {
158 unsigned S,
bool X) {
167 const unsigned slotSingleLoad = 0x1, slotSingleStore = 0x1, slotOne = 0x2,
168 slotThree = 0x8, slotFirstJump = 0x8, slotLastJump = 0x4,
169 slotFirstLoadStore = 0x2, slotLastLoadStore = 0x1;
171 unsigned slotJump = slotFirstJump;
172 unsigned slotLoadStore = slotFirstLoadStore;
174 unsigned jumps = 0, jump1 = 0;
177 unsigned memory = 0, loads = 0, load0 = 0,
stores = 0, store0 = 0, store1 = 0;
179 unsigned CVIloads = 0, CVIstores = 0;
181 unsigned duplex = 0, solo = 0;
184 unsigned onlyAX = 0, neitherAnorX = 0;
186 unsigned onlyAin1 = 0;
188 unsigned onlyNo1 = 0;
189 unsigned xtypeFloat = 0;
190 unsigned pSlot3Cnt = 0;
198 solo += !ISJ->isSoloException();
200 onlyAX += !ISJ->isSoloException();
202 onlyAin1 += !ISJ->isSoloException();
231 if (ISJ->Core.getUnits() == slotSingleLoad)
244 if (ISJ->Core.getUnits() == slotSingleStore)
268 if ((load0 > 1 || store0 > 1 || CVIloads > 1 || CVIstores > 1) ||
269 (duplex > 1 || (duplex && memory)) || (solo &&
size() > 1) ||
270 (onlyAX && neitherAnorX > 1) || (onlyAX && xtypeFloat)) {
275 if (jump1 && jumps > 1) {
283 bool bOnlySlot3 =
false;
287 if (!ISJ->Core.getUnits()) {
296 ISJ->Core.setUnits(ISJ->Core.getUnits() & ~slotOne);
301 ISJ->Core.setUnits(ISJ->Core.getUnits() & ~slotOne);
307 if (slotJump < slotLastJump) {
314 ISJ->Core.setUnits(ISJ->Core.getUnits() & slotJump);
321 if (loads == 1 && loads == memory)
323 ISJ->Core.setUnits(ISJ->Core.getUnits() & slotSingleLoad);
330 ISJ->Core.setUnits(ISJ->Core.getUnits() & slotSingleStore);
332 if (slotLoadStore < slotLastLoadStore) {
338 ISJ->Core.setUnits(ISJ->Core.getUnits() & slotLoadStore);
343 if (store1 &&
stores > 1) {
351 if (ISJ->Core.getUnits() == slotThree)
354 if (!ISJ->Core.getUnits()) {
361 bool validateSlots =
true;
362 if (bOnlySlot3 ==
false && pSlot3Cnt == 1 && slot3ISJ !=
end()) {
365 unsigned saveUnits = slot3ISJ->Core.getUnits();
366 slot3ISJ->Core.setUnits(saveUnits & slotThree);
368 HexagonUnitAuction AuctionCore;
374 if (!AuctionCore.bid(
I->Core.getUnits()))
379 validateSlots =
false;
384 ISJ->Core.setUnits(saveUnits);
391 HexagonUnitAuction AuctionCore;
396 if (!AuctionCore.bid(
I->Core.getUnits())) {
403 HexagonUnitAuction AuctionCVI;
408 for (
unsigned i = 0;
i <
I->CVI.getLanes(); ++
i)
409 if (!AuctionCVI.bid(
I->CVI.getUnits() <<
i)) {
433 unsigned slotSkip, slotWeight;
436 for (ISJ = ISK = Packet.
begin(), slotSkip = slotWeight = 0;
437 ISK != Packet.
end(); ++ISK, ++slotSkip)
438 if (slotSkip < nSlot - emptySlots)
443 slotWeight += ISK->Core.setWeight(HEXAGON_PACKET_SIZE - nSlot - 1);
448 std::sort(ISJ, Packet.
end());
bool isSoloAin1(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether the insn can be packaged only with an A-type insn in slot #1.
std::string & operator+=(std::string &buffer, StringRef string)
void push_back(const T &Elt)
static bool lessCore(const HexagonInstr &A, const HexagonInstr &B)
void setUnits(unsigned s)
unsigned getError() const
bool isReturn() const
Return true if the instruction is a return.
bool mayStore() const
Return true if this instruction could possibly modify memory.
bool isSolo(MCInstrInfo const &MCII, MCInst const &MCI)
unsigned setWeight(unsigned s)
No free slots for store insns.
#define HEXAGON_PACKET_SIZE
bool isBranch() const
Returns true if this is a conditional, unconditional, or indirect branch.
bool isCall() const
Return true if the instruction is a call.
bool isCofMax1(MCInstrInfo const &MCII, MCInst const &MCI)
StringRef getCPU() const
getCPU - Return the CPU string.
HexagonShuffler(MCInstrInfo const &MCII, MCSubtargetInfo const &STI)
unsigned getUnits() const
No free slots for branch insns.
raw_ostream & write_hex(unsigned long long N)
Output N in hexadecimal, without any prefix or padding.
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
Instances of this class represent a single low-level machine instruction.
HexagonCVIResource(TypeUnitsAndLanes *TUL, MCInstrInfo const &MCII, unsigned s, MCInst const *id)
std::size_t countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the least significant bit to the most stopping at the first 1...
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
Interface to description of machine instruction set.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
No free slots for other insns.
bool prefersSlot3(MCInstrInfo const &MCII, MCInst const &MCI)
unsigned getOpcode() const
Return the opcode number for this descriptor.
void append(MCInst const *ID, MCInst const *Extender, unsigned S, bool X=false)
unsigned countPopulation(T Value)
Count the number of set bits in a value.
bool mayLoad() const
Return true if this instruction could possibly read memory.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
size_type count(const KeyT &Val) const
Return 1 if the specified key is in the map, 0 otherwise.
bool isSoloAX(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether the insn can be packaged only with A and X-type insns.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
MCSubtargetInfo - Generic base class for all target subtargets.
MCInstrDesc const & getDesc(MCInstrInfo const &MCII, MCInst const &MCI)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool isFloat(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether it is a floating-point insn.
Lightweight error class with error context and mandatory checking.
std::pair< unsigned, unsigned > UnitsAndLanes
static bool lessCVI(const HexagonInstr &A, const HexagonInstr &B)
StringRef - Represent a constant reference to a string, i.e.
unsigned getType(MCInstrInfo const &MCII, MCInst const &MCI)
static void SetupTUL(TypeUnitsAndLanes *TUL, StringRef CPU)
bool check()
Check that the packet is legal and enforce relative insn order.