LLVM  10.0.0svn
HexagonShuffler.cpp
Go to the documentation of this file.
1 //===- HexagonShuffler.cpp - Instruction bundle shuffling -----------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This implements the shuffling of insns inside a bundle according to the
10 // packet formation rules of the Hexagon ISA.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #define DEBUG_TYPE "hexagon-shuffle"
15 
20 #include "llvm/ADT/SmallVector.h"
21 #include "llvm/ADT/Twine.h"
22 #include "llvm/MC/MCContext.h"
23 #include "llvm/MC/MCInst.h"
24 #include "llvm/MC/MCInstrDesc.h"
26 #include "llvm/Support/Compiler.h"
27 #include "llvm/Support/Debug.h"
29 #include "llvm/Support/SourceMgr.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);
118  (*TUL)[HexagonII::TypeCVI_VS_VX] = UnitsAndLanes(CVI_XLANE | CVI_SHIFT, 1);
120  (CPU == "hexagonv60")
121  ? UnitsAndLanes(CVI_SHIFT, 1)
122  : UnitsAndLanes(CVI_XLANE | CVI_SHIFT | CVI_MPY0 | CVI_MPY1, 1);
123  (*TUL)[HexagonII::TypeCVI_VM_LD] =
124  UnitsAndLanes(CVI_XLANE | CVI_SHIFT | CVI_MPY0 | CVI_MPY1, 1);
125  (*TUL)[HexagonII::TypeCVI_VM_TMP_LD] = UnitsAndLanes(CVI_NONE, 0);
126  (*TUL)[HexagonII::TypeCVI_VM_VP_LDU] = UnitsAndLanes(CVI_XLANE, 1);
127  (*TUL)[HexagonII::TypeCVI_VM_ST] =
128  UnitsAndLanes(CVI_XLANE | CVI_SHIFT | CVI_MPY0 | CVI_MPY1, 1);
129  (*TUL)[HexagonII::TypeCVI_VM_NEW_ST] = UnitsAndLanes(CVI_NONE, 0);
130  (*TUL)[HexagonII::TypeCVI_VM_STU] = UnitsAndLanes(CVI_XLANE, 1);
131  (*TUL)[HexagonII::TypeCVI_HIST] = UnitsAndLanes(CVI_XLANE, 4);
132  (*TUL)[HexagonII::TypeCVI_GATHER] =
133  UnitsAndLanes(CVI_XLANE | CVI_SHIFT | CVI_MPY0 | CVI_MPY1, 1);
135  UnitsAndLanes(CVI_XLANE | CVI_SHIFT | CVI_MPY0 | CVI_MPY1, 1);
137  UnitsAndLanes(CVI_XLANE | CVI_MPY0, 2);
139  UnitsAndLanes(CVI_XLANE | CVI_SHIFT | CVI_MPY0 | CVI_MPY1, 1);
140  (*TUL)[HexagonII::TypeCVI_4SLOT_MPY] = UnitsAndLanes(CVI_XLANE, 4);
141  (*TUL)[HexagonII::TypeCVI_ZW] = UnitsAndLanes(CVI_ZW, 1);
142 }
143 
145  MCInstrInfo const &MCII, unsigned s,
146  MCInst const *id)
147  : HexagonResource(s) {
148  unsigned T = HexagonMCInstrInfo::getType(MCII, *id);
149 
150  if (TUL->count(T)) {
151  // For an HVX insn.
152  Valid = true;
153  setUnits((*TUL)[T].first);
154  setLanes((*TUL)[T].second);
155  setLoad(HexagonMCInstrInfo::getDesc(MCII, *id).mayLoad());
156  setStore(HexagonMCInstrInfo::getDesc(MCII, *id).mayStore());
157  } else {
158  // For core insns.
159  Valid = false;
160  setUnits(0);
161  setLanes(0);
162  setLoad(false);
163  setStore(false);
164  }
165 }
166 
167 struct CVIUnits {
168  unsigned Units;
169  unsigned Lanes;
170 };
172 
173 static unsigned makeAllBits(unsigned startBit, unsigned Lanes)
174 {
175  for (unsigned i = 1; i < Lanes; ++i)
176  startBit = (startBit << 1) | startBit;
177  return startBit;
178 }
179 
180 static bool checkHVXPipes(const HVXInstsT &hvxInsts, unsigned startIdx,
181  unsigned usedUnits) {
182  if (startIdx < hvxInsts.size()) {
183  if (!hvxInsts[startIdx].Units)
184  return checkHVXPipes(hvxInsts, startIdx + 1, usedUnits);
185  for (unsigned b = 0x1; b <= 0x8; b <<= 1) {
186  if ((hvxInsts[startIdx].Units & b) == 0)
187  continue;
188  unsigned allBits = makeAllBits(b, hvxInsts[startIdx].Lanes);
189  if ((allBits & usedUnits) == 0) {
190  if (checkHVXPipes(hvxInsts, startIdx + 1, usedUnits | allBits))
191  return true;
192  }
193  }
194  return false;
195  }
196  return true;
197 }
198 
200  MCInstrInfo const &MCII,
201  MCSubtargetInfo const &STI)
202  : Context(Context), MCII(MCII), STI(STI), ReportErrors(ReportErrors) {
203  reset();
205 }
206 
208  Packet.clear();
209  BundleFlags = 0;
210 }
211 
212 void HexagonShuffler::append(MCInst const &ID, MCInst const *Extender,
213  unsigned S) {
214  HexagonInstr PI(&TUL, MCII, &ID, Extender, S);
215 
216  Packet.push_back(PI);
217 }
218 
219 static struct {
220  unsigned first;
221  unsigned second;
222 } jumpSlots[] = {{8, 4}, {8, 2}, {8, 1}, {4, 2}, {4, 1}, {2, 1}};
223 #define MAX_JUMP_SLOTS (sizeof(jumpSlots) / sizeof(jumpSlots[0]))
224 
226  bool HasRestrictSlot1AOK = false;
227  SMLoc RestrictLoc;
228  for (iterator ISJ = begin(); ISJ != end(); ++ISJ) {
229  MCInst const &Inst = ISJ->getDesc();
231  HasRestrictSlot1AOK = true;
232  RestrictLoc = Inst.getLoc();
233  }
234  }
235  if (HasRestrictSlot1AOK)
236  for (iterator ISJ = begin(); ISJ != end(); ++ISJ) {
237  MCInst const &Inst = ISJ->getDesc();
238  unsigned Type = HexagonMCInstrInfo::getType(MCII, Inst);
239  if (Type != HexagonII::TypeALU32_2op &&
240  Type != HexagonII::TypeALU32_3op &&
241  Type != HexagonII::TypeALU32_ADDI) {
242  unsigned Units = ISJ->Core.getUnits();
243  if (Units & 2U) {
244  AppliedRestrictions.push_back(std::make_pair(
245  Inst.getLoc(),
246  "Instruction was restricted from being in slot 1"));
247  AppliedRestrictions.push_back(
248  std::make_pair(RestrictLoc, "Instruction can only be combine "
249  "with an ALU instruction in slot 1"));
250  ISJ->Core.setUnits(Units & ~2U);
251  }
252  }
253  }
254 }
255 
257  bool HasRestrictNoSlot1Store = false;
258  SMLoc RestrictLoc;
259  for (iterator ISJ = begin(); ISJ != end(); ++ISJ) {
260  MCInst const &Inst = ISJ->getDesc();
262  HasRestrictNoSlot1Store = true;
263  RestrictLoc = Inst.getLoc();
264  }
265  }
266  if (HasRestrictNoSlot1Store) {
267  bool AppliedRestriction = false;
268  for (iterator ISJ = begin(); ISJ != end(); ++ISJ) {
269  MCInst const &Inst = ISJ->getDesc();
270  if (HexagonMCInstrInfo::getDesc(MCII, Inst).mayStore()) {
271  unsigned Units = ISJ->Core.getUnits();
272  if (Units & 2U) {
273  AppliedRestriction = true;
274  AppliedRestrictions.push_back(std::make_pair(
275  Inst.getLoc(),
276  "Instruction was restricted from being in slot 1"));
277  ISJ->Core.setUnits(Units & ~2U);
278  }
279  }
280  }
281  if (AppliedRestriction)
282  AppliedRestrictions.push_back(std::make_pair(
283  RestrictLoc, "Instruction does not allow a store in slot 1"));
284  }
285 }
286 
290 }
291 
292 /// Check that the packet is legal and enforce relative insn order.
294  // Descriptive slot masks.
295  const unsigned slotSingleLoad = 0x1, slotSingleStore = 0x1,
296  slotThree = 0x8, // slotFirstJump = 0x8,
297  slotFirstLoadStore = 0x2, slotLastLoadStore = 0x1;
298  // Highest slots for branches and stores used to keep their original order.
299  // unsigned slotJump = slotFirstJump;
300  unsigned slotLoadStore = slotFirstLoadStore;
301  // Number of memory operations, loads, solo loads, stores, solo stores, single
302  // stores.
303  unsigned memory = 0, loads = 0, load0 = 0, stores = 0, store0 = 0, store1 = 0;
304  unsigned NonZCVIloads = 0, AllCVIloads = 0, CVIstores = 0;
305  // Number of duplex insns
306  unsigned duplex = 0;
307  unsigned pSlot3Cnt = 0;
308  unsigned memops = 0;
309  iterator slot3ISJ = end();
310  std::vector<iterator> foundBranches;
311  unsigned reservedSlots = 0;
312 
313  // Collect information from the insns in the packet.
314  for (iterator ISJ = begin(); ISJ != end(); ++ISJ) {
315  MCInst const &ID = ISJ->getDesc();
316 
318  ++pSlot3Cnt;
319  slot3ISJ = ISJ;
320  }
321  reservedSlots |= HexagonMCInstrInfo::getOtherReservedSlots(MCII, STI, ID);
322 
323  switch (HexagonMCInstrInfo::getType(MCII, ID)) {
327  break;
328  case HexagonII::TypeJ:
329  foundBranches.push_back(ISJ);
330  break;
336  ++NonZCVIloads;
339  ++AllCVIloads;
341  case HexagonII::TypeLD:
342  ++loads;
343  ++memory;
344  if (ISJ->Core.getUnits() == slotSingleLoad ||
346  ++load0;
348  foundBranches.push_back(ISJ);
349  break;
358  ++CVIstores;
360  case HexagonII::TypeST:
361  ++stores;
362  ++memory;
363  if (ISJ->Core.getUnits() == slotSingleStore ||
365  ++store0;
366  break;
368  ++loads;
369  ++stores;
370  ++store1;
371  ++memops;
372  ++memory;
373  break;
374  case HexagonII::TypeNCJ:
375  ++memory; // NV insns are memory-like.
376  foundBranches.push_back(ISJ);
377  break;
379  if (HexagonMCInstrInfo::getDesc(MCII, ID).mayLoad()) {
380  ++loads;
381  ++memory;
382  if (ISJ->Core.getUnits() == slotSingleLoad ||
385  ++load0;
386  } else {
387  assert(HexagonMCInstrInfo::getDesc(MCII, ID).mayStore());
388  ++memory;
389  ++stores;
390  }
391  break;
392  case HexagonII::TypeCR:
393  // Legacy conditional branch predicated on a register.
394  case HexagonII::TypeCJ:
396  foundBranches.push_back(ISJ);
397  break;
398  case HexagonII::TypeDUPLEX: {
399  ++duplex;
400  MCInst const &Inst0 = *ID.getOperand(0).getInst();
401  MCInst const &Inst1 = *ID.getOperand(1).getInst();
403  foundBranches.push_back(ISJ);
405  foundBranches.push_back(ISJ);
406  if (HexagonMCInstrInfo::getDesc(MCII, Inst0).isReturn())
407  foundBranches.push_back(ISJ);
408  if (HexagonMCInstrInfo::getDesc(MCII, Inst1).isReturn())
409  foundBranches.push_back(ISJ);
410  break;
411  }
412  }
413  }
415 
416  // Check if the packet is legal.
417  const unsigned ZCVIloads = AllCVIloads - NonZCVIloads;
418  const bool ValidHVXMem =
419  NonZCVIloads <= 1 && ZCVIloads <= 1 && CVIstores <= 1;
420  if ((load0 > 1 || store0 > 1 || !ValidHVXMem) ||
421  (duplex > 1 || (duplex && memory))) {
422  reportError(llvm::Twine("invalid instruction packet"));
423  return false;
424  }
425 
426  // Modify packet accordingly.
427  // TODO: need to reserve slots #0 and #1 for duplex insns.
428  bool bOnlySlot3 = false;
429  for (iterator ISJ = begin(); ISJ != end(); ++ISJ) {
430  MCInst const &ID = ISJ->getDesc();
431 
432  if (!ISJ->Core.getUnits()) {
433  // Error if insn may not be executed in any slot.
434  return false;
435  }
436 
437  // A single load must use slot #0.
439  if (loads == 1 && loads == memory && memops == 0)
440  // Pin the load to slot #0.
441  switch (ID.getOpcode()) {
442  case Hexagon::V6_vgathermw:
443  case Hexagon::V6_vgathermh:
444  case Hexagon::V6_vgathermhw:
445  case Hexagon::V6_vgathermwq:
446  case Hexagon::V6_vgathermhq:
447  case Hexagon::V6_vgathermhwq:
448  // Slot1 only loads
449  break;
450  default:
451  ISJ->Core.setUnits(ISJ->Core.getUnits() & slotSingleLoad);
452  break;
453  }
454  else if (loads >= 1 && isMemReorderDisabled()) { // }:mem_noshuf
455  // Loads must keep the original order ONLY if
456  // isMemReorderDisabled() == true
457  if (slotLoadStore < slotLastLoadStore) {
458  // Error if no more slots available for loads.
459  reportError(
460  llvm::Twine("invalid instruction packet: too many loads"));
461  return false;
462  }
463  // Pin the load to the highest slot available to it.
464  ISJ->Core.setUnits(ISJ->Core.getUnits() & slotLoadStore);
465  // Update the next highest slot available to loads.
466  slotLoadStore >>= 1;
467  }
468  }
469 
470  // A single store must use slot #0.
472  if (!store0) {
473  if (stores == 1 && (loads == 0 || !isMemReorderDisabled()))
474  // Pin the store to slot #0 only if isMemReorderDisabled() == false
475  ISJ->Core.setUnits(ISJ->Core.getUnits() & slotSingleStore);
476  else if (stores >= 1) {
477  if (slotLoadStore < slotLastLoadStore) {
478  // Error if no more slots available for stores.
479  reportError(Twine("invalid instruction packet: too many stores"));
480  return false;
481  }
482  // Pin the store to the highest slot available to it.
483  ISJ->Core.setUnits(ISJ->Core.getUnits() & slotLoadStore);
484  // Update the next highest slot available to stores.
485  slotLoadStore >>= 1;
486  }
487  }
488  if (store1 && stores > 1) {
489  // Error if a single store with another store.
490  reportError(Twine("invalid instruction packet: too many stores"));
491  return false;
492  }
493  }
494 
495  // flag if an instruction requires to be in slot 3
496  if (ISJ->Core.getUnits() == slotThree)
497  bOnlySlot3 = true;
498 
499  if (!ISJ->Core.getUnits()) {
500  // Error if insn may not be executed in any slot.
501  reportError(Twine("invalid instruction packet: out of slots"));
502  return false;
503  }
504  }
505 
506  // preserve branch order
507  bool validateSlots = true;
508  if (foundBranches.size() > 1) {
509  if (foundBranches.size() > 2) {
510  reportError(Twine("too many branches in packet"));
511  return false;
512  }
513 
514  // try all possible choices
515  for (unsigned int i = 0; i < MAX_JUMP_SLOTS; ++i) {
516  // validate first jump with this slot rule
517  if (!(jumpSlots[i].first & foundBranches[0]->Core.getUnits()))
518  continue;
519 
520  // validate second jump with this slot rule
521  if (!(jumpSlots[i].second & foundBranches[1]->Core.getUnits()))
522  continue;
523 
524  // both valid for this configuration, set new slot rules
525  PacketSave = Packet;
526  foundBranches[0]->Core.setUnits(jumpSlots[i].first);
527  foundBranches[1]->Core.setUnits(jumpSlots[i].second);
528 
529  HexagonUnitAuction AuctionCore(reservedSlots);
531 
532  // see if things ok with that instruction being pinned to slot "slotJump"
533  bool bFail = false;
534  for (iterator I = begin(); I != end() && !bFail; ++I)
535  if (!AuctionCore.bid(I->Core.getUnits()))
536  bFail = true;
537 
538  // if yes, great, if not then restore original slot mask
539  if (!bFail) {
540  validateSlots = false; // all good, no need to re-do auction
541  break;
542  } else
543  // restore original values
544  Packet = PacketSave;
545  }
546  if (validateSlots) {
547  reportError(Twine("invalid instruction packet: out of slots"));
548  return false;
549  }
550  }
551 
552  if (foundBranches.size() <= 1 && bOnlySlot3 == false && pSlot3Cnt == 1 &&
553  slot3ISJ != end()) {
554  validateSlots = true;
555  // save off slot mask of instruction marked with A_PREFER_SLOT3
556  // and then pin it to slot #3
557  unsigned saveUnits = slot3ISJ->Core.getUnits();
558  slot3ISJ->Core.setUnits(saveUnits & slotThree);
559 
560  HexagonUnitAuction AuctionCore(reservedSlots);
562 
563  // see if things ok with that instruction being pinned to slot #3
564  bool bFail = false;
565  for (iterator I = begin(); I != end() && !bFail; ++I)
566  if (!AuctionCore.bid(I->Core.getUnits()))
567  bFail = true;
568 
569  // if yes, great, if not then restore original slot mask
570  if (!bFail)
571  validateSlots = false; // all good, no need to re-do auction
572  else
573  for (iterator ISJ = begin(); ISJ != end(); ++ISJ) {
574  MCInst const &ID = ISJ->getDesc();
576  ISJ->Core.setUnits(saveUnits);
577  }
578  }
579 
580  // Check if any slot, core or CVI, is over-subscribed.
581  // Verify the core slot subscriptions.
582  if (validateSlots) {
583  HexagonUnitAuction AuctionCore(reservedSlots);
584 
586 
587  for (iterator I = begin(); I != end(); ++I)
588  if (!AuctionCore.bid(I->Core.getUnits())) {
589  reportError(Twine("invalid instruction packet: slot error"));
590  return false;
591  }
592  }
593  // Verify the CVI slot subscriptions.
595  // create vector of hvx instructions to check
596  HVXInstsT hvxInsts;
597  hvxInsts.clear();
598  for (iterator I = begin(); I != end(); ++I) {
599  struct CVIUnits inst;
600  inst.Units = I->CVI.getUnits();
601  inst.Lanes = I->CVI.getLanes();
602  if (inst.Units == 0)
603  continue; // not an hvx inst or an hvx inst that doesn't uses any pipes
604  hvxInsts.push_back(inst);
605  }
606  // if there are any hvx instructions in this packet, check pipe usage
607  if (hvxInsts.size() > 0) {
608  unsigned startIdx, usedUnits;
609  startIdx = usedUnits = 0x0;
610  if (!checkHVXPipes(hvxInsts, startIdx, usedUnits)) {
611  // too many pipes used to be valid
612  reportError(Twine("invalid instruction packet: slot error"));
613  return false;
614  }
615  }
616 
617  return true;
618 }
619 
621  if (size() > HEXAGON_PACKET_SIZE) {
622  // Ignore a packet with with more than what a packet can hold
623  // or with compound or duplex insns for now.
624  reportError(Twine("invalid instruction packet"));
625  return false;
626  }
627 
628  // Check and prepare packet.
629  bool Ok = true;
630  if (size() > 1 && (Ok = check()))
631  // Reorder the handles for each slot.
632  for (unsigned nSlot = 0, emptySlots = 0; nSlot < HEXAGON_PACKET_SIZE;
633  ++nSlot) {
634  iterator ISJ, ISK;
635  unsigned slotSkip, slotWeight;
636 
637  // Prioritize the handles considering their restrictions.
638  for (ISJ = ISK = Packet.begin(), slotSkip = slotWeight = 0;
639  ISK != Packet.end(); ++ISK, ++slotSkip)
640  if (slotSkip < nSlot - emptySlots)
641  // Note which handle to begin at.
642  ++ISJ;
643  else
644  // Calculate the weight of the slot.
645  slotWeight += ISK->Core.setWeight(HEXAGON_PACKET_SIZE - nSlot - 1);
646 
647  if (slotWeight)
648  // Sort the packet, favoring source order,
649  // beginning after the previous slot.
650  std::stable_sort(ISJ, Packet.end());
651  else
652  // Skip unused slot.
653  ++emptySlots;
654  }
655 
656  for (iterator ISJ = begin(); ISJ != end(); ++ISJ)
657  LLVM_DEBUG(dbgs().write_hex(ISJ->Core.getUnits()); if (ISJ->CVI.isValid()) {
658  dbgs() << '/';
659  dbgs().write_hex(ISJ->CVI.getUnits()) << '|';
660  dbgs() << ISJ->CVI.getLanes();
661  } dbgs() << ':'
662  << HexagonMCInstrInfo::getDesc(MCII, ISJ->getDesc()).getOpcode();
663  dbgs() << '\n');
664  LLVM_DEBUG(dbgs() << '\n');
665 
666  return Ok;
667 }
668 
670  if (ReportErrors) {
671  for (auto const &I : AppliedRestrictions) {
672  auto SM = Context.getSourceManager();
673  if (SM)
674  SM->PrintMessage(I.first, SourceMgr::DK_Note, I.second);
675  }
676  Context.reportError(Loc, Msg);
677  }
678 }
std::string & operator+=(std::string &buffer, StringRef string)
Definition: StringRef.h:902
static bool lessCore(const HexagonInstr &A, const HexagonInstr &B)
#define MAX_JUMP_SLOTS
void setUnits(unsigned s)
LLVMContext & Context
This class represents lattice values for constants.
Definition: AllocatorList.h:23
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 push_back(const T &Elt)
Definition: SmallVector.h:211
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:413
bool isReturn() const
Return true if the instruction is a return.
Definition: MCInstrDesc.h:260
unsigned size() const
unsigned 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:119
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:242
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:80
static Optional< unsigned > getOpcode(ArrayRef< VPValue *> Values)
Returns the opcode of Values or ~0 if they do not all agree.
Definition: VPlanSLP.cpp:196
bool isRestrictNoSlot1Store(MCInstrInfo const &MCII, MCInst const &MCI)
Context object for machine code objects.
Definition: MCContext.h:65
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:105
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:158
HexagonCVIResource(TypeUnitsAndLanes *TUL, MCInstrInfo const &MCII, unsigned s, MCInst const *id)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
MCSubtargetInfo const & STI
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:23
MCInstrDesc const & getDesc(MCInstrInfo const &MCII, MCInst const &MCI)
void reportError(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:687
static struct @461 jumpSlots[]
bool isMemReorderDisabled() const
const SourceMgr * getSourceManager() const
Definition: MCContext.h:314
size_t size() const
Definition: SmallVector.h:52
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:519
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:837
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:179
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
StringRef getCPU() const
SMLoc getLoc() const
Definition: MCInst.h:177
bool mayStore() const
Return true if this instruction could possibly modify memory.
Definition: MCInstrDesc.h:419
std::pair< unsigned, unsigned > UnitsAndLanes
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:145
unsigned Lanes
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isBranch(unsigned Opcode)
void stable_sort(R &&Range)
Definition: STLExtras.h:1289
#define HEXAGON_PACKET_SIZE
std::vector< std::pair< SMLoc, std::string > > AppliedRestrictions
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
Definition: Compiler.h:265
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:48
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:23
unsigned getOpcode() const
Definition: MCInst.h:171
#define LLVM_DEBUG(X)
Definition: Debug.h:122
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.