1 //===- HexagonShuffler.cpp - Instruction bundle shuffling -----------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This implements the shuffling of insns inside a bundle according to the
10 // packet formation rules of the Hexagon ISA.
12 //===----------------------------------------------------------------------===//
14 #define DEBUG_TYPE "hexagon-shuffle"
16 #include "MCTargetDesc/HexagonShuffler.h"
17 #include "MCTargetDesc/HexagonBaseInfo.h"
18 #include "MCTargetDesc/HexagonMCInstrInfo.h"
19 #include "MCTargetDesc/HexagonMCTargetDesc.h"
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"
25 #include "llvm/MC/MCSubtargetInfo.h"
26 #include "llvm/Support/Compiler.h"
27 #include "llvm/Support/Debug.h"
28 #include "llvm/Support/MathExtras.h"
29 #include "llvm/Support/SourceMgr.h"
30 #include "llvm/Support/raw_ostream.h"
40 // Insn shuffling priority.
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.
49 HexagonBid() = default;
50 HexagonBid(unsigned B) { Bid = B ? MAX / countPopulation(B) : 0; }
52 // Check if the insn priority is overflowed.
53 bool isSold() const { return (Bid >= MAX); }
55 HexagonBid &operator+=(const HexagonBid &B) {
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;
68 HexagonUnitAuction(unsigned cs = 0) : isSold(cs) {}
71 bool bid(unsigned B) {
72 // Exclude already auctioned slots from the bid.
73 unsigned b = B & ~isSold;
75 for (unsigned i = 0; i < HEXAGON_PACKET_SIZE; ++i)
77 // Request candidate slots.
78 Scores[i] += HexagonBid(b);
79 isSold |= Scores[i].isSold() << i;
83 // Error if the desired slots are already full.
88 } // end anonymous namespace
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;
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))
102 unsigned Ctpop = countPopulation(Units);
103 unsigned Cttz = countTrailingZeros(Units);
104 Weight = (1u << (SlotWeight * s)) * ((MaskWeight - Ctpop) << Cttz);
108 void HexagonCVIResource::SetupTUL(TypeUnitsAndLanes *TUL, StringRef CPU) {
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);
119 (*TUL)[HexagonII::TypeCVI_VINLANESAT] =
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);
134 (*TUL)[HexagonII::TypeCVI_SCATTER] =
135 UnitsAndLanes(CVI_XLANE | CVI_SHIFT | CVI_MPY0 | CVI_MPY1, 1);
136 (*TUL)[HexagonII::TypeCVI_SCATTER_DV] =
137 UnitsAndLanes(CVI_XLANE | CVI_MPY0, 2);
138 (*TUL)[HexagonII::TypeCVI_SCATTER_NEW_ST] =
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);
144 HexagonCVIResource::HexagonCVIResource(TypeUnitsAndLanes *TUL,
145 MCInstrInfo const &MCII, unsigned s,
147 : HexagonResource(s) {
148 unsigned T = HexagonMCInstrInfo::getType(MCII, *id);
153 setUnits((*TUL)[T].first);
154 setLanes((*TUL)[T].second);
155 setLoad(HexagonMCInstrInfo::getDesc(MCII, *id).mayLoad());
156 setStore(HexagonMCInstrInfo::getDesc(MCII, *id).mayStore());
171 using HVXInstsT = SmallVector<struct CVIUnits, 8>;
173 static unsigned makeAllBits(unsigned startBit, unsigned Lanes)
175 for (unsigned i = 1; i < Lanes; ++i)
176 startBit = (startBit << 1) | startBit;
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)
188 unsigned allBits = makeAllBits(b, hvxInsts[startIdx].Lanes);
189 if ((allBits & usedUnits) == 0) {
190 if (checkHVXPipes(hvxInsts, startIdx + 1, usedUnits | allBits))
199 HexagonShuffler::HexagonShuffler(MCContext &Context, bool ReportErrors,
200 MCInstrInfo const &MCII,
201 MCSubtargetInfo const &STI)
202 : Context(Context), MCII(MCII), STI(STI), ReportErrors(ReportErrors) {
204 HexagonCVIResource::SetupTUL(&TUL, STI.getCPU());
207 void HexagonShuffler::reset() {
212 void HexagonShuffler::append(MCInst const &ID, MCInst const *Extender,
214 HexagonInstr PI(&TUL, MCII, &ID, Extender, S);
216 Packet.push_back(PI);
222 } jumpSlots[] = {{8, 4}, {8, 2}, {8, 1}, {4, 2}, {4, 1}, {2, 1}};
223 #define MAX_JUMP_SLOTS (sizeof(jumpSlots) / sizeof(jumpSlots[0]))
225 void HexagonShuffler::restrictSlot1AOK() {
226 bool HasRestrictSlot1AOK = false;
228 for (iterator ISJ = begin(); ISJ != end(); ++ISJ) {
229 MCInst const &Inst = ISJ->getDesc();
230 if (HexagonMCInstrInfo::isRestrictSlot1AOK(MCII, Inst)) {
231 HasRestrictSlot1AOK = true;
232 RestrictLoc = Inst.getLoc();
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();
244 AppliedRestrictions.push_back(std::make_pair(
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);
256 void HexagonShuffler::restrictNoSlot1Store() {
257 bool HasRestrictNoSlot1Store = false;
259 for (iterator ISJ = begin(); ISJ != end(); ++ISJ) {
260 MCInst const &Inst = ISJ->getDesc();
261 if (HexagonMCInstrInfo::isRestrictNoSlot1Store(MCII, Inst)) {
262 HasRestrictNoSlot1Store = true;
263 RestrictLoc = Inst.getLoc();
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();
273 AppliedRestriction = true;
274 AppliedRestrictions.push_back(std::make_pair(
276 "Instruction was restricted from being in slot 1"));
277 ISJ->Core.setUnits(Units & ~2U);
281 if (AppliedRestriction)
282 AppliedRestrictions.push_back(std::make_pair(
283 RestrictLoc, "Instruction does not allow a store in slot 1"));
287 void HexagonShuffler::applySlotRestrictions() {
289 restrictNoSlot1Store();
292 /// Check that the packet is legal and enforce relative insn order.
293 bool HexagonShuffler::check() {
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
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
307 unsigned pSlot3Cnt = 0;
309 iterator slot3ISJ = end();
310 std::vector<iterator> foundBranches;
311 unsigned reservedSlots = 0;
313 // Collect information from the insns in the packet.
314 for (iterator ISJ = begin(); ISJ != end(); ++ISJ) {
315 MCInst const &ID = ISJ->getDesc();
317 if (HexagonMCInstrInfo::prefersSlot3(MCII, ID)) {
321 reservedSlots |= HexagonMCInstrInfo::getOtherReservedSlots(MCII, STI, ID);
323 switch (HexagonMCInstrInfo::getType(MCII, ID)) {
324 case HexagonII::TypeS_2op:
325 case HexagonII::TypeS_3op:
326 case HexagonII::TypeALU64:
328 case HexagonII::TypeJ:
329 foundBranches.push_back(ISJ);
331 case HexagonII::TypeCVI_VM_VP_LDU:
332 case HexagonII::TypeCVI_VM_LD:
333 case HexagonII::TypeCVI_VM_TMP_LD:
334 case HexagonII::TypeCVI_GATHER:
335 case HexagonII::TypeCVI_GATHER_RST:
338 case HexagonII::TypeCVI_ZW:
341 case HexagonII::TypeLD:
344 if (ISJ->Core.getUnits() == slotSingleLoad ||
345 HexagonMCInstrInfo::getType(MCII, ID) == HexagonII::TypeCVI_VM_VP_LDU)
347 if (HexagonMCInstrInfo::getDesc(MCII, ID).isReturn())
348 foundBranches.push_back(ISJ);
350 case HexagonII::TypeCVI_VM_STU:
351 case HexagonII::TypeCVI_VM_ST:
352 case HexagonII::TypeCVI_VM_NEW_ST:
353 case HexagonII::TypeCVI_SCATTER:
354 case HexagonII::TypeCVI_SCATTER_DV:
355 case HexagonII::TypeCVI_SCATTER_RST:
356 case HexagonII::TypeCVI_SCATTER_NEW_RST:
357 case HexagonII::TypeCVI_SCATTER_NEW_ST:
360 case HexagonII::TypeST:
363 if (ISJ->Core.getUnits() == slotSingleStore ||
364 HexagonMCInstrInfo::getType(MCII, ID) == HexagonII::TypeCVI_VM_STU)
367 case HexagonII::TypeV4LDST:
374 case HexagonII::TypeNCJ:
375 ++memory; // NV insns are memory-like.
376 foundBranches.push_back(ISJ);
378 case HexagonII::TypeV2LDST:
379 if (HexagonMCInstrInfo::getDesc(MCII, ID).mayLoad()) {
382 if (ISJ->Core.getUnits() == slotSingleLoad ||
383 HexagonMCInstrInfo::getType(MCII, ID) ==
384 HexagonII::TypeCVI_VM_VP_LDU)
387 assert(HexagonMCInstrInfo::getDesc(MCII, ID).mayStore());
392 case HexagonII::TypeCR:
393 // Legacy conditional branch predicated on a register.
394 case HexagonII::TypeCJ:
395 if (HexagonMCInstrInfo::getDesc(MCII, ID).isBranch())
396 foundBranches.push_back(ISJ);
398 case HexagonII::TypeDUPLEX: {
400 MCInst const &Inst0 = *ID.getOperand(0).getInst();
401 MCInst const &Inst1 = *ID.getOperand(1).getInst();
402 if (HexagonMCInstrInfo::getDesc(MCII, Inst0).isBranch())
403 foundBranches.push_back(ISJ);
404 if (HexagonMCInstrInfo::getDesc(MCII, Inst1).isBranch())
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);
414 applySlotRestrictions();
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"));
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();
432 if (!ISJ->Core.getUnits()) {
433 // Error if insn may not be executed in any slot.
437 // A single load must use slot #0.
438 if (HexagonMCInstrInfo::getDesc(MCII, ID).mayLoad()) {
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:
451 ISJ->Core.setUnits(ISJ->Core.getUnits() & slotSingleLoad);
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.
460 llvm::Twine("invalid instruction packet: too many loads"));
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.
470 // A single store must use slot #0.
471 if (HexagonMCInstrInfo::getDesc(MCII, ID).mayStore()) {
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"));
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.
488 if (store1 && stores > 1) {
489 // Error if a single store with another store.
490 reportError(Twine("invalid instruction packet: too many stores"));
495 // flag if an instruction requires to be in slot 3
496 if (ISJ->Core.getUnits() == slotThree)
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"));
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"));
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()))
520 // validate second jump with this slot rule
521 if (!(jumpSlots[i].second & foundBranches[1]->Core.getUnits()))
524 // both valid for this configuration, set new slot rules
526 foundBranches[0]->Core.setUnits(jumpSlots[i].first);
527 foundBranches[1]->Core.setUnits(jumpSlots[i].second);
529 HexagonUnitAuction AuctionCore(reservedSlots);
530 std::stable_sort(begin(), end(), HexagonInstr::lessCore);
532 // see if things ok with that instruction being pinned to slot "slotJump"
534 for (iterator I = begin(); I != end() && !bFail; ++I)
535 if (!AuctionCore.bid(I->Core.getUnits()))
538 // if yes, great, if not then restore original slot mask
540 validateSlots = false; // all good, no need to re-do auction
543 // restore original values
547 reportError(Twine("invalid instruction packet: out of slots"));
552 if (foundBranches.size() <= 1 && bOnlySlot3 == false && pSlot3Cnt == 1 &&
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);
560 HexagonUnitAuction AuctionCore(reservedSlots);
561 std::stable_sort(begin(), end(), HexagonInstr::lessCore);
563 // see if things ok with that instruction being pinned to slot #3
565 for (iterator I = begin(); I != end() && !bFail; ++I)
566 if (!AuctionCore.bid(I->Core.getUnits()))
569 // if yes, great, if not then restore original slot mask
571 validateSlots = false; // all good, no need to re-do auction
573 for (iterator ISJ = begin(); ISJ != end(); ++ISJ) {
574 MCInst const &ID = ISJ->getDesc();
575 if (HexagonMCInstrInfo::prefersSlot3(MCII, ID))
576 ISJ->Core.setUnits(saveUnits);
580 // Check if any slot, core or CVI, is over-subscribed.
581 // Verify the core slot subscriptions.
583 HexagonUnitAuction AuctionCore(reservedSlots);
585 std::stable_sort(begin(), end(), HexagonInstr::lessCore);
587 for (iterator I = begin(); I != end(); ++I)
588 if (!AuctionCore.bid(I->Core.getUnits())) {
589 reportError(Twine("invalid instruction packet: slot error"));
593 // Verify the CVI slot subscriptions.
594 std::stable_sort(begin(), end(), HexagonInstr::lessCVI);
595 // create vector of hvx instructions to check
598 for (iterator I = begin(); I != end(); ++I) {
599 struct CVIUnits inst;
600 inst.Units = I->CVI.getUnits();
601 inst.Lanes = I->CVI.getLanes();
603 continue; // not an hvx inst or an hvx inst that doesn't uses any pipes
604 hvxInsts.push_back(inst);
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"));
620 bool HexagonShuffler::shuffle() {
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"));
628 // Check and prepare packet.
630 if (size() > 1 && (Ok = check()))
631 // Reorder the handles for each slot.
632 for (unsigned nSlot = 0, emptySlots = 0; nSlot < HEXAGON_PACKET_SIZE;
635 unsigned slotSkip, slotWeight;
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.
644 // Calculate the weight of the slot.
645 slotWeight += ISK->Core.setWeight(HEXAGON_PACKET_SIZE - nSlot - 1);
648 // Sort the packet, favoring source order,
649 // beginning after the previous slot.
650 std::stable_sort(ISJ, Packet.end());
656 for (iterator ISJ = begin(); ISJ != end(); ++ISJ)
657 LLVM_DEBUG(dbgs().write_hex(ISJ->Core.getUnits()); if (ISJ->CVI.isValid()) {
659 dbgs().write_hex(ISJ->CVI.getUnits()) << '|';
660 dbgs() << ISJ->CVI.getLanes();
662 << HexagonMCInstrInfo::getDesc(MCII, ISJ->getDesc()).getOpcode();
664 LLVM_DEBUG(dbgs() << '\n');
669 void HexagonShuffler::reportError(Twine const &Msg) {
671 for (auto const &I : AppliedRestrictions) {
672 auto SM = Context.getSourceManager();
674 SM->PrintMessage(I.first, SourceMgr::DK_Note, I.second);
676 Context.reportError(Loc, Msg);