LLVM  7.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"
30 #include "llvm/Support/SourceMgr.h"
32 #include <algorithm>
33 #include <cassert>
34 #include <utility>
35 #include <vector>
36 
37 using namespace llvm;
38 
39 namespace {
40 
41 // Insn shuffling priority.
42 class HexagonBid {
43  // The priority is directly proportional to how restricted the insn is based
44  // on its flexibility to run on the available slots. So, the fewer slots it
45  // may run on, the higher its priority.
46  enum { MAX = 360360 }; // LCD of 1/2, 1/3, 1/4,... 1/15.
47  unsigned Bid = 0;
48 
49 public:
50  HexagonBid() = default;
51  HexagonBid(unsigned B) { Bid = B ? MAX / countPopulation(B) : 0; }
52 
53  // Check if the insn priority is overflowed.
54  bool isSold() const { return (Bid >= MAX); }
55 
56  HexagonBid &operator+=(const HexagonBid &B) {
57  Bid += B.Bid;
58  return *this;
59  }
60 };
61 
62 // Slot shuffling allocation.
63 class HexagonUnitAuction {
64  HexagonBid Scores[HEXAGON_PACKET_SIZE];
65  // Mask indicating which slot is unavailable.
66  unsigned isSold : HEXAGON_PACKET_SIZE;
67 
68 public:
69  HexagonUnitAuction(unsigned cs = 0) : isSold(cs) {}
70 
71  // Allocate slots.
72  bool bid(unsigned B) {
73  // Exclude already auctioned slots from the bid.
74  unsigned b = B & ~isSold;
75  if (b) {
76  for (unsigned i = 0; i < HEXAGON_PACKET_SIZE; ++i)
77  if (b & (1 << i)) {
78  // Request candidate slots.
79  Scores[i] += HexagonBid(b);
80  isSold |= Scores[i].isSold() << i;
81  }
82  return true;
83  } else
84  // Error if the desired slots are already full.
85  return false;
86  }
87 };
88 
89 } // end anonymous namespace
90 
91 unsigned HexagonResource::setWeight(unsigned s) {
92  const unsigned SlotWeight = 8;
93  const unsigned MaskWeight = SlotWeight - 1;
94  unsigned Units = getUnits();
95  unsigned Key = ((1u << s) & Units) != 0;
96 
97  // Calculate relative weight of the insn for the given slot, weighing it the
98  // heavier the more restrictive the insn is and the lowest the slots that the
99  // insn may be executed in.
100  if (Key == 0 || Units == 0 || (SlotWeight * s >= 32))
101  return Weight = 0;
102 
103  unsigned Ctpop = countPopulation(Units);
104  unsigned Cttz = countTrailingZeros(Units);
105  Weight = (1u << (SlotWeight * s)) * ((MaskWeight - Ctpop) << Cttz);
106  return Weight;
107 }
108 
110  (*TUL)[HexagonII::TypeCVI_VA] =
111  UnitsAndLanes(CVI_XLANE | CVI_SHIFT | CVI_MPY0 | CVI_MPY1, 1);
112  (*TUL)[HexagonII::TypeCVI_VA_DV] = UnitsAndLanes(CVI_XLANE | CVI_MPY0, 2);
113  (*TUL)[HexagonII::TypeCVI_VX] = UnitsAndLanes(CVI_MPY0 | CVI_MPY1, 1);
114  (*TUL)[HexagonII::TypeCVI_VX_LATE] = UnitsAndLanes(CVI_MPY0 | CVI_MPY1, 1);
115  (*TUL)[HexagonII::TypeCVI_VX_DV] = UnitsAndLanes(CVI_MPY0, 2);
116  (*TUL)[HexagonII::TypeCVI_VP] = UnitsAndLanes(CVI_XLANE, 1);
117  (*TUL)[HexagonII::TypeCVI_VP_VS] = UnitsAndLanes(CVI_XLANE, 2);
118  (*TUL)[HexagonII::TypeCVI_VS] = UnitsAndLanes(CVI_SHIFT, 1);
119  (*TUL)[HexagonII::TypeCVI_VS_VX] = UnitsAndLanes(CVI_XLANE | CVI_SHIFT, 1);
121  (CPU == "hexagonv60")
122  ? UnitsAndLanes(CVI_SHIFT, 1)
123  : UnitsAndLanes(CVI_XLANE | CVI_SHIFT | CVI_MPY0 | CVI_MPY1, 1);
124  (*TUL)[HexagonII::TypeCVI_VM_LD] =
125  UnitsAndLanes(CVI_XLANE | CVI_SHIFT | CVI_MPY0 | CVI_MPY1, 1);
126  (*TUL)[HexagonII::TypeCVI_VM_TMP_LD] = UnitsAndLanes(CVI_NONE, 0);
127  (*TUL)[HexagonII::TypeCVI_VM_VP_LDU] = UnitsAndLanes(CVI_XLANE, 1);
128  (*TUL)[HexagonII::TypeCVI_VM_ST] =
129  UnitsAndLanes(CVI_XLANE | CVI_SHIFT | CVI_MPY0 | CVI_MPY1, 1);
130  (*TUL)[HexagonII::TypeCVI_VM_NEW_ST] = UnitsAndLanes(CVI_NONE, 0);
131  (*TUL)[HexagonII::TypeCVI_VM_STU] = UnitsAndLanes(CVI_XLANE, 1);
132  (*TUL)[HexagonII::TypeCVI_HIST] = UnitsAndLanes(CVI_XLANE, 4);
133  (*TUL)[HexagonII::TypeCVI_GATHER] =
134  UnitsAndLanes(CVI_XLANE | CVI_SHIFT | CVI_MPY0 | CVI_MPY1, 1);
136  UnitsAndLanes(CVI_XLANE | CVI_SHIFT | CVI_MPY0 | CVI_MPY1, 1);
138  UnitsAndLanes(CVI_XLANE | CVI_MPY0, 2);
140  UnitsAndLanes(CVI_XLANE | CVI_SHIFT | CVI_MPY0 | CVI_MPY1, 1);
141 }
142 
144  MCInstrInfo const &MCII, unsigned s,
145  MCInst const *id)
146  : HexagonResource(s) {
147  unsigned T = HexagonMCInstrInfo::getType(MCII, *id);
148 
149  if (TUL->count(T)) {
150  // For an HVX insn.
151  Valid = true;
152  setUnits((*TUL)[T].first);
153  setLanes((*TUL)[T].second);
154  setLoad(HexagonMCInstrInfo::getDesc(MCII, *id).mayLoad());
155  setStore(HexagonMCInstrInfo::getDesc(MCII, *id).mayStore());
156  } else {
157  // For core insns.
158  Valid = false;
159  setUnits(0);
160  setLanes(0);
161  setLoad(false);
162  setStore(false);
163  }
164 }
165 
166 struct CVIUnits {
167  unsigned Units;
168  unsigned Lanes;
169 };
171 
172 static unsigned makeAllBits(unsigned startBit, unsigned Lanes)
173 {
174  for (unsigned i = 1; i < Lanes; ++i)
175  startBit = (startBit << 1) | startBit;
176  return startBit;
177 }
178 
179 static bool checkHVXPipes(const HVXInstsT &hvxInsts, unsigned startIdx,
180  unsigned usedUnits) {
181  if (startIdx < hvxInsts.size()) {
182  if (!hvxInsts[startIdx].Units)
183  return checkHVXPipes(hvxInsts, startIdx + 1, usedUnits);
184  for (unsigned b = 0x1; b <= 0x8; b <<= 1) {
185  if ((hvxInsts[startIdx].Units & b) == 0)
186  continue;
187  unsigned allBits = makeAllBits(b, hvxInsts[startIdx].Lanes);
188  if ((allBits & usedUnits) == 0) {
189  if (checkHVXPipes(hvxInsts, startIdx + 1, usedUnits | allBits))
190  return true;
191  }
192  }
193  return false;
194  }
195  return true;
196 }
197 
199  MCInstrInfo const &MCII,
200  MCSubtargetInfo const &STI)
201  : Context(Context), MCII(MCII), STI(STI), ReportErrors(ReportErrors) {
202  reset();
204 }
205 
207  Packet.clear();
208  BundleFlags = 0;
209 }
210 
211 void HexagonShuffler::append(MCInst const &ID, MCInst const *Extender,
212  unsigned S) {
213  HexagonInstr PI(&TUL, MCII, &ID, Extender, S);
214 
215  Packet.push_back(PI);
216 }
217 
218 static struct {
219  unsigned first;
220  unsigned second;
221 } jumpSlots[] = {{8, 4}, {8, 2}, {8, 1}, {4, 2}, {4, 1}, {2, 1}};
222 #define MAX_JUMP_SLOTS (sizeof(jumpSlots) / sizeof(jumpSlots[0]))
223 
225  bool HasRestrictSlot1AOK = false;
226  SMLoc RestrictLoc;
227  for (iterator ISJ = begin(); ISJ != end(); ++ISJ) {
228  MCInst const &Inst = ISJ->getDesc();
230  HasRestrictSlot1AOK = true;
231  RestrictLoc = Inst.getLoc();
232  }
233  }
234  if (HasRestrictSlot1AOK)
235  for (iterator ISJ = begin(); ISJ != end(); ++ISJ) {
236  MCInst const &Inst = ISJ->getDesc();
237  unsigned Type = HexagonMCInstrInfo::getType(MCII, Inst);
238  if (Type != HexagonII::TypeALU32_2op &&
239  Type != HexagonII::TypeALU32_3op &&
240  Type != HexagonII::TypeALU32_ADDI) {
241  unsigned Units = ISJ->Core.getUnits();
242  if (Units & 2U) {
243  AppliedRestrictions.push_back(std::make_pair(
244  Inst.getLoc(),
245  "Instruction was restricted from being in slot 1"));
246  AppliedRestrictions.push_back(
247  std::make_pair(RestrictLoc, "Instruction can only be combine "
248  "with an ALU instruction in slot 1"));
249  ISJ->Core.setUnits(Units & ~2U);
250  }
251  }
252  }
253 }
254 
256  bool HasRestrictNoSlot1Store = false;
257  SMLoc RestrictLoc;
258  for (iterator ISJ = begin(); ISJ != end(); ++ISJ) {
259  MCInst const &Inst = ISJ->getDesc();
261  HasRestrictNoSlot1Store = true;
262  RestrictLoc = Inst.getLoc();
263  }
264  }
265  if (HasRestrictNoSlot1Store) {
266  bool AppliedRestriction = false;
267  for (iterator ISJ = begin(); ISJ != end(); ++ISJ) {
268  MCInst const &Inst = ISJ->getDesc();
269  if (HexagonMCInstrInfo::getDesc(MCII, Inst).mayStore()) {
270  unsigned Units = ISJ->Core.getUnits();
271  if (Units & 2U) {
272  AppliedRestriction = true;
273  AppliedRestrictions.push_back(std::make_pair(
274  Inst.getLoc(),
275  "Instruction was restricted from being in slot 1"));
276  ISJ->Core.setUnits(Units & ~2U);
277  }
278  }
279  }
280  if (AppliedRestriction)
281  AppliedRestrictions.push_back(std::make_pair(
282  RestrictLoc, "Instruction does not allow a store in slot 1"));
283  }
284 }
285 
289 }
290 
291 /// Check that the packet is legal and enforce relative insn order.
293  // Descriptive slot masks.
294  const unsigned slotSingleLoad = 0x1, slotSingleStore = 0x1,
295  slotThree = 0x8, // slotFirstJump = 0x8,
296  slotFirstLoadStore = 0x2, slotLastLoadStore = 0x1;
297  // Highest slots for branches and stores used to keep their original order.
298  // unsigned slotJump = slotFirstJump;
299  unsigned slotLoadStore = slotFirstLoadStore;
300  // Number of memory operations, loads, solo loads, stores, solo stores, single
301  // stores.
302  unsigned memory = 0, loads = 0, load0 = 0, stores = 0, store0 = 0, store1 = 0;
303  // Number of duplex insns
304  unsigned duplex = 0;
305  unsigned pSlot3Cnt = 0;
306  unsigned memops = 0;
307  iterator slot3ISJ = end();
308  std::vector<iterator> foundBranches;
309  unsigned reservedSlots = 0;
310 
311  // Collect information from the insns in the packet.
312  for (iterator ISJ = begin(); ISJ != end(); ++ISJ) {
313  MCInst const &ID = ISJ->getDesc();
314 
316  ++pSlot3Cnt;
317  slot3ISJ = ISJ;
318  }
319  reservedSlots |= HexagonMCInstrInfo::getOtherReservedSlots(MCII, STI, ID);
320 
321  switch (HexagonMCInstrInfo::getType(MCII, ID)) {
325  break;
326  case HexagonII::TypeJ:
327  foundBranches.push_back(ISJ);
328  break;
334  case HexagonII::TypeLD:
335  ++loads;
336  ++memory;
337  if (ISJ->Core.getUnits() == slotSingleLoad ||
339  ++load0;
341  foundBranches.push_back(ISJ);
342  break;
351  case HexagonII::TypeST:
352  ++stores;
353  ++memory;
354  if (ISJ->Core.getUnits() == slotSingleStore ||
356  ++store0;
357  break;
359  ++loads;
360  ++stores;
361  ++store1;
362  ++memops;
363  ++memory;
364  break;
365  case HexagonII::TypeNCJ:
366  ++memory; // NV insns are memory-like.
367  foundBranches.push_back(ISJ);
368  break;
370  if (HexagonMCInstrInfo::getDesc(MCII, ID).mayLoad()) {
371  ++loads;
372  ++memory;
373  if (ISJ->Core.getUnits() == slotSingleLoad ||
376  ++load0;
377  } else {
378  assert(HexagonMCInstrInfo::getDesc(MCII, ID).mayStore());
379  ++memory;
380  ++stores;
381  }
382  break;
383  case HexagonII::TypeCR:
384  // Legacy conditional branch predicated on a register.
385  case HexagonII::TypeCJ:
387  foundBranches.push_back(ISJ);
388  break;
389  case HexagonII::TypeDUPLEX: {
390  ++duplex;
391  MCInst const &Inst0 = *ID.getOperand(0).getInst();
392  MCInst const &Inst1 = *ID.getOperand(1).getInst();
394  foundBranches.push_back(ISJ);
396  foundBranches.push_back(ISJ);
397  if (HexagonMCInstrInfo::getDesc(MCII, Inst0).isReturn())
398  foundBranches.push_back(ISJ);
399  if (HexagonMCInstrInfo::getDesc(MCII, Inst1).isReturn())
400  foundBranches.push_back(ISJ);
401  break;
402  }
403  }
404  }
406 
407  // Check if the packet is legal.
408  if ((load0 > 1 || store0 > 1) || (duplex > 1 || (duplex && memory))) {
409  reportError(llvm::Twine("invalid instruction packet"));
410  return false;
411  }
412 
413  // Modify packet accordingly.
414  // TODO: need to reserve slots #0 and #1 for duplex insns.
415  bool bOnlySlot3 = false;
416  for (iterator ISJ = begin(); ISJ != end(); ++ISJ) {
417  MCInst const &ID = ISJ->getDesc();
418 
419  if (!ISJ->Core.getUnits()) {
420  // Error if insn may not be executed in any slot.
421  return false;
422  }
423 
424  // A single load must use slot #0.
426  if (loads == 1 && loads == memory && memops == 0)
427  // Pin the load to slot #0.
428  switch (ID.getOpcode()) {
429  case Hexagon::V6_vgathermw:
430  case Hexagon::V6_vgathermh:
431  case Hexagon::V6_vgathermhw:
432  case Hexagon::V6_vgathermwq:
433  case Hexagon::V6_vgathermhq:
434  case Hexagon::V6_vgathermhwq:
435  // Slot1 only loads
436  break;
437  default:
438  ISJ->Core.setUnits(ISJ->Core.getUnits() & slotSingleLoad);
439  break;
440  }
441  else if (loads >= 1 && isMemReorderDisabled()) { // }:mem_noshuf
442  // Loads must keep the original order ONLY if
443  // isMemReorderDisabled() == true
444  if (slotLoadStore < slotLastLoadStore) {
445  // Error if no more slots available for loads.
446  reportError(
447  llvm::Twine("invalid instruction packet: too many loads"));
448  return false;
449  }
450  // Pin the load to the highest slot available to it.
451  ISJ->Core.setUnits(ISJ->Core.getUnits() & slotLoadStore);
452  // Update the next highest slot available to loads.
453  slotLoadStore >>= 1;
454  }
455  }
456 
457  // A single store must use slot #0.
459  if (!store0) {
460  if (stores == 1 && (loads == 0 || !isMemReorderDisabled()))
461  // Pin the store to slot #0 only if isMemReorderDisabled() == false
462  ISJ->Core.setUnits(ISJ->Core.getUnits() & slotSingleStore);
463  else if (stores >= 1) {
464  if (slotLoadStore < slotLastLoadStore) {
465  // Error if no more slots available for stores.
466  reportError(Twine("invalid instruction packet: too many stores"));
467  return false;
468  }
469  // Pin the store to the highest slot available to it.
470  ISJ->Core.setUnits(ISJ->Core.getUnits() & slotLoadStore);
471  // Update the next highest slot available to stores.
472  slotLoadStore >>= 1;
473  }
474  }
475  if (store1 && stores > 1) {
476  // Error if a single store with another store.
477  reportError(Twine("invalid instruction packet: too many stores"));
478  return false;
479  }
480  }
481 
482  // flag if an instruction requires to be in slot 3
483  if (ISJ->Core.getUnits() == slotThree)
484  bOnlySlot3 = true;
485 
486  if (!ISJ->Core.getUnits()) {
487  // Error if insn may not be executed in any slot.
488  reportError(Twine("invalid instruction packet: out of slots"));
489  return false;
490  }
491  }
492 
493  // preserve branch order
494  bool validateSlots = true;
495  if (foundBranches.size() > 1) {
496  if (foundBranches.size() > 2) {
497  reportError(Twine("too many branches in packet"));
498  return false;
499  }
500 
501  // try all possible choices
502  for (unsigned int i = 0; i < MAX_JUMP_SLOTS; ++i) {
503  // validate first jump with this slot rule
504  if (!(jumpSlots[i].first & foundBranches[0]->Core.getUnits()))
505  continue;
506 
507  // validate second jump with this slot rule
508  if (!(jumpSlots[i].second & foundBranches[1]->Core.getUnits()))
509  continue;
510 
511  // both valid for this configuration, set new slot rules
512  PacketSave = Packet;
513  foundBranches[0]->Core.setUnits(jumpSlots[i].first);
514  foundBranches[1]->Core.setUnits(jumpSlots[i].second);
515 
516  HexagonUnitAuction AuctionCore(reservedSlots);
517  std::stable_sort(begin(), end(), HexagonInstr::lessCore);
518 
519  // see if things ok with that instruction being pinned to slot "slotJump"
520  bool bFail = false;
521  for (iterator I = begin(); I != end() && !bFail; ++I)
522  if (!AuctionCore.bid(I->Core.getUnits()))
523  bFail = true;
524 
525  // if yes, great, if not then restore original slot mask
526  if (!bFail) {
527  validateSlots = false; // all good, no need to re-do auction
528  break;
529  } else
530  // restore original values
531  Packet = PacketSave;
532  }
533  if (validateSlots) {
534  reportError(Twine("invalid instruction packet: out of slots"));
535  return false;
536  }
537  }
538 
539  if (foundBranches.size() <= 1 && bOnlySlot3 == false && pSlot3Cnt == 1 &&
540  slot3ISJ != end()) {
541  validateSlots = true;
542  // save off slot mask of instruction marked with A_PREFER_SLOT3
543  // and then pin it to slot #3
544  unsigned saveUnits = slot3ISJ->Core.getUnits();
545  slot3ISJ->Core.setUnits(saveUnits & slotThree);
546 
547  HexagonUnitAuction AuctionCore(reservedSlots);
548  std::stable_sort(begin(), end(), HexagonInstr::lessCore);
549 
550  // see if things ok with that instruction being pinned to slot #3
551  bool bFail = false;
552  for (iterator I = begin(); I != end() && !bFail; ++I)
553  if (!AuctionCore.bid(I->Core.getUnits()))
554  bFail = true;
555 
556  // if yes, great, if not then restore original slot mask
557  if (!bFail)
558  validateSlots = false; // all good, no need to re-do auction
559  else
560  for (iterator ISJ = begin(); ISJ != end(); ++ISJ) {
561  MCInst const &ID = ISJ->getDesc();
563  ISJ->Core.setUnits(saveUnits);
564  }
565  }
566 
567  // Check if any slot, core or CVI, is over-subscribed.
568  // Verify the core slot subscriptions.
569  if (validateSlots) {
570  HexagonUnitAuction AuctionCore(reservedSlots);
571 
572  std::stable_sort(begin(), end(), HexagonInstr::lessCore);
573 
574  for (iterator I = begin(); I != end(); ++I)
575  if (!AuctionCore.bid(I->Core.getUnits())) {
576  reportError(Twine("invalid instruction packet: slot error"));
577  return false;
578  }
579  }
580  // Verify the CVI slot subscriptions.
581  std::stable_sort(begin(), end(), HexagonInstr::lessCVI);
582  // create vector of hvx instructions to check
583  HVXInstsT hvxInsts;
584  hvxInsts.clear();
585  for (iterator I = begin(); I != end(); ++I) {
586  struct CVIUnits inst;
587  inst.Units = I->CVI.getUnits();
588  inst.Lanes = I->CVI.getLanes();
589  if (inst.Units == 0)
590  continue; // not an hvx inst or an hvx inst that doesn't uses any pipes
591  hvxInsts.push_back(inst);
592  }
593  // if there are any hvx instructions in this packet, check pipe usage
594  if (hvxInsts.size() > 0) {
595  unsigned startIdx, usedUnits;
596  startIdx = usedUnits = 0x0;
597  if (!checkHVXPipes(hvxInsts, startIdx, usedUnits)) {
598  // too many pipes used to be valid
599  reportError(Twine("invalid instruction packet: slot error"));
600  return false;
601  }
602  }
603 
604  return true;
605 }
606 
608  if (size() > HEXAGON_PACKET_SIZE) {
609  // Ignore a packet with with more than what a packet can hold
610  // or with compound or duplex insns for now.
611  reportError(Twine("invalid instruction packet"));
612  return false;
613  }
614 
615  // Check and prepare packet.
616  bool Ok = true;
617  if (size() > 1 && (Ok = check()))
618  // Reorder the handles for each slot.
619  for (unsigned nSlot = 0, emptySlots = 0; nSlot < HEXAGON_PACKET_SIZE;
620  ++nSlot) {
621  iterator ISJ, ISK;
622  unsigned slotSkip, slotWeight;
623 
624  // Prioritize the handles considering their restrictions.
625  for (ISJ = ISK = Packet.begin(), slotSkip = slotWeight = 0;
626  ISK != Packet.end(); ++ISK, ++slotSkip)
627  if (slotSkip < nSlot - emptySlots)
628  // Note which handle to begin at.
629  ++ISJ;
630  else
631  // Calculate the weight of the slot.
632  slotWeight += ISK->Core.setWeight(HEXAGON_PACKET_SIZE - nSlot - 1);
633 
634  if (slotWeight)
635  // Sort the packet, favoring source order,
636  // beginning after the previous slot.
637  std::stable_sort(ISJ, Packet.end());
638  else
639  // Skip unused slot.
640  ++emptySlots;
641  }
642 
643  for (iterator ISJ = begin(); ISJ != end(); ++ISJ)
644  LLVM_DEBUG(dbgs().write_hex(ISJ->Core.getUnits()); if (ISJ->CVI.isValid()) {
645  dbgs() << '/';
646  dbgs().write_hex(ISJ->CVI.getUnits()) << '|';
647  dbgs() << ISJ->CVI.getLanes();
648  } dbgs() << ':'
649  << HexagonMCInstrInfo::getDesc(MCII, ISJ->getDesc()).getOpcode();
650  dbgs() << '\n');
651  LLVM_DEBUG(dbgs() << '\n');
652 
653  return Ok;
654 }
655 
657  if (ReportErrors) {
658  for (auto const &I : AppliedRestrictions) {
659  auto SM = Context.getSourceManager();
660  if (SM)
661  SM->PrintMessage(I.first, SourceMgr::DK_Note, I.second);
662  }
663  Context.reportError(Loc, Msg);
664  }
665 }
std::string & operator+=(std::string &buffer, StringRef string)
Definition: StringRef.h:921
void push_back(const T &Elt)
Definition: SmallVector.h:213
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:137
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:392
bool isReturn() const
Return true if the instruction is a return.
Definition: MCInstrDesc.h:244
unsigned size() const
void PrintMessage(raw_ostream &OS, SMLoc Loc, DiagKind Kind, const Twine &Msg, ArrayRef< SMRange > Ranges=None, ArrayRef< SMFixIt > FixIts=None, bool ShowColors=true) const
Emit a message about the specified location with the specified string.
Definition: SourceMgr.cpp:247
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 isRestrictNoSlot1Store(MCInstrInfo const &MCII, MCInst const &MCI)
Context object for machine code objects.
Definition: MCContext.h:63
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:161
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:120
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
static struct @407 jumpSlots[]
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
Definition: SmallVector.h:117
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:617
bool isMemReorderDisabled() const
const SourceMgr * getSourceManager() const
Definition: MCContext.h:289
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:520
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:861
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:182
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:133
StringRef getCPU() const
SMLoc getLoc() const
Definition: MCInst.h:180
bool mayStore() const
Return true if this instruction could possibly modify memory.
Definition: MCInstrDesc.h:398
std::pair< unsigned, unsigned > UnitsAndLanes
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
Definition: SmallVector.h:121
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
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)
std::vector< std::pair< SMLoc, std::string > > AppliedRestrictions
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.
Represents a location in source code.
Definition: SMLoc.h:24
unsigned getOpcode() const
Definition: MCInst.h:174
#define LLVM_DEBUG(X)
Definition: Debug.h:119
static void SetupTUL(TypeUnitsAndLanes *TUL, StringRef CPU)
bool isRestrictSlot1AOK(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether the insn can be packaged only with an A-type insn in slot #1.
hexagon widen stores
bool check()
Check that the packet is legal and enforce relative insn order.