LLVM  17.0.0git
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 
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/ADT/Twine.h"
20 #include "llvm/MC/MCContext.h"
21 #include "llvm/MC/MCInst.h"
22 #include "llvm/MC/MCInstrDesc.h"
24 #include "llvm/Support/Compiler.h"
25 #include "llvm/Support/Debug.h"
27 #include "llvm/Support/SourceMgr.h"
29 #include <algorithm>
30 #include <cassert>
31 #include <optional>
32 #include <utility>
33 #include <vector>
34 
35 #define DEBUG_TYPE "hexagon-shuffle"
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 / llvm::popcount(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 = llvm::popcount(Units);
104  unsigned Cttz = countTrailingZeros(Units);
105  Weight = (1u << (SlotWeight * s)) * ((MaskWeight - Ctpop) << Cttz);
106  return Weight;
107 }
108 
110  MCSubtargetInfo const &STI,
111  unsigned s,
112  MCInst const *id)
113  : HexagonResource(s) {
114 
115  const unsigned ItinUnits = HexagonMCInstrInfo::getCVIResources(MCII, STI, *id);
116  unsigned Lanes;
117  const unsigned Units = HexagonConvertUnits(ItinUnits, &Lanes);
118 
119  if (Units == 0 && Lanes == 0) {
120  // For core insns.
121  Valid = false;
122  setUnits(0);
123  setLanes(0);
124  setLoad(false);
125  setStore(false);
126  } else {
127  // For an HVX insn.
128  Valid = true;
129  setUnits(Units);
130  setLanes(Lanes);
131  setLoad(HexagonMCInstrInfo::getDesc(MCII, *id).mayLoad());
132  setStore(HexagonMCInstrInfo::getDesc(MCII, *id).mayStore());
133  }
134 }
135 
136 struct CVIUnits {
137  unsigned Units;
138  unsigned Lanes;
139 };
141 
142 static unsigned makeAllBits(unsigned startBit, unsigned Lanes)
143 {
144  for (unsigned i = 1; i < Lanes; ++i)
145  startBit = (startBit << 1) | startBit;
146  return startBit;
147 }
148 
149 static bool checkHVXPipes(const HVXInstsT &hvxInsts, unsigned startIdx,
150  unsigned usedUnits) {
151  if (startIdx < hvxInsts.size()) {
152  if (!hvxInsts[startIdx].Units)
153  return checkHVXPipes(hvxInsts, startIdx + 1, usedUnits);
154  for (unsigned b = 0x1; b <= 0x8; b <<= 1) {
155  if ((hvxInsts[startIdx].Units & b) == 0)
156  continue;
157  unsigned allBits = makeAllBits(b, hvxInsts[startIdx].Lanes);
158  if ((allBits & usedUnits) == 0) {
159  if (checkHVXPipes(hvxInsts, startIdx + 1, usedUnits | allBits))
160  return true;
161  }
162  }
163  return false;
164  }
165  return true;
166 }
167 
169  MCInstrInfo const &MCII,
170  MCSubtargetInfo const &STI)
171  : Context(Context), BundleFlags(), MCII(MCII), STI(STI),
172  ReportErrors(ReportErrors), CheckFailure() {
173  reset();
174 }
175 
177  Packet.clear();
178  BundleFlags = 0;
179  CheckFailure = false;
180 }
181 
182 void HexagonShuffler::append(MCInst const &ID, MCInst const *Extender,
183  unsigned S) {
184  HexagonInstr PI(MCII, STI, &ID, Extender, S);
185 
186  Packet.push_back(PI);
187 }
188 
189 
190 static const unsigned Slot0Mask = 1 << 0;
191 static const unsigned Slot1Mask = 1 << 1;
192 static const unsigned Slot3Mask = 1 << 3;
193 static const unsigned slotSingleLoad = Slot0Mask;
194 static const unsigned slotSingleStore = Slot0Mask;
195 
196 void HexagonShuffler::restrictSlot1AOK(HexagonPacketSummary const &Summary) {
197  if (Summary.Slot1AOKLoc)
198  for (HexagonInstr &ISJ : insts()) {
199  MCInst const &Inst = ISJ.getDesc();
200  const unsigned Type = HexagonMCInstrInfo::getType(MCII, Inst);
204  const unsigned Units = ISJ.Core.getUnits();
205 
206  if (Units & Slot1Mask) {
207  AppliedRestrictions.push_back(std::make_pair(
208  Inst.getLoc(),
209  "Instruction was restricted from being in slot 1"));
210  AppliedRestrictions.push_back(std::make_pair(
211  *Summary.Slot1AOKLoc, "Instruction can only be combined "
212  "with an ALU instruction in slot 1"));
213  ISJ.Core.setUnits(Units & ~Slot1Mask);
214  }
215  }
216  }
217 }
218 
220  HexagonPacketSummary const &Summary) {
221  // If this packet contains an instruction that bars slot-1 stores,
222  // we should mask off slot 1 from all of the store instructions in
223  // this packet.
224 
225  if (!Summary.NoSlot1StoreLoc)
226  return;
227 
228  bool AppliedRestriction = false;
229 
230  for (HexagonInstr &ISJ : insts()) {
231  MCInst const &Inst = ISJ.getDesc();
232  if (HexagonMCInstrInfo::getDesc(MCII, Inst).mayStore()) {
233  unsigned Units = ISJ.Core.getUnits();
234  if (Units & Slot1Mask) {
235  AppliedRestriction = true;
236  AppliedRestrictions.push_back(std::make_pair(
237  Inst.getLoc(), "Instruction was restricted from being in slot 1"));
238  ISJ.Core.setUnits(Units & ~Slot1Mask);
239  }
240  }
241  }
242 
243  if (AppliedRestriction)
244  AppliedRestrictions.push_back(
245  std::make_pair(*Summary.NoSlot1StoreLoc,
246  "Instruction does not allow a store in slot 1"));
247 }
248 
249 bool HexagonShuffler::applySlotRestrictions(HexagonPacketSummary const &Summary,
250  const bool DoShuffle) {
251  // These restrictions can modify the slot masks in the instructions
252  // in the Packet member. They should run unconditionally and their
253  // order does not matter.
254  restrictSlot1AOK(Summary);
255  restrictNoSlot1Store(Summary);
256 
257  permitNonSlot();
258 
259  // These restrictions can modify the slot masks in the instructions
260  // in the Packet member, but they can also detect constraint failures
261  // which are fatal.
262  if (!CheckFailure)
263  restrictStoreLoadOrder(Summary);
264  if (!CheckFailure)
265  restrictBranchOrder(Summary);
266  if (!CheckFailure)
267  restrictPreferSlot3(Summary, DoShuffle);
268  return !CheckFailure;
269 }
270 
271 void HexagonShuffler::restrictBranchOrder(HexagonPacketSummary const &Summary) {
272  // preserve branch order
273  const bool HasMultipleBranches = Summary.branchInsts.size() > 1;
274  if (!HasMultipleBranches)
275  return;
276 
277  if (Summary.branchInsts.size() > 2) {
278  reportError(Twine("too many branches in packet"));
279  return;
280  }
281 
282  const static std::pair<unsigned, unsigned> jumpSlots[] = {
283  {8, 4}, {8, 2}, {8, 1}, {4, 2}, {4, 1}, {2, 1}};
284  // try all possible choices
285  for (std::pair<unsigned, unsigned> jumpSlot : jumpSlots) {
286  // validate first jump with this slot rule
287  if (!(jumpSlot.first & Summary.branchInsts[0]->Core.getUnits()))
288  continue;
289 
290  // validate second jump with this slot rule
291  if (!(jumpSlot.second & Summary.branchInsts[1]->Core.getUnits()))
292  continue;
293 
294  // both valid for this configuration, set new slot rules
295  const HexagonPacket PacketSave = Packet;
296  Summary.branchInsts[0]->Core.setUnits(jumpSlot.first);
297  Summary.branchInsts[1]->Core.setUnits(jumpSlot.second);
298 
299  const bool HasShuffledPacket = tryAuction(Summary).has_value();
300  if (HasShuffledPacket)
301  return;
302 
303  // if yes, great, if not then restore original slot mask
304  // restore original values
305  Packet = PacketSave;
306  }
307 
308  reportResourceError(Summary, "out of slots");
309 }
310 
312  for (HexagonInstr &ISJ : insts()) {
313  const bool RequiresSlot = HexagonMCInstrInfo::requiresSlot(STI, *ISJ.ID);
314  if (!RequiresSlot)
315  ISJ.Core.setAllUnits();
316  }
317 }
318 
319 bool HexagonShuffler::ValidResourceUsage(HexagonPacketSummary const &Summary) {
320  std::optional<HexagonPacket> ShuffledPacket = tryAuction(Summary);
321 
322  if (!ShuffledPacket) {
323  reportResourceError(Summary, "slot error");
324  return false;
325  }
326 
327  // Verify the CVI slot subscriptions.
328  llvm::stable_sort(*ShuffledPacket, HexagonInstr::lessCVI);
329  // create vector of hvx instructions to check
330  HVXInstsT hvxInsts;
331  hvxInsts.clear();
332  for (const auto &I : *ShuffledPacket) {
333  struct CVIUnits inst;
334  inst.Units = I.CVI.getUnits();
335  inst.Lanes = I.CVI.getLanes();
336  if (inst.Units == 0)
337  continue; // not an hvx inst or an hvx inst that doesn't uses any pipes
338  hvxInsts.push_back(inst);
339  }
340 
341  // if there are any hvx instructions in this packet, check pipe usage
342  if (hvxInsts.size() > 0) {
343  unsigned startIdx, usedUnits;
344  startIdx = usedUnits = 0x0;
345  if (!checkHVXPipes(hvxInsts, startIdx, usedUnits)) {
346  // too many pipes used to be valid
347  reportError(Twine("invalid instruction packet: slot error"));
348  return false;
349  }
350  }
351 
352  Packet = *ShuffledPacket;
353 
354  return true;
355 }
356 
358  HexagonPacketSummary const &Summary) {
359  // Modify packet accordingly.
360  // TODO: need to reserve slots #0 and #1 for duplex insns.
361  static const unsigned slotFirstLoadStore = Slot1Mask;
362  static const unsigned slotLastLoadStore = Slot0Mask;
363  unsigned slotLoadStore = slotFirstLoadStore;
364 
365  for (iterator ISJ = begin(); ISJ != end(); ++ISJ) {
366  MCInst const &ID = ISJ->getDesc();
367 
368  if (!ISJ->Core.getUnits())
369  // Error if insn may not be executed in any slot.
370  return false;
371 
372  // A single load must use slot #0.
374  if (Summary.loads == 1 && Summary.loads == Summary.memory &&
375  Summary.memops == 0)
376  // Pin the load to slot #0.
377  switch (ID.getOpcode()) {
378  case Hexagon::V6_vgathermw:
379  case Hexagon::V6_vgathermh:
380  case Hexagon::V6_vgathermhw:
381  case Hexagon::V6_vgathermwq:
382  case Hexagon::V6_vgathermhq:
383  case Hexagon::V6_vgathermhwq:
384  // Slot1 only loads
385  break;
386  default:
387  ISJ->Core.setUnits(ISJ->Core.getUnits() & slotSingleLoad);
388  break;
389  }
390  else if (Summary.loads >= 1 && isMemReorderDisabled()) { // }:mem_noshuf
391  // Loads must keep the original order ONLY if
392  // isMemReorderDisabled() == true
393  if (slotLoadStore < slotLastLoadStore) {
394  // Error if no more slots available for loads.
395  reportError("invalid instruction packet: too many loads");
396  return false;
397  }
398  // Pin the load to the highest slot available to it.
399  ISJ->Core.setUnits(ISJ->Core.getUnits() & slotLoadStore);
400  // Update the next highest slot available to loads.
401  slotLoadStore >>= 1;
402  }
403  }
404 
405  // A single store must use slot #0.
406  if (HexagonMCInstrInfo::getDesc(MCII, ID).mayStore()) {
407  if (!Summary.store0) {
408  const bool PacketHasNoOnlySlot0 =
409  llvm::none_of(insts(), [&](HexagonInstr const &I) {
410  return I.Core.getUnits() == Slot0Mask &&
411  I.ID->getOpcode() != ID.getOpcode();
412  });
413  const bool SafeToMoveToSlot0 =
414  (Summary.loads == 0) ||
415  (!isMemReorderDisabled() && PacketHasNoOnlySlot0);
416 
417  if (Summary.stores == 1 && SafeToMoveToSlot0)
418  // Pin the store to slot #0 only if isMemReorderDisabled() == false
419  ISJ->Core.setUnits(ISJ->Core.getUnits() & slotSingleStore);
420  else if (Summary.stores >= 1) {
421  if (slotLoadStore < slotLastLoadStore) {
422  // Error if no more slots available for stores.
423  reportError("invalid instruction packet: too many stores");
424  return false;
425  }
426  // Pin the store to the highest slot available to it.
427  ISJ->Core.setUnits(ISJ->Core.getUnits() & slotLoadStore);
428  // Update the next highest slot available to stores.
429  slotLoadStore >>= 1;
430  }
431  }
432  if (Summary.store1 && Summary.stores > 1) {
433  // Error if a single store with another store.
434  reportError("invalid instruction packet: too many stores");
435  return false;
436  }
437  }
438  }
439 
440  return true;
441 }
442 
443 static std::string SlotMaskToText(unsigned SlotMask) {
445  for (unsigned SlotNum = 0; SlotNum < HEXAGON_PACKET_SIZE; SlotNum++)
446  if ((SlotMask & (1 << SlotNum)) != 0)
447  Slots.push_back(utostr(SlotNum));
448 
449  return llvm::join(Slots, StringRef(", "));
450 }
451 
452 HexagonShuffler::HexagonPacketSummary HexagonShuffler::GetPacketSummary() {
453  HexagonPacketSummary Summary = HexagonPacketSummary();
454 
455  // Collect information from the insns in the packet.
456  for (iterator ISJ = begin(); ISJ != end(); ++ISJ) {
457  MCInst const &ID = ISJ->getDesc();
458 
460  Summary.Slot1AOKLoc = ID.getLoc();
462  Summary.NoSlot1StoreLoc = ID.getLoc();
463 
465  ++Summary.pSlot3Cnt;
466  Summary.PrefSlot3Inst = ISJ;
467  }
468  const unsigned ReservedSlots =
470  Summary.ReservedSlotMask |= ReservedSlots;
471  if (ReservedSlots != 0)
472  AppliedRestrictions.push_back(std::make_pair(ID.getLoc(),
473  (Twine("Instruction has reserved slots: ") +
474  SlotMaskToText(ReservedSlots)).str()));
475 
476  switch (HexagonMCInstrInfo::getType(MCII, ID)) {
480  break;
481  case HexagonII::TypeJ:
483  Summary.branchInsts.push_back(ISJ);
484  break;
491  ++Summary.NonZCVIloads;
492  [[fallthrough]];
494  ++Summary.AllCVIloads;
495  [[fallthrough]];
496  case HexagonII::TypeLD:
497  ++Summary.loads;
498  ++Summary.memory;
499  if (ISJ->Core.getUnits() == slotSingleLoad ||
501  ++Summary.load0;
502  if (HexagonMCInstrInfo::getDesc(MCII, ID).isReturn())
503  Summary.branchInsts.push_back(ISJ);
504  break;
513  ++Summary.CVIstores;
514  [[fallthrough]];
515  case HexagonII::TypeST:
516  ++Summary.stores;
517  ++Summary.memory;
518  if (ISJ->Core.getUnits() == slotSingleStore ||
520  ++Summary.store0;
521  break;
523  ++Summary.loads;
524  ++Summary.stores;
525  ++Summary.store1;
526  ++Summary.memops;
527  ++Summary.memory;
528  break;
529  case HexagonII::TypeNCJ:
530  ++Summary.memory; // NV insns are memory-like.
531  Summary.branchInsts.push_back(ISJ);
532  break;
534  if (HexagonMCInstrInfo::getDesc(MCII, ID).mayLoad()) {
535  ++Summary.loads;
536  ++Summary.memory;
537  if (ISJ->Core.getUnits() == slotSingleLoad ||
540  ++Summary.load0;
541  } else {
543  ++Summary.memory;
544  ++Summary.stores;
545  }
546  break;
547  case HexagonII::TypeCR:
548  // Legacy conditional branch predicated on a register.
549  case HexagonII::TypeCJ:
551  Summary.branchInsts.push_back(ISJ);
552  break;
553  case HexagonII::TypeDUPLEX: {
554  ++Summary.duplex;
555  MCInst const &Inst0 = *ID.getOperand(0).getInst();
556  MCInst const &Inst1 = *ID.getOperand(1).getInst();
558  Summary.branchInsts.push_back(ISJ);
560  Summary.branchInsts.push_back(ISJ);
561  if (HexagonMCInstrInfo::getDesc(MCII, Inst0).isReturn())
562  Summary.branchInsts.push_back(ISJ);
563  if (HexagonMCInstrInfo::getDesc(MCII, Inst1).isReturn())
564  Summary.branchInsts.push_back(ISJ);
565  break;
566  }
567  }
568  }
569  return Summary;
570 }
571 
573  HexagonPacketSummary const &Summary) const {
574  // Check if the packet is legal.
575  const unsigned ZCVIloads = Summary.AllCVIloads - Summary.NonZCVIloads;
576  const bool ValidHVXMem =
577  Summary.NonZCVIloads <= 1 && ZCVIloads <= 1 && Summary.CVIstores <= 1;
578  const bool InvalidPacket =
579  ((Summary.load0 > 1 || Summary.store0 > 1 || !ValidHVXMem) ||
580  (Summary.duplex > 1 || (Summary.duplex && Summary.memory)));
581 
582  return !InvalidPacket;
583 }
584 
585 void HexagonShuffler::restrictPreferSlot3(HexagonPacketSummary const &Summary,
586  const bool DoShuffle) {
587  // flag if an instruction requires to be in slot 3
588  const bool HasOnlySlot3 = llvm::any_of(insts(), [&](HexagonInstr const &I) {
589  return (I.Core.getUnits() == Slot3Mask);
590  });
591  const bool NeedsPrefSlot3Shuffle = Summary.branchInsts.size() <= 1 &&
592  !HasOnlySlot3 && Summary.pSlot3Cnt == 1 &&
593  Summary.PrefSlot3Inst && DoShuffle;
594 
595  if (!NeedsPrefSlot3Shuffle)
596  return;
597 
598  HexagonInstr *PrefSlot3Inst = *Summary.PrefSlot3Inst;
599  // save off slot mask of instruction marked with A_PREFER_SLOT3
600  // and then pin it to slot #3
601  const unsigned saveUnits = PrefSlot3Inst->Core.getUnits();
602  PrefSlot3Inst->Core.setUnits(saveUnits & Slot3Mask);
603  const bool HasShuffledPacket = tryAuction(Summary).has_value();
604  if (HasShuffledPacket)
605  return;
606 
607  PrefSlot3Inst->Core.setUnits(saveUnits);
608 }
609 
610 /// Check that the packet is legal and enforce relative insn order.
611 bool HexagonShuffler::check(const bool RequireShuffle) {
612  const HexagonPacketSummary Summary = GetPacketSummary();
613  if (!applySlotRestrictions(Summary, RequireShuffle))
614  return false;
615 
616  if (!ValidPacketMemoryOps(Summary)) {
617  reportError("invalid instruction packet");
618  return false;
619  }
620 
621  if (RequireShuffle)
622  ValidResourceUsage(Summary);
623 
624  return !CheckFailure;
625 }
626 
627 std::optional<HexagonShuffler::HexagonPacket>
628 HexagonShuffler::tryAuction(HexagonPacketSummary const &Summary) {
629  HexagonPacket PacketResult = Packet;
630  HexagonUnitAuction AuctionCore(Summary.ReservedSlotMask);
632 
633  const bool ValidSlots =
634  llvm::all_of(insts(PacketResult), [&AuctionCore](HexagonInstr const &I) {
635  return AuctionCore.bid(I.Core.getUnits());
636  });
637 
638  LLVM_DEBUG(
639  dbgs() << "Shuffle attempt: " << (ValidSlots ? "passed" : "failed")
640  << "\n";
641  for (HexagonInstr const &ISJ : insts(PacketResult))
642  dbgs() << "\t" << HexagonMCInstrInfo::getName(MCII, *ISJ.ID) << ": "
643  << llvm::format_hex(ISJ.Core.getUnits(), 4, true) << "\n";
644  );
645 
646  std::optional<HexagonPacket> Res;
647  if (ValidSlots)
648  Res = PacketResult;
649 
650  return Res;
651 }
652 
654  if (size() > HEXAGON_PACKET_SIZE) {
655  // Ignore a packet with with more than what a packet can hold
656  // or with compound or duplex insns for now.
657  reportError("invalid instruction packet");
658  return false;
659  }
660 
661  // Check and prepare packet.
662  bool Ok = check();
663  if (size() > 1 && Ok)
664  // Reorder the handles for each slot.
665  for (unsigned nSlot = 0, emptySlots = 0; nSlot < HEXAGON_PACKET_SIZE;
666  ++nSlot) {
667  iterator ISJ, ISK;
668  unsigned slotSkip, slotWeight;
669 
670  // Prioritize the handles considering their restrictions.
671  for (ISJ = ISK = Packet.begin(), slotSkip = slotWeight = 0;
672  ISK != Packet.end(); ++ISK, ++slotSkip)
673  if (slotSkip < nSlot - emptySlots)
674  // Note which handle to begin at.
675  ++ISJ;
676  else
677  // Calculate the weight of the slot.
678  slotWeight += ISK->Core.setWeight(HEXAGON_PACKET_SIZE - nSlot - 1);
679 
680  if (slotWeight)
681  // Sort the packet, favoring source order,
682  // beginning after the previous slot.
683  std::stable_sort(ISJ, Packet.end());
684  else
685  // Skip unused slot.
686  ++emptySlots;
687  }
688 
689  LLVM_DEBUG(
690  for (HexagonInstr const &ISJ : insts()) {
691  dbgs().write_hex(ISJ.Core.getUnits());
692  if (ISJ.CVI.isValid()) {
693  dbgs() << '/';
694  dbgs().write_hex(ISJ.CVI.getUnits()) << '|';
695  dbgs() << ISJ.CVI.getLanes();
696  }
697  dbgs() << ':'
698  << HexagonMCInstrInfo::getDesc(MCII, ISJ.getDesc()).getOpcode()
699  << '\n';
700  } dbgs() << '\n';
701  );
702 
703  return Ok;
704 }
705 
706 void HexagonShuffler::reportResourceError(HexagonPacketSummary const &Summary, StringRef Err) {
707  if (ReportErrors)
708  reportResourceUsage(Summary);
709  reportError(Twine("invalid instruction packet: ") + Err);
710 }
711 
712 
713 void HexagonShuffler::reportResourceUsage(HexagonPacketSummary const &Summary) {
714  auto SM = Context.getSourceManager();
715  if (SM) {
716  for (HexagonInstr const &I : insts()) {
717  const unsigned Units = I.Core.getUnits();
718 
720  const std::string UnitsText = Units ? SlotMaskToText(Units) : "<None>";
721  SM->PrintMessage(I.ID->getLoc(), SourceMgr::DK_Note,
722  Twine("Instruction can utilize slots: ") +
723  UnitsText);
724  }
725  else if (!HexagonMCInstrInfo::isImmext(*I.ID))
726  SM->PrintMessage(I.ID->getLoc(), SourceMgr::DK_Note,
727  "Instruction does not require a slot");
728  }
729  }
730 }
731 
733  CheckFailure = true;
734  if (ReportErrors) {
735  for (auto const &I : AppliedRestrictions) {
736  auto SM = Context.getSourceManager();
737  if (SM)
738  SM->PrintMessage(I.first, SourceMgr::DK_Note, I.second);
739  }
741  }
742 }
i
i
Definition: README.txt:29
HexagonMCTargetDesc.h
llvm::HexagonShuffler::MCII
const MCInstrInfo & MCII
Definition: HexagonShuffler.h:165
slotSingleStore
static const unsigned slotSingleStore
Definition: HexagonShuffler.cpp:194
llvm::MCInstrDesc::getOpcode
unsigned getOpcode() const
Return the opcode number for this descriptor.
Definition: MCInstrDesc.h:230
llvm::HexagonShuffler::begin
iterator begin()
Definition: HexagonShuffler.h:211
llvm::HexagonShuffler::GetPacketSummary
HexagonPacketSummary GetPacketSummary()
Definition: HexagonShuffler.cpp:452
MathExtras.h
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::HexagonMCInstrInfo::getDesc
const MCInstrDesc & getDesc(MCInstrInfo const &MCII, MCInst const &MCI)
Definition: HexagonMCInstrInfo.cpp:255
llvm::HexagonII::TypeALU32_ADDI
@ TypeALU32_ADDI
Definition: HexagonDepITypes.h:19
llvm::HexagonShuffler::reportError
void reportError(Twine const &Msg)
Definition: HexagonShuffler.cpp:732
llvm::HexagonShuffler::shuffle
bool shuffle()
Definition: HexagonShuffler.cpp:653
llvm::HexagonConvertUnits
unsigned HexagonConvertUnits(unsigned ItinUnits, unsigned *Lanes)
Definition: HexagonMCTargetDesc.cpp:174
llvm::none_of
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1749
llvm::HexagonII::TypeCVI_VM_VP_LDU
@ TypeCVI_VM_VP_LDU
Definition: HexagonDepITypes.h:40
llvm::HexagonCVIResource::HexagonCVIResource
HexagonCVIResource(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, unsigned s, MCInst const *id)
Definition: HexagonShuffler.cpp:109
llvm::HexagonShuffler::CheckFailure
bool CheckFailure
Definition: HexagonShuffler.h:169
llvm::HexagonCVIResource::mayLoad
bool mayLoad() const
Definition: HexagonShuffler.h:94
llvm::HexagonII::TypeCR
@ TypeCR
Definition: HexagonDepITypes.h:22
MCInstrDesc.h
llvm::HexagonMCInstrInfo::isRestrictSlot1AOK
bool isRestrictSlot1AOK(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether the insn can be packaged only with an A-type insn in slot #1.
Definition: HexagonMCInstrInfo.cpp:775
llvm::HexagonShuffler::restrictStoreLoadOrder
bool restrictStoreLoadOrder(HexagonPacketSummary const &Summary)
Definition: HexagonShuffler.cpp:357
llvm::HexagonShuffler::Loc
SMLoc Loc
Definition: HexagonShuffler.h:167
llvm::HexagonMCInstrInfo::IsABranchingInst
bool IsABranchingInst(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst const &I)
Definition: HexagonMCInstrInfo.cpp:1046
llvm::MCContext
Context object for machine code objects.
Definition: MCContext.h:76
llvm::HexagonResource::setUnits
void setUnits(unsigned s)
Definition: HexagonShuffler.h:46
llvm::HexagonShuffler::isMemReorderDisabled
bool isMemReorderDisabled() const
Definition: HexagonShuffler.h:207
llvm::HexagonII::TypeLD
@ TypeLD
Definition: HexagonDepITypes.h:53
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1199
HexagonShuffler.h
llvm::HexagonMCInstrInfo::getCVIResources
unsigned getCVIResources(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst const &MCI)
Return the resources used by this instruction.
Definition: HexagonMCInstrInfo.cpp:430
llvm::HexagonShuffler::iterator
HexagonPacket::iterator iterator
Definition: HexagonShuffler.h:190
llvm::HexagonShuffler::reportResourceUsage
void reportResourceUsage(HexagonPacketSummary const &Summary)
Definition: HexagonShuffler.cpp:713
llvm::HexagonII::TypeALU32_3op
@ TypeALU32_3op
Definition: HexagonDepITypes.h:18
Slot0Mask
static const unsigned Slot0Mask
Definition: HexagonShuffler.cpp:190
llvm::HexagonShuffler::restrictNoSlot1Store
void restrictNoSlot1Store(HexagonPacketSummary const &Summary)
Definition: HexagonShuffler.cpp:219
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
llvm::HexagonII::TypeST
@ TypeST
Definition: HexagonDepITypes.h:58
llvm::HexagonII::TypeCVI_GATHER_RST
@ TypeCVI_GATHER_RST
Definition: HexagonDepITypes.h:26
llvm::HexagonMCInstrInfo::isImmext
bool isImmext(MCInst const &MCI)
Definition: HexagonMCInstrInfo.cpp:642
llvm::HexagonResource::getUnits
unsigned getUnits() const
Definition: HexagonShuffler.h:56
llvm::HexagonII::TypeCVI_ZW
@ TypeCVI_ZW
Definition: HexagonDepITypes.h:48
llvm::SourceMgr::DK_Note
@ DK_Note
Definition: SourceMgr.h:37
llvm::MCInst
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
slotSingleLoad
static const unsigned slotSingleLoad
Definition: HexagonShuffler.cpp:193
llvm::HexagonMCInstrInfo::prefersSlot3
bool prefersSlot3(MCInstrInfo const &MCII, MCInst const &MCI)
Definition: HexagonMCInstrInfo.cpp:940
llvm::HexagonII::TypeCVI_GATHER_DV
@ TypeCVI_GATHER_DV
Definition: HexagonDepITypes.h:25
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
HexagonBaseInfo.h
llvm::HexagonShuffler::permitNonSlot
void permitNonSlot()
Definition: HexagonShuffler.cpp:311
llvm::HexagonMCInstrInfo::getOtherReservedSlots
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.
Definition: HexagonMCInstrInfo.cpp:461
makeAllBits
static unsigned makeAllBits(unsigned startBit, unsigned Lanes)
Definition: HexagonShuffler.cpp:142
Context
LLVMContext & Context
Definition: NVVMIntrRange.cpp:66
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::HexagonII::TypeV2LDST
@ TypeV2LDST
Definition: HexagonDepITypes.h:62
llvm::all_of
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1735
Slot1Mask
static const unsigned Slot1Mask
Definition: HexagonShuffler.cpp:191
llvm::HexagonII::TypeCVI_VM_NEW_ST
@ TypeCVI_VM_NEW_ST
Definition: HexagonDepITypes.h:36
llvm::HexagonInstr::lessCVI
static bool lessCVI(const HexagonInstr &A, const HexagonInstr &B)
Definition: HexagonShuffler.h:127
llvm::HexagonShuffler::restrictSlot1AOK
void restrictSlot1AOK(HexagonPacketSummary const &Summary)
Definition: HexagonShuffler.cpp:196
llvm::HexagonMCInstrInfo::requiresSlot
bool requiresSlot(MCSubtargetInfo const &STI, MCInst const &MCI)
Definition: HexagonMCInstrInfo.cpp:966
HexagonMCInstrInfo.h
llvm::HexagonII::TypeCVI_SCATTER_RST
@ TypeCVI_SCATTER_RST
Definition: HexagonDepITypes.h:32
llvm::HexagonShuffler::restrictBranchOrder
void restrictBranchOrder(HexagonPacketSummary const &Summary)
Definition: HexagonShuffler.cpp:271
llvm::MCOperand::getInst
const MCInst * getInst() const
Definition: MCInst.h:124
llvm::HexagonCVIResource::mayStore
bool mayStore() const
Definition: HexagonShuffler.h:95
llvm::popcount
int popcount(T Value) noexcept
Count the number of set bits in a value.
Definition: bit.h:349
Twine.h
MCContext.h
llvm::HexagonShuffler::size
unsigned size() const
Definition: HexagonShuffler.h:205
llvm::operator+=
std::string & operator+=(std::string &buffer, StringRef string)
Definition: StringRef.h:891
llvm::HexagonShuffler::insts
packet_range insts()
Definition: HexagonShuffler.h:221
b
the resulting code requires compare and branches when and if the revised code is with conditional branches instead of More there is a byte word extend before each where there should be only and the condition codes are not remembered when the same two values are compared twice More LSR enhancements i8 and i32 load store addressing modes are identical int b
Definition: README.txt:418
llvm::AMDGPU::PALMD::Key
Key
PAL metadata keys.
Definition: AMDGPUMetadata.h:486
MCInst.h
llvm::HexagonMCInstrInfo::getName
StringRef getName(MCInstrInfo const &MCII, MCInst const &MCI)
Definition: HexagonMCInstrInfo.cpp:374
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
MCSubtargetInfo.h
llvm::HexagonII::TypeV4LDST
@ TypeV4LDST
Definition: HexagonDepITypes.h:63
llvm::HexagonShuffler::Context
MCContext & Context
Definition: HexagonShuffler.h:163
llvm::HexagonII::TypeCVI_SCATTER_NEW_ST
@ TypeCVI_SCATTER_NEW_ST
Definition: HexagonDepITypes.h:31
llvm::HexagonMCInstrInfo::isRestrictNoSlot1Store
bool isRestrictNoSlot1Store(MCInstrInfo const &MCII, MCInst const &MCI)
Definition: HexagonMCInstrInfo.cpp:782
llvm::countTrailingZeros
unsigned countTrailingZeros(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
Definition: MathExtras.h:69
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
SourceMgr.h
llvm::HexagonShuffler::end
iterator end()
Definition: HexagonShuffler.h:212
llvm::HexagonShuffler::reportResourceError
void reportResourceError(HexagonPacketSummary const &Summary, StringRef Err)
Definition: HexagonShuffler.cpp:706
llvm::HexagonII::TypeS_2op
@ TypeS_2op
Definition: HexagonDepITypes.h:60
llvm::MCInstrDesc::mayLoad
bool mayLoad() const
Return true if this instruction could possibly read memory.
Definition: MCInstrDesc.h:437
llvm::HexagonShuffler::tryAuction
std::optional< HexagonPacket > tryAuction(HexagonPacketSummary const &Summary)
Definition: HexagonShuffler.cpp:628
llvm::HexagonInstr
Definition: HexagonShuffler.h:99
llvm::HexagonII::TypeALU64
@ TypeALU64
Definition: HexagonDepITypes.h:20
llvm::SourceMgr::PrintMessage
void PrintMessage(raw_ostream &OS, SMLoc Loc, DiagKind Kind, const Twine &Msg, ArrayRef< SMRange > Ranges={}, ArrayRef< SMFixIt > FixIts={}, bool ShowColors=true) const
Emit a message about the specified location with the specified string.
Definition: SourceMgr.cpp:352
s
multiplies can be turned into SHL s
Definition: README.txt:370
llvm::HexagonShuffler::applySlotRestrictions
bool applySlotRestrictions(HexagonPacketSummary const &Summary, const bool DoShuffle)
Definition: HexagonShuffler.cpp:249
llvm::HexagonII::TypeCVI_GATHER
@ TypeCVI_GATHER
Definition: HexagonDepITypes.h:24
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::HexagonShuffler::AppliedRestrictions
std::vector< std::pair< SMLoc, std::string > > AppliedRestrictions
Definition: HexagonShuffler.h:170
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::MCContext::reportError
void reportError(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:1055
isBranch
static bool isBranch(unsigned Opcode)
Definition: R600InstrInfo.cpp:642
llvm::HexagonShuffler::BundleFlags
int64_t BundleFlags
Definition: HexagonShuffler.h:164
llvm::HexagonII::TypeCVI_SCATTER
@ TypeCVI_SCATTER
Definition: HexagonDepITypes.h:28
llvm::HexagonII::TypeALU32_2op
@ TypeALU32_2op
Definition: HexagonDepITypes.h:17
llvm::HexagonII::TypeCVI_VM_LD
@ TypeCVI_VM_LD
Definition: HexagonDepITypes.h:35
llvm::HexagonShuffler::STI
const MCSubtargetInfo & STI
Definition: HexagonShuffler.h:166
llvm::HexagonShuffler::append
void append(MCInst const &ID, MCInst const *Extender, unsigned S)
Definition: HexagonShuffler.cpp:182
llvm::HexagonShuffler::ValidResourceUsage
bool ValidResourceUsage(HexagonPacketSummary const &Summary)
Definition: HexagonShuffler.cpp:319
llvm::HexagonII::TypeDUPLEX
@ TypeDUPLEX
Definition: HexagonDepITypes.h:49
llvm::any_of
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1742
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
llvm::HexagonResource
Definition: HexagonShuffler.h:38
llvm::HexagonII::TypeCVI_SCATTER_NEW_RST
@ TypeCVI_SCATTER_NEW_RST
Definition: HexagonDepITypes.h:30
llvm::HexagonResource::setWeight
unsigned setWeight(unsigned s)
Definition: HexagonShuffler.cpp:91
Compiler.h
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::HexagonII::TypeCJ
@ TypeCJ
Definition: HexagonDepITypes.h:21
llvm::HexagonShuffler::reset
void reset()
Definition: HexagonShuffler.cpp:176
CVIUnits
Definition: HexagonShuffler.cpp:136
llvm::AMDGPU::SendMsg::Msg
const CustomOperand< const MCSubtargetInfo & > Msg[]
Definition: AMDGPUAsmUtils.cpp:39
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
llvm::MCInst::getLoc
SMLoc getLoc() const
Definition: MCInst.h:204
llvm::stable_sort
void stable_sort(R &&Range)
Definition: STLExtras.h:1948
CVIUnits::Units
unsigned Units
Definition: HexagonShuffler.cpp:137
llvm::MCInstrInfo
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:26
llvm::HexagonMCInstrInfo::getType
unsigned getType(MCInstrInfo const &MCII, MCInst const &MCI)
Return the Hexagon ISA class for the insn.
Definition: HexagonMCInstrInfo.cpp:423
llvm::HexagonII::TypeS_3op
@ TypeS_3op
Definition: HexagonDepITypes.h:61
llvm::HexagonShuffler::restrictPreferSlot3
void restrictPreferSlot3(HexagonPacketSummary const &Summary, const bool DoShuffle)
Definition: HexagonShuffler.cpp:585
Slot3Mask
static const unsigned Slot3Mask
Definition: HexagonShuffler.cpp:192
checkHVXPipes
static bool checkHVXPipes(const HVXInstsT &hvxInsts, unsigned startIdx, unsigned usedUnits)
Definition: HexagonShuffler.cpp:149
llvm::HexagonShuffler::ValidPacketMemoryOps
bool ValidPacketMemoryOps(HexagonPacketSummary const &Summary) const
Definition: HexagonShuffler.cpp:572
llvm::SmallVectorImpl::clear
void clear()
Definition: SmallVector.h:614
llvm::HexagonII::TypeCVI_VM_ST
@ TypeCVI_VM_ST
Definition: HexagonDepITypes.h:37
llvm::HexagonShuffler::HexagonShuffler
HexagonShuffler(MCContext &Context, bool ReportErrors, MCInstrInfo const &MCII, MCSubtargetInfo const &STI)
Definition: HexagonShuffler.cpp:168
llvm::HexagonII::TypeCVI_VM_STU
@ TypeCVI_VM_STU
Definition: HexagonDepITypes.h:38
llvm::HexagonII::TypeNCJ
@ TypeNCJ
Definition: HexagonDepITypes.h:56
llvm::HexagonShuffler::ReportErrors
bool ReportErrors
Definition: HexagonShuffler.h:168
SmallVector.h
llvm::MCContext::getSourceManager
const SourceMgr * getSourceManager() const
Definition: MCContext.h:435
llvm::MCInst::getOperand
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:206
SlotMaskToText
static std::string SlotMaskToText(unsigned SlotMask)
Definition: HexagonShuffler.cpp:443
llvm::HexagonII::TypeCVI_SCATTER_DV
@ TypeCVI_SCATTER_DV
Definition: HexagonDepITypes.h:29
llvm::HexagonInstr::lessCore
static bool lessCore(const HexagonInstr &A, const HexagonInstr &B)
Definition: HexagonShuffler.h:122
CVIUnits::Lanes
unsigned Lanes
Definition: HexagonShuffler.cpp:138
llvm::HexagonII::TypeJ
@ TypeJ
Definition: HexagonDepITypes.h:52
raw_ostream.h
HEXAGON_PACKET_SIZE
#define HEXAGON_PACKET_SIZE
Definition: HexagonMCTargetDesc.h:36
llvm::HexagonShuffler::check
bool check(const bool RequireShuffle=true)
Check that the packet is legal and enforce relative insn order.
Definition: HexagonShuffler.cpp:611
llvm::format_hex
FormattedNumber format_hex(uint64_t N, unsigned Width, bool Upper=false)
format_hex - Output N as a fixed width hexadecimal.
Definition: Format.h:186
llvm::MCSubtargetInfo
Generic base class for all target subtargets.
Definition: MCSubtargetInfo.h:76
llvm::HexagonII::TypeCVI_VM_TMP_LD
@ TypeCVI_VM_TMP_LD
Definition: HexagonDepITypes.h:39
Debug.h
llvm::raw_ostream::write_hex
raw_ostream & write_hex(unsigned long long N)
Output N in hexadecimal, without any prefix or padding.
Definition: raw_ostream.cpp:138