LLVM  15.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 <utility>
32 #include <vector>
33 
34 #define DEBUG_TYPE "hexagon-shuffle"
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  MCSubtargetInfo const &STI,
110  unsigned s,
111  MCInst const *id)
112  : HexagonResource(s) {
113 
114  const unsigned ItinUnits = HexagonMCInstrInfo::getCVIResources(MCII, STI, *id);
115  unsigned Lanes;
116  const unsigned Units = HexagonConvertUnits(ItinUnits, &Lanes);
117 
118  if (Units == 0 && Lanes == 0) {
119  // For core insns.
120  Valid = false;
121  setUnits(0);
122  setLanes(0);
123  setLoad(false);
124  setStore(false);
125  } else {
126  // For an HVX insn.
127  Valid = true;
128  setUnits(Units);
129  setLanes(Lanes);
130  setLoad(HexagonMCInstrInfo::getDesc(MCII, *id).mayLoad());
131  setStore(HexagonMCInstrInfo::getDesc(MCII, *id).mayStore());
132  }
133 }
134 
135 struct CVIUnits {
136  unsigned Units;
137  unsigned Lanes;
138 };
140 
141 static unsigned makeAllBits(unsigned startBit, unsigned Lanes)
142 {
143  for (unsigned i = 1; i < Lanes; ++i)
144  startBit = (startBit << 1) | startBit;
145  return startBit;
146 }
147 
148 static bool checkHVXPipes(const HVXInstsT &hvxInsts, unsigned startIdx,
149  unsigned usedUnits) {
150  if (startIdx < hvxInsts.size()) {
151  if (!hvxInsts[startIdx].Units)
152  return checkHVXPipes(hvxInsts, startIdx + 1, usedUnits);
153  for (unsigned b = 0x1; b <= 0x8; b <<= 1) {
154  if ((hvxInsts[startIdx].Units & b) == 0)
155  continue;
156  unsigned allBits = makeAllBits(b, hvxInsts[startIdx].Lanes);
157  if ((allBits & usedUnits) == 0) {
158  if (checkHVXPipes(hvxInsts, startIdx + 1, usedUnits | allBits))
159  return true;
160  }
161  }
162  return false;
163  }
164  return true;
165 }
166 
168  MCInstrInfo const &MCII,
169  MCSubtargetInfo const &STI)
170  : Context(Context), BundleFlags(), MCII(MCII), STI(STI),
171  ReportErrors(ReportErrors), CheckFailure() {
172  reset();
173 }
174 
176  Packet.clear();
177  BundleFlags = 0;
178  CheckFailure = false;
179 }
180 
181 void HexagonShuffler::append(MCInst const &ID, MCInst const *Extender,
182  unsigned S) {
183  HexagonInstr PI(MCII, STI, &ID, Extender, S);
184 
185  Packet.push_back(PI);
186 }
187 
188 
189 static const unsigned Slot0Mask = 1 << 0;
190 static const unsigned Slot1Mask = 1 << 1;
191 static const unsigned Slot3Mask = 1 << 3;
192 static const unsigned slotSingleLoad = Slot0Mask;
193 static const unsigned slotSingleStore = Slot0Mask;
194 
195 void HexagonShuffler::restrictSlot1AOK(HexagonPacketSummary const &Summary) {
196  if (Summary.Slot1AOKLoc)
197  for (HexagonInstr &ISJ : insts()) {
198  MCInst const &Inst = ISJ.getDesc();
199  const unsigned Type = HexagonMCInstrInfo::getType(MCII, Inst);
203  const unsigned Units = ISJ.Core.getUnits();
204 
205  if (Units & Slot1Mask) {
206  AppliedRestrictions.push_back(std::make_pair(
207  Inst.getLoc(),
208  "Instruction was restricted from being in slot 1"));
209  AppliedRestrictions.push_back(std::make_pair(
210  *Summary.Slot1AOKLoc, "Instruction can only be combined "
211  "with an ALU instruction in slot 1"));
212  ISJ.Core.setUnits(Units & ~Slot1Mask);
213  }
214  }
215  }
216 }
217 
219  HexagonPacketSummary const &Summary) {
220  // If this packet contains an instruction that bars slot-1 stores,
221  // we should mask off slot 1 from all of the store instructions in
222  // this packet.
223 
224  if (!Summary.NoSlot1StoreLoc)
225  return;
226 
227  bool AppliedRestriction = false;
228 
229  for (HexagonInstr &ISJ : insts()) {
230  MCInst const &Inst = ISJ.getDesc();
231  if (HexagonMCInstrInfo::getDesc(MCII, Inst).mayStore()) {
232  unsigned Units = ISJ.Core.getUnits();
233  if (Units & Slot1Mask) {
234  AppliedRestriction = true;
235  AppliedRestrictions.push_back(std::make_pair(
236  Inst.getLoc(), "Instruction was restricted from being in slot 1"));
237  ISJ.Core.setUnits(Units & ~Slot1Mask);
238  }
239  }
240  }
241 
242  if (AppliedRestriction)
243  AppliedRestrictions.push_back(
244  std::make_pair(*Summary.NoSlot1StoreLoc,
245  "Instruction does not allow a store in slot 1"));
246 }
247 
248 bool HexagonShuffler::applySlotRestrictions(HexagonPacketSummary const &Summary,
249  const bool DoShuffle) {
250  // These restrictions can modify the slot masks in the instructions
251  // in the Packet member. They should run unconditionally and their
252  // order does not matter.
253  restrictSlot1AOK(Summary);
254  restrictNoSlot1Store(Summary);
255 
256  permitNonSlot();
257 
258  // These restrictions can modify the slot masks in the instructions
259  // in the Packet member, but they can also detect constraint failures
260  // which are fatal.
261  if (!CheckFailure)
262  restrictStoreLoadOrder(Summary);
263  if (!CheckFailure)
264  restrictBranchOrder(Summary);
265  if (!CheckFailure)
266  restrictPreferSlot3(Summary, DoShuffle);
267  return !CheckFailure;
268 }
269 
270 void HexagonShuffler::restrictBranchOrder(HexagonPacketSummary const &Summary) {
271  // preserve branch order
272  const bool HasMultipleBranches = Summary.branchInsts.size() > 1;
273  if (!HasMultipleBranches)
274  return;
275 
276  if (Summary.branchInsts.size() > 2) {
277  reportError(Twine("too many branches in packet"));
278  return;
279  }
280 
281  const static std::pair<unsigned, unsigned> jumpSlots[] = {
282  {8, 4}, {8, 2}, {8, 1}, {4, 2}, {4, 1}, {2, 1}};
283  // try all possible choices
284  for (std::pair<unsigned, unsigned> jumpSlot : jumpSlots) {
285  // validate first jump with this slot rule
286  if (!(jumpSlot.first & Summary.branchInsts[0]->Core.getUnits()))
287  continue;
288 
289  // validate second jump with this slot rule
290  if (!(jumpSlot.second & Summary.branchInsts[1]->Core.getUnits()))
291  continue;
292 
293  // both valid for this configuration, set new slot rules
294  const HexagonPacket PacketSave = Packet;
295  Summary.branchInsts[0]->Core.setUnits(jumpSlot.first);
296  Summary.branchInsts[1]->Core.setUnits(jumpSlot.second);
297 
298  const bool HasShuffledPacket = tryAuction(Summary).has_value();
299  if (HasShuffledPacket)
300  return;
301 
302  // if yes, great, if not then restore original slot mask
303  // restore original values
304  Packet = PacketSave;
305  }
306 
307  reportResourceError(Summary, "out of slots");
308 }
309 
311  for (HexagonInstr &ISJ : insts()) {
312  const bool RequiresSlot = HexagonMCInstrInfo::requiresSlot(STI, *ISJ.ID);
313  if (!RequiresSlot)
314  ISJ.Core.setAllUnits();
315  }
316 }
317 
318 bool HexagonShuffler::ValidResourceUsage(HexagonPacketSummary const &Summary) {
319  Optional<HexagonPacket> ShuffledPacket = tryAuction(Summary);
320 
321  if (!ShuffledPacket) {
322  reportResourceError(Summary, "slot error");
323  return false;
324  }
325 
326  // Verify the CVI slot subscriptions.
327  llvm::stable_sort(*ShuffledPacket, HexagonInstr::lessCVI);
328  // create vector of hvx instructions to check
329  HVXInstsT hvxInsts;
330  hvxInsts.clear();
331  for (const auto &I : *ShuffledPacket) {
332  struct CVIUnits inst;
333  inst.Units = I.CVI.getUnits();
334  inst.Lanes = I.CVI.getLanes();
335  if (inst.Units == 0)
336  continue; // not an hvx inst or an hvx inst that doesn't uses any pipes
337  hvxInsts.push_back(inst);
338  }
339 
340  // if there are any hvx instructions in this packet, check pipe usage
341  if (hvxInsts.size() > 0) {
342  unsigned startIdx, usedUnits;
343  startIdx = usedUnits = 0x0;
344  if (!checkHVXPipes(hvxInsts, startIdx, usedUnits)) {
345  // too many pipes used to be valid
346  reportError(Twine("invalid instruction packet: slot error"));
347  return false;
348  }
349  }
350 
351  Packet = *ShuffledPacket;
352 
353  return true;
354 }
355 
357  HexagonPacketSummary const &Summary) {
358  // Modify packet accordingly.
359  // TODO: need to reserve slots #0 and #1 for duplex insns.
360  static const unsigned slotFirstLoadStore = Slot1Mask;
361  static const unsigned slotLastLoadStore = Slot0Mask;
362  unsigned slotLoadStore = slotFirstLoadStore;
363 
364  for (iterator ISJ = begin(); ISJ != end(); ++ISJ) {
365  MCInst const &ID = ISJ->getDesc();
366 
367  if (!ISJ->Core.getUnits())
368  // Error if insn may not be executed in any slot.
369  return false;
370 
371  // A single load must use slot #0.
373  if (Summary.loads == 1 && Summary.loads == Summary.memory &&
374  Summary.memops == 0)
375  // Pin the load to slot #0.
376  switch (ID.getOpcode()) {
377  case Hexagon::V6_vgathermw:
378  case Hexagon::V6_vgathermh:
379  case Hexagon::V6_vgathermhw:
380  case Hexagon::V6_vgathermwq:
381  case Hexagon::V6_vgathermhq:
382  case Hexagon::V6_vgathermhwq:
383  // Slot1 only loads
384  break;
385  default:
386  ISJ->Core.setUnits(ISJ->Core.getUnits() & slotSingleLoad);
387  break;
388  }
389  else if (Summary.loads >= 1 && isMemReorderDisabled()) { // }:mem_noshuf
390  // Loads must keep the original order ONLY if
391  // isMemReorderDisabled() == true
392  if (slotLoadStore < slotLastLoadStore) {
393  // Error if no more slots available for loads.
394  reportError("invalid instruction packet: too many loads");
395  return false;
396  }
397  // Pin the load to the highest slot available to it.
398  ISJ->Core.setUnits(ISJ->Core.getUnits() & slotLoadStore);
399  // Update the next highest slot available to loads.
400  slotLoadStore >>= 1;
401  }
402  }
403 
404  // A single store must use slot #0.
405  if (HexagonMCInstrInfo::getDesc(MCII, ID).mayStore()) {
406  if (!Summary.store0) {
407  const bool PacketHasNoOnlySlot0 =
408  llvm::none_of(insts(), [&](HexagonInstr const &I) {
409  return I.Core.getUnits() == Slot0Mask &&
410  I.ID->getOpcode() != ID.getOpcode();
411  });
412  const bool SafeToMoveToSlot0 =
413  (Summary.loads == 0) ||
414  (!isMemReorderDisabled() && PacketHasNoOnlySlot0);
415 
416  if (Summary.stores == 1 && SafeToMoveToSlot0)
417  // Pin the store to slot #0 only if isMemReorderDisabled() == false
418  ISJ->Core.setUnits(ISJ->Core.getUnits() & slotSingleStore);
419  else if (Summary.stores >= 1) {
420  if (slotLoadStore < slotLastLoadStore) {
421  // Error if no more slots available for stores.
422  reportError("invalid instruction packet: too many stores");
423  return false;
424  }
425  // Pin the store to the highest slot available to it.
426  ISJ->Core.setUnits(ISJ->Core.getUnits() & slotLoadStore);
427  // Update the next highest slot available to stores.
428  slotLoadStore >>= 1;
429  }
430  }
431  if (Summary.store1 && Summary.stores > 1) {
432  // Error if a single store with another store.
433  reportError("invalid instruction packet: too many stores");
434  return false;
435  }
436  }
437  }
438 
439  return true;
440 }
441 
442 static std::string SlotMaskToText(unsigned SlotMask) {
444  for (unsigned SlotNum = 0; SlotNum < HEXAGON_PACKET_SIZE; SlotNum++)
445  if ((SlotMask & (1 << SlotNum)) != 0)
446  Slots.push_back(utostr(SlotNum));
447 
448  return llvm::join(Slots, StringRef(", "));
449 }
450 
451 HexagonShuffler::HexagonPacketSummary HexagonShuffler::GetPacketSummary() {
452  HexagonPacketSummary Summary = HexagonPacketSummary();
453 
454  // Collect information from the insns in the packet.
455  for (iterator ISJ = begin(); ISJ != end(); ++ISJ) {
456  MCInst const &ID = ISJ->getDesc();
457 
459  Summary.Slot1AOKLoc = ID.getLoc();
461  Summary.NoSlot1StoreLoc = ID.getLoc();
462 
464  ++Summary.pSlot3Cnt;
465  Summary.PrefSlot3Inst = ISJ;
466  }
467  const unsigned ReservedSlots =
469  Summary.ReservedSlotMask |= ReservedSlots;
470  if (ReservedSlots != 0)
471  AppliedRestrictions.push_back(std::make_pair(ID.getLoc(),
472  (Twine("Instruction has reserved slots: ") +
473  SlotMaskToText(ReservedSlots)).str()));
474 
475  switch (HexagonMCInstrInfo::getType(MCII, ID)) {
479  break;
480  case HexagonII::TypeJ:
482  Summary.branchInsts.push_back(ISJ);
483  break;
490  ++Summary.NonZCVIloads;
493  ++Summary.AllCVIloads;
495  case HexagonII::TypeLD:
496  ++Summary.loads;
497  ++Summary.memory;
498  if (ISJ->Core.getUnits() == slotSingleLoad ||
500  ++Summary.load0;
501  if (HexagonMCInstrInfo::getDesc(MCII, ID).isReturn())
502  Summary.branchInsts.push_back(ISJ);
503  break;
512  ++Summary.CVIstores;
514  case HexagonII::TypeST:
515  ++Summary.stores;
516  ++Summary.memory;
517  if (ISJ->Core.getUnits() == slotSingleStore ||
519  ++Summary.store0;
520  break;
522  ++Summary.loads;
523  ++Summary.stores;
524  ++Summary.store1;
525  ++Summary.memops;
526  ++Summary.memory;
527  break;
528  case HexagonII::TypeNCJ:
529  ++Summary.memory; // NV insns are memory-like.
530  Summary.branchInsts.push_back(ISJ);
531  break;
533  if (HexagonMCInstrInfo::getDesc(MCII, ID).mayLoad()) {
534  ++Summary.loads;
535  ++Summary.memory;
536  if (ISJ->Core.getUnits() == slotSingleLoad ||
539  ++Summary.load0;
540  } else {
542  ++Summary.memory;
543  ++Summary.stores;
544  }
545  break;
546  case HexagonII::TypeCR:
547  // Legacy conditional branch predicated on a register.
548  case HexagonII::TypeCJ:
550  Summary.branchInsts.push_back(ISJ);
551  break;
552  case HexagonII::TypeDUPLEX: {
553  ++Summary.duplex;
554  MCInst const &Inst0 = *ID.getOperand(0).getInst();
555  MCInst const &Inst1 = *ID.getOperand(1).getInst();
557  Summary.branchInsts.push_back(ISJ);
559  Summary.branchInsts.push_back(ISJ);
560  if (HexagonMCInstrInfo::getDesc(MCII, Inst0).isReturn())
561  Summary.branchInsts.push_back(ISJ);
562  if (HexagonMCInstrInfo::getDesc(MCII, Inst1).isReturn())
563  Summary.branchInsts.push_back(ISJ);
564  break;
565  }
566  }
567  }
568  return Summary;
569 }
570 
572  HexagonPacketSummary const &Summary) const {
573  // Check if the packet is legal.
574  const unsigned ZCVIloads = Summary.AllCVIloads - Summary.NonZCVIloads;
575  const bool ValidHVXMem =
576  Summary.NonZCVIloads <= 1 && ZCVIloads <= 1 && Summary.CVIstores <= 1;
577  const bool InvalidPacket =
578  ((Summary.load0 > 1 || Summary.store0 > 1 || !ValidHVXMem) ||
579  (Summary.duplex > 1 || (Summary.duplex && Summary.memory)));
580 
581  return !InvalidPacket;
582 }
583 
584 void HexagonShuffler::restrictPreferSlot3(HexagonPacketSummary const &Summary,
585  const bool DoShuffle) {
586  // flag if an instruction requires to be in slot 3
587  const bool HasOnlySlot3 = llvm::any_of(insts(), [&](HexagonInstr const &I) {
588  return (I.Core.getUnits() == Slot3Mask);
589  });
590  const bool NeedsPrefSlot3Shuffle = Summary.branchInsts.size() <= 1 &&
591  !HasOnlySlot3 && Summary.pSlot3Cnt == 1 &&
592  Summary.PrefSlot3Inst && DoShuffle;
593 
594  if (!NeedsPrefSlot3Shuffle)
595  return;
596 
597  HexagonInstr *PrefSlot3Inst = *Summary.PrefSlot3Inst;
598  // save off slot mask of instruction marked with A_PREFER_SLOT3
599  // and then pin it to slot #3
600  const unsigned saveUnits = PrefSlot3Inst->Core.getUnits();
601  PrefSlot3Inst->Core.setUnits(saveUnits & Slot3Mask);
602  const bool HasShuffledPacket = tryAuction(Summary).has_value();
603  if (HasShuffledPacket)
604  return;
605 
606  PrefSlot3Inst->Core.setUnits(saveUnits);
607 }
608 
609 /// Check that the packet is legal and enforce relative insn order.
610 bool HexagonShuffler::check(const bool RequireShuffle) {
611  const HexagonPacketSummary Summary = GetPacketSummary();
612  if (!applySlotRestrictions(Summary, RequireShuffle))
613  return false;
614 
615  if (!ValidPacketMemoryOps(Summary)) {
616  reportError("invalid instruction packet");
617  return false;
618  }
619 
620  if (RequireShuffle)
621  ValidResourceUsage(Summary);
622 
623  return !CheckFailure;
624 }
625 
627 HexagonShuffler::tryAuction(HexagonPacketSummary const &Summary) {
628  HexagonPacket PacketResult = Packet;
629  HexagonUnitAuction AuctionCore(Summary.ReservedSlotMask);
631 
632  const bool ValidSlots =
633  llvm::all_of(insts(PacketResult), [&AuctionCore](HexagonInstr const &I) {
634  return AuctionCore.bid(I.Core.getUnits());
635  });
636 
637  LLVM_DEBUG(
638  dbgs() << "Shuffle attempt: " << (ValidSlots ? "passed" : "failed")
639  << "\n";
640  for (HexagonInstr const &ISJ : insts(PacketResult))
641  dbgs() << "\t" << HexagonMCInstrInfo::getName(MCII, *ISJ.ID) << ": "
642  << llvm::format_hex(ISJ.Core.getUnits(), 4, true) << "\n";
643  );
644 
646  if (ValidSlots)
647  Res = PacketResult;
648 
649  return Res;
650 }
651 
653  if (size() > HEXAGON_PACKET_SIZE) {
654  // Ignore a packet with with more than what a packet can hold
655  // or with compound or duplex insns for now.
656  reportError("invalid instruction packet");
657  return false;
658  }
659 
660  // Check and prepare packet.
661  bool Ok = check();
662  if (size() > 1 && Ok)
663  // Reorder the handles for each slot.
664  for (unsigned nSlot = 0, emptySlots = 0; nSlot < HEXAGON_PACKET_SIZE;
665  ++nSlot) {
666  iterator ISJ, ISK;
667  unsigned slotSkip, slotWeight;
668 
669  // Prioritize the handles considering their restrictions.
670  for (ISJ = ISK = Packet.begin(), slotSkip = slotWeight = 0;
671  ISK != Packet.end(); ++ISK, ++slotSkip)
672  if (slotSkip < nSlot - emptySlots)
673  // Note which handle to begin at.
674  ++ISJ;
675  else
676  // Calculate the weight of the slot.
677  slotWeight += ISK->Core.setWeight(HEXAGON_PACKET_SIZE - nSlot - 1);
678 
679  if (slotWeight)
680  // Sort the packet, favoring source order,
681  // beginning after the previous slot.
682  std::stable_sort(ISJ, Packet.end());
683  else
684  // Skip unused slot.
685  ++emptySlots;
686  }
687 
688  LLVM_DEBUG(
689  for (HexagonInstr const &ISJ : insts()) {
690  dbgs().write_hex(ISJ.Core.getUnits());
691  if (ISJ.CVI.isValid()) {
692  dbgs() << '/';
693  dbgs().write_hex(ISJ.CVI.getUnits()) << '|';
694  dbgs() << ISJ.CVI.getLanes();
695  }
696  dbgs() << ':'
697  << HexagonMCInstrInfo::getDesc(MCII, ISJ.getDesc()).getOpcode()
698  << '\n';
699  } dbgs() << '\n';
700  );
701 
702  return Ok;
703 }
704 
705 void HexagonShuffler::reportResourceError(HexagonPacketSummary const &Summary, StringRef Err) {
706  if (ReportErrors)
707  reportResourceUsage(Summary);
708  reportError(Twine("invalid instruction packet: ") + Err);
709 }
710 
711 
712 void HexagonShuffler::reportResourceUsage(HexagonPacketSummary const &Summary) {
713  auto SM = Context.getSourceManager();
714  if (SM) {
715  for (HexagonInstr const &I : insts()) {
716  const unsigned Units = I.Core.getUnits();
717 
719  const std::string UnitsText = Units ? SlotMaskToText(Units) : "<None>";
720  SM->PrintMessage(I.ID->getLoc(), SourceMgr::DK_Note,
721  Twine("Instruction can utilize slots: ") +
722  UnitsText);
723  }
724  else if (!HexagonMCInstrInfo::isImmext(*I.ID))
725  SM->PrintMessage(I.ID->getLoc(), SourceMgr::DK_Note,
726  "Instruction does not require a slot");
727  }
728  }
729 }
730 
732  CheckFailure = true;
733  if (ReportErrors) {
734  for (auto const &I : AppliedRestrictions) {
735  auto SM = Context.getSourceManager();
736  if (SM)
737  SM->PrintMessage(I.first, SourceMgr::DK_Note, I.second);
738  }
740  }
741 }
i
i
Definition: README.txt:29
HexagonMCTargetDesc.h
llvm::HexagonShuffler::MCII
const MCInstrInfo & MCII
Definition: HexagonShuffler.h:164
slotSingleStore
static const unsigned slotSingleStore
Definition: HexagonShuffler.cpp:193
llvm::MCInstrDesc::getOpcode
unsigned getOpcode() const
Return the opcode number for this descriptor.
Definition: MCInstrDesc.h:223
llvm::HexagonShuffler::begin
iterator begin()
Definition: HexagonShuffler.h:210
llvm::HexagonShuffler::GetPacketSummary
HexagonPacketSummary GetPacketSummary()
Definition: HexagonShuffler.cpp:451
MathExtras.h
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
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:20
llvm::HexagonShuffler::reportError
void reportError(Twine const &Msg)
Definition: HexagonShuffler.cpp:731
llvm::HexagonShuffler::shuffle
bool shuffle()
Definition: HexagonShuffler.cpp:652
llvm::HexagonConvertUnits
unsigned HexagonConvertUnits(unsigned ItinUnits, unsigned *Lanes)
Definition: HexagonMCTargetDesc.cpp:161
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:1631
llvm::HexagonII::TypeCVI_VM_VP_LDU
@ TypeCVI_VM_VP_LDU
Definition: HexagonDepITypes.h:41
llvm::HexagonCVIResource::HexagonCVIResource
HexagonCVIResource(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, unsigned s, MCInst const *id)
Definition: HexagonShuffler.cpp:108
llvm::HexagonShuffler::CheckFailure
bool CheckFailure
Definition: HexagonShuffler.h:168
llvm::HexagonCVIResource::mayLoad
bool mayLoad() const
Definition: HexagonShuffler.h:93
llvm::HexagonII::TypeCR
@ TypeCR
Definition: HexagonDepITypes.h:23
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:356
llvm::HexagonShuffler::Loc
SMLoc Loc
Definition: HexagonShuffler.h:166
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:45
llvm::HexagonShuffler::isMemReorderDisabled
bool isMemReorderDisabled() const
Definition: HexagonShuffler.h:206
llvm::HexagonII::TypeLD
@ TypeLD
Definition: HexagonDepITypes.h:54
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1185
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:189
llvm::HexagonShuffler::reportResourceUsage
void reportResourceUsage(HexagonPacketSummary const &Summary)
Definition: HexagonShuffler.cpp:712
llvm::HexagonII::TypeALU32_3op
@ TypeALU32_3op
Definition: HexagonDepITypes.h:19
Slot0Mask
static const unsigned Slot0Mask
Definition: HexagonShuffler.cpp:189
llvm::HexagonShuffler::restrictNoSlot1Store
void restrictNoSlot1Store(HexagonPacketSummary const &Summary)
Definition: HexagonShuffler.cpp:218
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:59
llvm::HexagonII::TypeCVI_GATHER_RST
@ TypeCVI_GATHER_RST
Definition: HexagonDepITypes.h:27
llvm::HexagonMCInstrInfo::isImmext
bool isImmext(MCInst const &MCI)
Definition: HexagonMCInstrInfo.cpp:642
llvm::HexagonResource::getUnits
unsigned getUnits() const
Definition: HexagonShuffler.h:55
llvm::Optional
Definition: APInt.h:33
llvm::HexagonII::TypeCVI_ZW
@ TypeCVI_ZW
Definition: HexagonDepITypes.h:49
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:192
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:26
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
HexagonBaseInfo.h
llvm::HexagonShuffler::permitNonSlot
void permitNonSlot()
Definition: HexagonShuffler.cpp:310
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:141
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:63
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:1617
Slot1Mask
static const unsigned Slot1Mask
Definition: HexagonShuffler.cpp:190
llvm::HexagonII::TypeCVI_VM_NEW_ST
@ TypeCVI_VM_NEW_ST
Definition: HexagonDepITypes.h:37
llvm::HexagonInstr::lessCVI
static bool lessCVI(const HexagonInstr &A, const HexagonInstr &B)
Definition: HexagonShuffler.h:126
llvm::HexagonShuffler::restrictSlot1AOK
void restrictSlot1AOK(HexagonPacketSummary const &Summary)
Definition: HexagonShuffler.cpp:195
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:33
llvm::HexagonShuffler::restrictBranchOrder
void restrictBranchOrder(HexagonPacketSummary const &Summary)
Definition: HexagonShuffler.cpp:270
llvm::MCOperand::getInst
const MCInst * getInst() const
Definition: MCInst.h:124
llvm::HexagonCVIResource::mayStore
bool mayStore() const
Definition: HexagonShuffler.h:94
Twine.h
MCContext.h
llvm::HexagonShuffler::size
unsigned size() const
Definition: HexagonShuffler.h:204
llvm::operator+=
std::string & operator+=(std::string &buffer, StringRef string)
Definition: StringRef.h:964
llvm::HexagonShuffler::insts
packet_range insts()
Definition: HexagonShuffler.h:220
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:64
llvm::HexagonShuffler::Context
MCContext & Context
Definition: HexagonShuffler.h:162
llvm::HexagonII::TypeCVI_SCATTER_NEW_ST
@ TypeCVI_SCATTER_NEW_ST
Definition: HexagonDepITypes.h:32
llvm::HexagonMCInstrInfo::isRestrictNoSlot1Store
bool isRestrictNoSlot1Store(MCInstrInfo const &MCII, MCInst const &MCI)
Definition: HexagonMCInstrInfo.cpp:782
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:211
llvm::HexagonShuffler::reportResourceError
void reportResourceError(HexagonPacketSummary const &Summary, StringRef Err)
Definition: HexagonShuffler.cpp:705
llvm::HexagonII::TypeS_2op
@ TypeS_2op
Definition: HexagonDepITypes.h:61
llvm::MCInstrDesc::mayLoad
bool mayLoad() const
Return true if this instruction could possibly read memory.
Definition: MCInstrDesc.h:435
llvm::countPopulation
unsigned countPopulation(T Value)
Count the number of set bits in a value.
Definition: MathExtras.h:567
llvm::HexagonInstr
Definition: HexagonShuffler.h:98
llvm::HexagonII::TypeALU64
@ TypeALU64
Definition: HexagonDepITypes.h:21
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:348
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:248
llvm::HexagonII::TypeCVI_GATHER
@ TypeCVI_GATHER
Definition: HexagonDepITypes.h:25
llvm::HexagonShuffler::tryAuction
Optional< HexagonPacket > tryAuction(HexagonPacketSummary const &Summary)
Definition: HexagonShuffler.cpp:627
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::HexagonShuffler::AppliedRestrictions
std::vector< std::pair< SMLoc, std::string > > AppliedRestrictions
Definition: HexagonShuffler.h:169
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::MCContext::reportError
void reportError(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:1037
isBranch
static bool isBranch(unsigned Opcode)
Definition: R600InstrInfo.cpp:642
llvm::HexagonShuffler::BundleFlags
int64_t BundleFlags
Definition: HexagonShuffler.h:163
llvm::HexagonII::TypeCVI_SCATTER
@ TypeCVI_SCATTER
Definition: HexagonDepITypes.h:29
llvm::HexagonII::TypeALU32_2op
@ TypeALU32_2op
Definition: HexagonDepITypes.h:18
llvm::HexagonII::TypeCVI_VM_LD
@ TypeCVI_VM_LD
Definition: HexagonDepITypes.h:36
llvm::HexagonShuffler::STI
const MCSubtargetInfo & STI
Definition: HexagonShuffler.h:165
llvm::HexagonShuffler::append
void append(MCInst const &ID, MCInst const *Extender, unsigned S)
Definition: HexagonShuffler.cpp:181
llvm::HexagonShuffler::ValidResourceUsage
bool ValidResourceUsage(HexagonPacketSummary const &Summary)
Definition: HexagonShuffler.cpp:318
llvm::HexagonII::TypeDUPLEX
@ TypeDUPLEX
Definition: HexagonDepITypes.h:50
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:1624
llvm::countTrailingZeros
unsigned countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the least significant bit to the most stopping at the first 1.
Definition: MathExtras.h:156
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::HexagonResource
Definition: HexagonShuffler.h:37
llvm::HexagonII::TypeCVI_SCATTER_NEW_RST
@ TypeCVI_SCATTER_NEW_RST
Definition: HexagonDepITypes.h:31
llvm::HexagonResource::setWeight
unsigned setWeight(unsigned s)
Definition: HexagonShuffler.cpp:90
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:22
llvm::HexagonShuffler::reset
void reset()
Definition: HexagonShuffler.cpp:175
LLVM_FALLTHROUGH
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
Definition: Compiler.h:280
CVIUnits
Definition: HexagonShuffler.cpp:135
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:83
llvm::MCInst::getLoc
SMLoc getLoc() const
Definition: MCInst.h:204
llvm::stable_sort
void stable_sort(R &&Range)
Definition: STLExtras.h:1761
CVIUnits::Units
unsigned Units
Definition: HexagonShuffler.cpp:136
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:62
llvm::HexagonShuffler::restrictPreferSlot3
void restrictPreferSlot3(HexagonPacketSummary const &Summary, const bool DoShuffle)
Definition: HexagonShuffler.cpp:584
Slot3Mask
static const unsigned Slot3Mask
Definition: HexagonShuffler.cpp:191
checkHVXPipes
static bool checkHVXPipes(const HVXInstsT &hvxInsts, unsigned startIdx, unsigned usedUnits)
Definition: HexagonShuffler.cpp:148
llvm::HexagonShuffler::ValidPacketMemoryOps
bool ValidPacketMemoryOps(HexagonPacketSummary const &Summary) const
Definition: HexagonShuffler.cpp:571
llvm::SmallVectorImpl::clear
void clear()
Definition: SmallVector.h:591
llvm::HexagonII::TypeCVI_VM_ST
@ TypeCVI_VM_ST
Definition: HexagonDepITypes.h:38
llvm::HexagonShuffler::HexagonShuffler
HexagonShuffler(MCContext &Context, bool ReportErrors, MCInstrInfo const &MCII, MCSubtargetInfo const &STI)
Definition: HexagonShuffler.cpp:167
llvm::HexagonII::TypeCVI_VM_STU
@ TypeCVI_VM_STU
Definition: HexagonDepITypes.h:39
llvm::HexagonII::TypeNCJ
@ TypeNCJ
Definition: HexagonDepITypes.h:57
llvm::HexagonShuffler::ReportErrors
bool ReportErrors
Definition: HexagonShuffler.h:167
SmallVector.h
llvm::MCContext::getSourceManager
const SourceMgr * getSourceManager() const
Definition: MCContext.h:432
llvm::MCInst::getOperand
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:206
SlotMaskToText
static std::string SlotMaskToText(unsigned SlotMask)
Definition: HexagonShuffler.cpp:442
llvm::HexagonII::TypeCVI_SCATTER_DV
@ TypeCVI_SCATTER_DV
Definition: HexagonDepITypes.h:30
llvm::HexagonInstr::lessCore
static bool lessCore(const HexagonInstr &A, const HexagonInstr &B)
Definition: HexagonShuffler.h:121
CVIUnits::Lanes
unsigned Lanes
Definition: HexagonShuffler.cpp:137
llvm::HexagonII::TypeJ
@ TypeJ
Definition: HexagonDepITypes.h:53
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:610
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:40
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:139