LLVM  6.0.0svn
HexagonShuffler.cpp
Go to the documentation of this file.
1 //===- HexagonShuffler.cpp - Instruction bundle shuffling -----------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This implements the shuffling of insns inside a bundle according to the
11 // packet formation rules of the Hexagon ISA.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #define DEBUG_TYPE "hexagon-shuffle"
16 
18 #include "Hexagon.h"
22 #include "llvm/ADT/SmallVector.h"
23 #include "llvm/ADT/Twine.h"
24 #include "llvm/MC/MCContext.h"
25 #include "llvm/MC/MCInst.h"
27 #include "llvm/Support/Compiler.h"
28 #include "llvm/Support/Debug.h"
31 #include <algorithm>
32 #include <cassert>
33 #include <utility>
34 #include <vector>
35 
36 using namespace llvm;
37 
38 namespace {
39 
40 // Insn shuffling priority.
41 class HexagonBid {
42  // The priority is directly proportional to how restricted the insn is based
43  // on its flexibility to run on the available slots. So, the fewer slots it
44  // may run on, the higher its priority.
45  enum { MAX = 360360 }; // LCD of 1/2, 1/3, 1/4,... 1/15.
46  unsigned Bid = 0;
47 
48 public:
49  HexagonBid() = default;
50  HexagonBid(unsigned B) { Bid = B ? MAX / countPopulation(B) : 0; }
51 
52  // Check if the insn priority is overflowed.
53  bool isSold() const { return (Bid >= MAX); }
54 
55  HexagonBid &operator+=(const HexagonBid &B) {
56  Bid += B.Bid;
57  return *this;
58  }
59 };
60 
61 // Slot shuffling allocation.
62 class HexagonUnitAuction {
63  HexagonBid Scores[HEXAGON_PACKET_SIZE];
64  // Mask indicating which slot is unavailable.
65  unsigned isSold : HEXAGON_PACKET_SIZE;
66 
67 public:
68  HexagonUnitAuction(unsigned cs = 0) : isSold(cs) {}
69 
70  // Allocate slots.
71  bool bid(unsigned B) {
72  // Exclude already auctioned slots from the bid.
73  unsigned b = B & ~isSold;
74  if (b) {
75  for (unsigned i = 0; i < HEXAGON_PACKET_SIZE; ++i)
76  if (b & (1 << i)) {
77  // Request candidate slots.
78  Scores[i] += HexagonBid(b);
79  isSold |= Scores[i].isSold() << i;
80  }
81  return true;
82  } else
83  // Error if the desired slots are already full.
84  return false;
85  }
86 };
87 
88 } // end anonymous namespace
89 
90 unsigned HexagonResource::setWeight(unsigned s) {
91  const unsigned SlotWeight = 8;
92  const unsigned MaskWeight = SlotWeight - 1;
93  unsigned Units = getUnits();
94  unsigned Key = ((1u << s) & Units) != 0;
95 
96  // Calculate relative weight of the insn for the given slot, weighing it the
97  // heavier the more restrictive the insn is and the lowest the slots that the
98  // insn may be executed in.
99  if (Key == 0 || Units == 0 || (SlotWeight * s >= 32))
100  return Weight = 0;
101 
102  unsigned Ctpop = countPopulation(Units);
103  unsigned Cttz = countTrailingZeros(Units);
104  Weight = (1u << (SlotWeight * s)) * ((MaskWeight - Ctpop) << Cttz);
105  return Weight;
106 }
107 
109  (*TUL)[HexagonII::TypeCVI_VA] =
110  UnitsAndLanes(CVI_XLANE | CVI_SHIFT | CVI_MPY0 | CVI_MPY1, 1);
111  (*TUL)[HexagonII::TypeCVI_VA_DV] = UnitsAndLanes(CVI_XLANE | CVI_MPY0, 2);
112  (*TUL)[HexagonII::TypeCVI_VX] = UnitsAndLanes(CVI_MPY0 | CVI_MPY1, 1);
113  (*TUL)[HexagonII::TypeCVI_VX_LATE] = UnitsAndLanes(CVI_MPY0 | CVI_MPY1, 1);
114  (*TUL)[HexagonII::TypeCVI_VX_DV] = UnitsAndLanes(CVI_MPY0, 2);
115  (*TUL)[HexagonII::TypeCVI_VP] = UnitsAndLanes(CVI_XLANE, 1);
116  (*TUL)[HexagonII::TypeCVI_VP_VS] = UnitsAndLanes(CVI_XLANE, 2);
117  (*TUL)[HexagonII::TypeCVI_VS] = UnitsAndLanes(CVI_SHIFT, 1);
119  (CPU == "hexagonv60")
120  ? UnitsAndLanes(CVI_SHIFT, 1)
121  : UnitsAndLanes(CVI_XLANE | CVI_SHIFT | CVI_MPY0 | CVI_MPY1, 1);
122  (*TUL)[HexagonII::TypeCVI_VM_LD] =
123  UnitsAndLanes(CVI_XLANE | CVI_SHIFT | CVI_MPY0 | CVI_MPY1, 1);
124  (*TUL)[HexagonII::TypeCVI_VM_TMP_LD] = UnitsAndLanes(CVI_NONE, 0);
125  (*TUL)[HexagonII::TypeCVI_VM_VP_LDU] = UnitsAndLanes(CVI_XLANE, 1);
126  (*TUL)[HexagonII::TypeCVI_VM_ST] =
127  UnitsAndLanes(CVI_XLANE | CVI_SHIFT | CVI_MPY0 | CVI_MPY1, 1);
128  (*TUL)[HexagonII::TypeCVI_VM_NEW_ST] = UnitsAndLanes(CVI_NONE, 0);
129  (*TUL)[HexagonII::TypeCVI_VM_STU] = UnitsAndLanes(CVI_XLANE, 1);
130  (*TUL)[HexagonII::TypeCVI_HIST] = UnitsAndLanes(CVI_XLANE, 4);
131 }
132 
134  MCInstrInfo const &MCII, unsigned s,
135  MCInst const *id)
136  : HexagonResource(s) {
137  unsigned T = HexagonMCInstrInfo::getType(MCII, *id);
138 
139  if (TUL->count(T)) {
140  // For an HVX insn.
141  Valid = true;
142  setUnits((*TUL)[T].first);
143  setLanes((*TUL)[T].second);
144  setLoad(HexagonMCInstrInfo::getDesc(MCII, *id).mayLoad());
145  setStore(HexagonMCInstrInfo::getDesc(MCII, *id).mayStore());
146  } else {
147  // For core insns.
148  Valid = false;
149  setUnits(0);
150  setLanes(0);
151  setLoad(false);
152  setStore(false);
153  }
154 }
155 
156 struct CVIUnits {
157  unsigned Units;
158  unsigned Lanes;
159 };
161 
162 static unsigned makeAllBits(unsigned startBit, unsigned Lanes)
163 {
164  for (unsigned i = 1; i < Lanes; ++i)
165  startBit = (startBit << 1) | startBit;
166  return startBit;
167 }
168 
169 static bool checkHVXPipes(const HVXInstsT &hvxInsts, unsigned startIdx,
170  unsigned usedUnits) {
171  if (startIdx < hvxInsts.size()) {
172  if (!hvxInsts[startIdx].Units)
173  return checkHVXPipes(hvxInsts, startIdx + 1, usedUnits);
174  for (unsigned b = 0x1; b <= 0x8; b <<= 1) {
175  if ((hvxInsts[startIdx].Units & b) == 0)
176  continue;
177  unsigned allBits = makeAllBits(b, hvxInsts[startIdx].Lanes);
178  if ((allBits & usedUnits) == 0) {
179  if (checkHVXPipes(hvxInsts, startIdx + 1, usedUnits | allBits))
180  return true;
181  }
182  }
183  return false;
184  }
185  return true;
186 }
187 
189  MCInstrInfo const &MCII,
190  MCSubtargetInfo const &STI)
191  : Context(Context), MCII(MCII), STI(STI), ReportErrors(ReportErrors) {
192  reset();
194 }
195 
197  Packet.clear();
198  BundleFlags = 0;
199 }
200 
201 void HexagonShuffler::append(MCInst const &ID, MCInst const *Extender,
202  unsigned S) {
203  HexagonInstr PI(&TUL, MCII, &ID, Extender, S);
204 
205  Packet.push_back(PI);
206 }
207 
208 static struct {
209  unsigned first;
210  unsigned second;
211 } jumpSlots[] = {{8, 4}, {8, 2}, {8, 1}, {4, 2}, {4, 1}, {2, 1}};
212 #define MAX_JUMP_SLOTS (sizeof(jumpSlots) / sizeof(jumpSlots[0]))
213 
214 /// Check that the packet is legal and enforce relative insn order.
216  // Descriptive slot masks.
217  const unsigned slotSingleLoad = 0x1, slotSingleStore = 0x1, slotOne = 0x2,
218  slotThree = 0x8, // slotFirstJump = 0x8,
219  slotFirstLoadStore = 0x2, slotLastLoadStore = 0x1;
220  // Highest slots for branches and stores used to keep their original order.
221  // unsigned slotJump = slotFirstJump;
222  unsigned slotLoadStore = slotFirstLoadStore;
223  // Number of branches, solo branches, indirect branches.
224  unsigned jumps = 0, jump1 = 0;
225  // Number of memory operations, loads, solo loads, stores, solo stores, single
226  // stores.
227  unsigned memory = 0, loads = 0, load0 = 0, stores = 0, store0 = 0, store1 = 0;
228  // Number of duplex insns
229  unsigned duplex = 0;
230  // Number of insns restricting other insns in slot #1 to A type.
231  unsigned onlyAin1 = 0;
232  // Number of insns restricting any insn in slot #1, except A2_nop.
233  unsigned onlyNo1 = 0;
234  unsigned pSlot3Cnt = 0;
235  unsigned nvstores = 0;
236  unsigned memops = 0;
237  unsigned deallocs = 0;
238  iterator slot3ISJ = end();
239  std::vector<iterator> foundBranches;
240  unsigned reservedSlots = 0;
241 
242  // Collect information from the insns in the packet.
243  for (iterator ISJ = begin(); ISJ != end(); ++ISJ) {
244  MCInst const &ID = ISJ->getDesc();
245 
247  ++onlyAin1;
249  ++pSlot3Cnt;
250  slot3ISJ = ISJ;
251  }
252  reservedSlots |= HexagonMCInstrInfo::getOtherReservedSlots(MCII, STI, ID);
254  ++jump1;
255 
256  switch (HexagonMCInstrInfo::getType(MCII, ID)) {
260  break;
261  case HexagonII::TypeJ:
262  ++jumps;
263  foundBranches.push_back(ISJ);
264  break;
266  ++onlyNo1;
270  case HexagonII::TypeLD:
271  ++loads;
272  ++memory;
273  if (ISJ->Core.getUnits() == slotSingleLoad ||
275  ++load0;
277  ++deallocs, ++jumps, ++jump1; // DEALLOC_RETURN is of type LD.
278  foundBranches.push_back(ISJ);
279  }
280  break;
282  ++onlyNo1;
286  case HexagonII::TypeST:
287  ++stores;
288  ++memory;
289  if (ISJ->Core.getUnits() == slotSingleStore ||
291  ++store0;
292  break;
294  ++loads;
295  ++stores;
296  ++store1;
297  ++memops;
298  ++memory;
299  break;
300  case HexagonII::TypeNCJ:
301  ++memory; // NV insns are memory-like.
302  ++jumps, ++jump1;
303  foundBranches.push_back(ISJ);
304  break;
306  if (HexagonMCInstrInfo::getDesc(MCII, ID).mayLoad()) {
307  ++loads;
308  ++memory;
309  if (ISJ->Core.getUnits() == slotSingleLoad ||
312  ++load0;
313  } else {
314  assert(HexagonMCInstrInfo::getDesc(MCII, ID).mayStore());
315  ++memory;
316  ++stores;
318  ++nvstores;
319  }
320  break;
321  case HexagonII::TypeCR:
322  // Legacy conditional branch predicated on a register.
323  case HexagonII::TypeCJ:
325  ++jumps;
326  foundBranches.push_back(ISJ);
327  }
328  break;
329  case HexagonII::TypeDUPLEX: {
330  ++duplex;
331  MCInst const &Inst0 = *ID.getOperand(0).getInst();
332  MCInst const &Inst1 = *ID.getOperand(1).getInst();
334  ++jump1;
336  ++jump1;
337  if (HexagonMCInstrInfo::getDesc(MCII, Inst0).isBranch()) {
338  ++jumps;
339  foundBranches.push_back(ISJ);
340  }
341  if (HexagonMCInstrInfo::getDesc(MCII, Inst1).isBranch()) {
342  ++jumps;
343  foundBranches.push_back(ISJ);
344  }
345  if (HexagonMCInstrInfo::getDesc(MCII, Inst0).isReturn()) {
346  ++deallocs, ++jumps, ++jump1; // DEALLOC_RETURN is of type LD.
347  foundBranches.push_back(ISJ);
348  }
349  if (HexagonMCInstrInfo::getDesc(MCII, Inst1).isReturn()) {
350  ++deallocs, ++jumps, ++jump1; // DEALLOC_RETURN is of type LD.
351  foundBranches.push_back(ISJ);
352  }
353  break;
354  }
355  }
356  }
357 
358  // Check if the packet is legal.
359  if ((load0 > 1 || store0 > 1) ||
360  (duplex > 1 || (duplex && memory))) {
361  reportError(Twine("invalid instruction packet"));
362  return false;
363  }
364 
365  if (jump1 && jumps > 1) {
366  // Error if single branch with another branch.
367  reportError(Twine("too many branches in packet"));
368  return false;
369  }
370  if ((nvstores || memops) && stores > 1) {
371  reportError(Twine("slot 0 instruction does not allow slot 1 store"));
372  return false;
373  }
374  if (deallocs && stores) {
375  reportError(Twine("slot 0 instruction does not allow slot 1 store"));
376  return false;
377  }
378 
379  // Modify packet accordingly.
380  // TODO: need to reserve slots #0 and #1 for duplex insns.
381  bool bOnlySlot3 = false;
382  for (iterator ISJ = begin(); ISJ != end(); ++ISJ) {
383  MCInst const &ID = ISJ->getDesc();
384 
385  if (!ISJ->Core.getUnits()) {
386  // Error if insn may not be executed in any slot.
387  return false;
388  }
389 
390  // Exclude from slot #1 any insn but A2_nop.
391  if (HexagonMCInstrInfo::getDesc(MCII, ID).getOpcode() != Hexagon::A2_nop)
392  if (onlyNo1)
393  ISJ->Core.setUnits(ISJ->Core.getUnits() & ~slotOne);
394 
395  // Exclude from slot #1 any insn but A-type.
399  if (onlyAin1)
400  ISJ->Core.setUnits(ISJ->Core.getUnits() & ~slotOne);
401 
402  // A single load must use slot #0.
404  if (loads == 1 && loads == memory && memops == 0)
405  // Pin the load to slot #0.
406  ISJ->Core.setUnits(ISJ->Core.getUnits() & slotSingleLoad);
407  }
408 
409  // A single store must use slot #0.
411  if (!store0) {
412  if (stores == 1)
413  ISJ->Core.setUnits(ISJ->Core.getUnits() & slotSingleStore);
414  else if (stores > 1) {
415  if (slotLoadStore < slotLastLoadStore) {
416  // Error if no more slots available for stores.
417  reportError(Twine("invalid instruction packet: too many stores"));
418  return false;
419  }
420  // Pin the store to the highest slot available to it.
421  ISJ->Core.setUnits(ISJ->Core.getUnits() & slotLoadStore);
422  // Update the next highest slot available to stores.
423  slotLoadStore >>= 1;
424  }
425  }
426  if (store1 && stores > 1) {
427  // Error if a single store with another store.
428  reportError(Twine("invalid instruction packet: too many stores"));
429  return false;
430  }
431  }
432 
433  // flag if an instruction requires to be in slot 3
434  if (ISJ->Core.getUnits() == slotThree)
435  bOnlySlot3 = true;
436 
437  if (!ISJ->Core.getUnits()) {
438  // Error if insn may not be executed in any slot.
439  reportError(Twine("invalid instruction packet: out of slots"));
440  return false;
441  }
442  }
443 
444  // preserve branch order
445  bool validateSlots = true;
446  if (jumps > 1) {
447  if (foundBranches.size() > 2) {
448  reportError(Twine("too many branches in packet"));
449  return false;
450  }
451 
452  // try all possible choices
453  for (unsigned int i = 0; i < MAX_JUMP_SLOTS; ++i) {
454  // validate first jump with this slot rule
455  if (!(jumpSlots[i].first & foundBranches[0]->Core.getUnits()))
456  continue;
457 
458  // validate second jump with this slot rule
459  if (!(jumpSlots[i].second & foundBranches[1]->Core.getUnits()))
460  continue;
461 
462  // both valid for this configuration, set new slot rules
463  PacketSave = Packet;
464  foundBranches[0]->Core.setUnits(jumpSlots[i].first);
465  foundBranches[1]->Core.setUnits(jumpSlots[i].second);
466 
467  HexagonUnitAuction AuctionCore(reservedSlots);
469 
470  // see if things ok with that instruction being pinned to slot "slotJump"
471  bool bFail = false;
472  for (iterator I = begin(); I != end() && !bFail; ++I)
473  if (!AuctionCore.bid(I->Core.getUnits()))
474  bFail = true;
475 
476  // if yes, great, if not then restore original slot mask
477  if (!bFail) {
478  validateSlots = false; // all good, no need to re-do auction
479  break;
480  } else
481  // restore original values
482  Packet = PacketSave;
483  }
484  if (validateSlots) {
485  reportError(Twine("invalid instruction packet: out of slots"));
486  return false;
487  }
488  }
489 
490  if (jumps <= 1 && !bOnlySlot3 && pSlot3Cnt == 1 && slot3ISJ != end()) {
491  validateSlots = true;
492  // save off slot mask of instruction marked with A_PREFER_SLOT3
493  // and then pin it to slot #3
494  unsigned saveUnits = slot3ISJ->Core.getUnits();
495  slot3ISJ->Core.setUnits(saveUnits & slotThree);
496 
497  HexagonUnitAuction AuctionCore(reservedSlots);
499 
500  // see if things ok with that instruction being pinned to slot #3
501  bool bFail = false;
502  for (iterator I = begin(); I != end() && !bFail; ++I)
503  if (!AuctionCore.bid(I->Core.getUnits()))
504  bFail = true;
505 
506  // if yes, great, if not then restore original slot mask
507  if (!bFail)
508  validateSlots = false; // all good, no need to re-do auction
509  else
510  for (iterator ISJ = begin(); ISJ != end(); ++ISJ) {
511  MCInst const &ID = ISJ->getDesc();
513  ISJ->Core.setUnits(saveUnits);
514  }
515  }
516 
517  // Check if any slot, core or CVI, is over-subscribed.
518  // Verify the core slot subscriptions.
519  if (validateSlots) {
520  HexagonUnitAuction AuctionCore(reservedSlots);
521 
523 
524  for (iterator I = begin(); I != end(); ++I)
525  if (!AuctionCore.bid(I->Core.getUnits())) {
526  reportError(Twine("invalid instruction packet: slot error"));
527  return false;
528  }
529  }
530  // Verify the CVI slot subscriptions.
532  // create vector of hvx instructions to check
533  HVXInstsT hvxInsts;
534  hvxInsts.clear();
535  for (iterator I = begin(); I != end(); ++I) {
536  struct CVIUnits inst;
537  inst.Units = I->CVI.getUnits();
538  inst.Lanes = I->CVI.getLanes();
539  if (inst.Units == 0)
540  continue; // not an hvx inst or an hvx inst that doesn't uses any pipes
541  hvxInsts.push_back(inst);
542  }
543  // if there are any hvx instructions in this packet, check pipe usage
544  if (hvxInsts.size() > 0) {
545  unsigned startIdx, usedUnits;
546  startIdx = usedUnits = 0x0;
547  if (!checkHVXPipes(hvxInsts, startIdx, usedUnits)) {
548  // too many pipes used to be valid
549  reportError(Twine("invalid instruction packet: slot error"));
550  return false;
551  }
552  }
553 
554  return true;
555 }
556 
558  if (size() > HEXAGON_PACKET_SIZE) {
559  // Ignore a packet with with more than what a packet can hold
560  // or with compound or duplex insns for now.
561  reportError(Twine("invalid instruction packet"));
562  return false;
563  }
564 
565  // Check and prepare packet.
566  bool Ok = true;
567  if (size() > 1 && (Ok = check()))
568  // Reorder the handles for each slot.
569  for (unsigned nSlot = 0, emptySlots = 0; nSlot < HEXAGON_PACKET_SIZE;
570  ++nSlot) {
571  iterator ISJ, ISK;
572  unsigned slotSkip, slotWeight;
573 
574  // Prioritize the handles considering their restrictions.
575  for (ISJ = ISK = Packet.begin(), slotSkip = slotWeight = 0;
576  ISK != Packet.end(); ++ISK, ++slotSkip)
577  if (slotSkip < nSlot - emptySlots)
578  // Note which handle to begin at.
579  ++ISJ;
580  else
581  // Calculate the weight of the slot.
582  slotWeight += ISK->Core.setWeight(HEXAGON_PACKET_SIZE - nSlot - 1);
583 
584  if (slotWeight)
585  // Sort the packet, favoring source order,
586  // beginning after the previous slot.
587  std::sort(ISJ, Packet.end());
588  else
589  // Skip unused slot.
590  ++emptySlots;
591  }
592 
593  for (iterator ISJ = begin(); ISJ != end(); ++ISJ)
594  DEBUG(dbgs().write_hex(ISJ->Core.getUnits()); if (ISJ->CVI.isValid()) {
595  dbgs() << '/';
596  dbgs().write_hex(ISJ->CVI.getUnits()) << '|';
597  dbgs() << ISJ->CVI.getLanes();
598  } dbgs() << ':'
599  << HexagonMCInstrInfo::getDesc(MCII, ISJ->getDesc()).getOpcode();
600  dbgs() << '\n');
601  DEBUG(dbgs() << '\n');
602 
603  return Ok;
604 }
605 
607  if (ReportErrors)
608  Context.reportError(Loc, Msg);
609 }
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)
Definition: StringRef.h:899
void push_back(const T &Elt)
Definition: SmallVector.h:212
static bool lessCore(const HexagonInstr &A, const HexagonInstr &B)
#define MAX_JUMP_SLOTS
void setUnits(unsigned s)
LLVMContext & Context
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
Definition: SmallVector.h:136
unsigned getOtherReservedSlots(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst const &MCI)
Return the slots this instruction consumes in addition to the slot(s) it can execute out of...
void append(MCInst const &ID, MCInst const *Extender, unsigned S)
unsigned second
unsigned setWeight(unsigned s)
bool mayLoad() const
Return true if this instruction could possibly read memory.
Definition: MCInstrDesc.h:387
bool isReturn() const
Return true if the instruction is a return.
Definition: MCInstrDesc.h:245
bool isNewValue(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether the insn expects newly produced value.
unsigned size() const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
#define HEXAGON_PACKET_SIZE
Definition: Hexagon.h:33
bool isCofMax1(MCInstrInfo const &MCII, MCInst const &MCI)
Context object for machine code objects.
Definition: MCContext.h:59
Key
PAL metadata keys.
HexagonPacket::iterator iterator
raw_ostream & write_hex(unsigned long long N)
Output N in hexadecimal, without any prefix or padding.
const MCInst * getInst() const
Definition: MCInst.h:106
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:159
HexagonCVIResource(TypeUnitsAndLanes *TUL, MCInstrInfo const &MCII, unsigned s, MCInst const *id)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
std::size_t countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0&#39;s from the least significant bit to the most stopping at the first 1...
Definition: MathExtras.h:112
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
Definition: SmallVector.h:116
MCSubtargetInfo const & STI
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:24
MCInstrDesc const & getDesc(MCInstrInfo const &MCII, MCInst const &MCI)
void reportError(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:570
bool prefersSlot3(MCInstrInfo const &MCII, MCInst const &MCI)
static unsigned makeAllBits(unsigned startBit, unsigned Lanes)
unsigned Units
unsigned first
unsigned countPopulation(T Value)
Count the number of set bits in a value.
Definition: MathExtras.h:512
MCInstrInfo const & MCII
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:864
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:180
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
StringRef getCPU() const
getCPU - Return the CPU string.
bool mayStore() const
Return true if this instruction could possibly modify memory.
Definition: MCInstrDesc.h:393
static struct @394 jumpSlots[]
std::pair< unsigned, unsigned > UnitsAndLanes
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
Definition: SmallVector.h:120
void reportError(Twine const &Msg)
HexagonShuffler(MCContext &Context, bool ReportErrors, MCInstrInfo const &MCII, MCSubtargetInfo const &STI)
#define I(x, y, z)
Definition: MD5.cpp:58
MCSubtargetInfo - Generic base class for all target subtargets.
static bool checkHVXPipes(const HVXInstsT &hvxInsts, unsigned startIdx, unsigned usedUnits)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Definition: DenseMap.h:141
unsigned Lanes
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isBranch(unsigned Opcode)
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
Definition: Compiler.h:235
unsigned getOpcode() const
Return the opcode number for this descriptor.
Definition: MCInstrDesc.h:203
#define DEBUG(X)
Definition: Debug.h:118
unsigned getUnits(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst const &MCI)
Return the slots used by the insn.
static bool lessCVI(const HexagonInstr &A, const HexagonInstr &B)
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
unsigned getType(MCInstrInfo const &MCII, MCInst const &MCI)
Return the Hexagon ISA class for the insn.
void sort(Policy policy, RandomAccessIterator Start, RandomAccessIterator End, const Comparator &Comp=Comparator())
Definition: Parallel.h:199
static void SetupTUL(TypeUnitsAndLanes *TUL, StringRef CPU)
hexagon widen stores
bool check()
Check that the packet is legal and enforce relative insn order.