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 #include "MCTargetDesc/HexagonShuffler.h"
15 #include "MCTargetDesc/HexagonBaseInfo.h"
16 #include "MCTargetDesc/HexagonMCInstrInfo.h"
17 #include "MCTargetDesc/HexagonMCTargetDesc.h"
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"
23 #include "llvm/MC/MCSubtargetInfo.h"
24 #include "llvm/Support/Compiler.h"
25 #include "llvm/Support/Debug.h"
26 #include "llvm/Support/MathExtras.h"
27 #include "llvm/Support/SourceMgr.h"
28 #include "llvm/Support/raw_ostream.h"
34 #define DEBUG_TYPE "hexagon-shuffle"
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 HexagonCVIResource::HexagonCVIResource(MCInstrInfo
const &MCII
,
109 MCSubtargetInfo
const &STI
,
112 : HexagonResource(s
) {
114 const unsigned ItinUnits
= HexagonMCInstrInfo::getCVIResources(MCII
, STI
, *id
);
116 const unsigned Units
= HexagonConvertUnits(ItinUnits
, &Lanes
);
118 if (Units
== 0 && Lanes
== 0) {
130 setLoad(HexagonMCInstrInfo::getDesc(MCII
, *id
).mayLoad());
131 setStore(HexagonMCInstrInfo::getDesc(MCII
, *id
).mayStore());
139 using HVXInstsT
= SmallVector
<struct CVIUnits
, 8>;
141 static unsigned makeAllBits(unsigned startBit
, unsigned Lanes
)
143 for (unsigned i
= 1; i
< Lanes
; ++i
)
144 startBit
= (startBit
<< 1) | startBit
;
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)
156 unsigned allBits
= makeAllBits(b
, hvxInsts
[startIdx
].Lanes
);
157 if ((allBits
& usedUnits
) == 0) {
158 if (checkHVXPipes(hvxInsts
, startIdx
+ 1, usedUnits
| allBits
))
167 HexagonShuffler::HexagonShuffler(MCContext
&Context
, bool ReportErrors
,
168 MCInstrInfo
const &MCII
,
169 MCSubtargetInfo
const &STI
)
170 : Context(Context
), MCII(MCII
), STI(STI
), ReportErrors(ReportErrors
) {
174 void HexagonShuffler::reset() {
177 CheckFailure
= false;
180 void HexagonShuffler::append(MCInst
const &ID
, MCInst
const *Extender
,
182 HexagonInstr
PI(MCII
, STI
, &ID
, Extender
, S
);
184 Packet
.push_back(PI
);
188 static const unsigned Slot0Mask
= 1 << 0;
189 static const unsigned Slot1Mask
= 1 << 1;
190 static const unsigned Slot3Mask
= 1 << 3;
191 static const unsigned slotSingleLoad
= Slot0Mask
;
192 static const unsigned slotSingleStore
= Slot0Mask
;
194 void HexagonShuffler::restrictSlot1AOK(HexagonPacketSummary
const &Summary
) {
195 if (Summary
.Slot1AOKLoc
)
196 for (HexagonInstr
&ISJ
: insts()) {
197 MCInst
const &Inst
= ISJ
.getDesc();
198 const unsigned Type
= HexagonMCInstrInfo::getType(MCII
, Inst
);
199 if (Type
!= HexagonII::TypeALU32_2op
&&
200 Type
!= HexagonII::TypeALU32_3op
&&
201 Type
!= HexagonII::TypeALU32_ADDI
) {
202 const unsigned Units
= ISJ
.Core
.getUnits();
204 if (Units
& Slot1Mask
) {
205 AppliedRestrictions
.push_back(std::make_pair(
207 "Instruction was restricted from being in slot 1"));
208 AppliedRestrictions
.push_back(std::make_pair(
209 *Summary
.Slot1AOKLoc
, "Instruction can only be combined "
210 "with an ALU instruction in slot 1"));
211 ISJ
.Core
.setUnits(Units
& ~Slot1Mask
);
217 void HexagonShuffler::restrictNoSlot1Store(
218 HexagonPacketSummary
const &Summary
) {
219 // If this packet contains an instruction that bars slot-1 stores,
220 // we should mask off slot 1 from all of the store instructions in
223 if (!Summary
.NoSlot1StoreLoc
)
226 bool AppliedRestriction
= false;
228 for (HexagonInstr
&ISJ
: insts()) {
229 MCInst
const &Inst
= ISJ
.getDesc();
230 if (HexagonMCInstrInfo::getDesc(MCII
, Inst
).mayStore()) {
231 unsigned Units
= ISJ
.Core
.getUnits();
232 if (Units
& Slot1Mask
) {
233 AppliedRestriction
= true;
234 AppliedRestrictions
.push_back(std::make_pair(
235 Inst
.getLoc(), "Instruction was restricted from being in slot 1"));
236 ISJ
.Core
.setUnits(Units
& ~Slot1Mask
);
241 if (AppliedRestriction
)
242 AppliedRestrictions
.push_back(
243 std::make_pair(*Summary
.NoSlot1StoreLoc
,
244 "Instruction does not allow a store in slot 1"));
247 bool HexagonShuffler::applySlotRestrictions(
248 HexagonPacketSummary
const &Summary
) {
249 // These restrictions can modify the slot masks in the instructions
250 // in the Packet member. They should run unconditionally and their
251 // order does not matter.
252 restrictSlot1AOK(Summary
);
253 restrictNoSlot1Store(Summary
);
257 // These restrictions can modify the slot masks in the instructions
258 // in the Packet member, but they can also detect constraint failures
261 restrictStoreLoadOrder(Summary
);
263 restrictBranchOrder(Summary
);
265 restrictPreferSlot3(Summary
);
266 return !CheckFailure
;
269 void HexagonShuffler::restrictBranchOrder(HexagonPacketSummary
const &Summary
) {
270 // preserve branch order
271 const bool HasMultipleBranches
= Summary
.branchInsts
.size() > 1;
272 if (!HasMultipleBranches
)
275 if (Summary
.branchInsts
.size() > 2) {
276 reportError(Twine("too many branches in packet"));
280 const static std::pair
<unsigned, unsigned> jumpSlots
[] = {
281 {8, 4}, {8, 2}, {8, 1}, {4, 2}, {4, 1}, {2, 1}};
282 // try all possible choices
283 for (std::pair
<unsigned, unsigned> jumpSlot
: jumpSlots
) {
284 // validate first jump with this slot rule
285 if (!(jumpSlot
.first
& Summary
.branchInsts
[0]->Core
.getUnits()))
288 // validate second jump with this slot rule
289 if (!(jumpSlot
.second
& Summary
.branchInsts
[1]->Core
.getUnits()))
292 // both valid for this configuration, set new slot rules
293 const HexagonPacket PacketSave
= Packet
;
294 Summary
.branchInsts
[0]->Core
.setUnits(jumpSlot
.first
);
295 Summary
.branchInsts
[1]->Core
.setUnits(jumpSlot
.second
);
297 const bool HasShuffledPacket
= tryAuction(Summary
).hasValue();
298 if (HasShuffledPacket
)
301 // if yes, great, if not then restore original slot mask
302 // restore original values
306 reportError("invalid instruction packet: out of slots");
310 void HexagonShuffler::permitNonSlot() {
311 for (HexagonInstr
&ISJ
: insts()) {
312 const bool RequiresSlot
= HexagonMCInstrInfo::requiresSlot(STI
, *ISJ
.ID
);
314 ISJ
.Core
.setAllUnits();
318 bool HexagonShuffler::ValidResourceUsage(HexagonPacketSummary
const &Summary
) {
319 Optional
<HexagonPacket
> ShuffledPacket
= tryAuction(Summary
);
321 if (!ShuffledPacket
) {
322 reportError("invalid instruction packet: slot error");
325 Packet
= *ShuffledPacket
;
328 // Verify the CVI slot subscriptions.
329 llvm::stable_sort(*this, HexagonInstr::lessCVI
);
330 // create vector of hvx instructions to check
333 for (const_iterator I
= cbegin(); I
!= cend(); ++I
) {
334 struct CVIUnits inst
;
335 inst
.Units
= I
->CVI
.getUnits();
336 inst
.Lanes
= I
->CVI
.getLanes();
338 continue; // not an hvx inst or an hvx inst that doesn't uses any pipes
339 hvxInsts
.push_back(inst
);
342 // if there are any hvx instructions in this packet, check pipe usage
343 if (hvxInsts
.size() > 0) {
344 unsigned startIdx
, usedUnits
;
345 startIdx
= usedUnits
= 0x0;
346 if (!checkHVXPipes(hvxInsts
, startIdx
, usedUnits
)) {
347 // too many pipes used to be valid
348 reportError(Twine("invalid instruction packet: slot error"));
355 bool HexagonShuffler::restrictStoreLoadOrder(
356 HexagonPacketSummary
const &Summary
) {
357 // Modify packet accordingly.
358 // TODO: need to reserve slots #0 and #1 for duplex insns.
359 static const unsigned slotFirstLoadStore
= Slot1Mask
;
360 static const unsigned slotLastLoadStore
= Slot0Mask
;
361 unsigned slotLoadStore
= slotFirstLoadStore
;
363 for (iterator ISJ
= begin(); ISJ
!= end(); ++ISJ
) {
364 MCInst
const &ID
= ISJ
->getDesc();
366 if (!ISJ
->Core
.getUnits())
367 // Error if insn may not be executed in any slot.
370 // A single load must use slot #0.
371 if (HexagonMCInstrInfo::getDesc(MCII
, ID
).mayLoad()) {
372 if (Summary
.loads
== 1 && Summary
.loads
== Summary
.memory
&&
374 // Pin the load to slot #0.
375 switch (ID
.getOpcode()) {
376 case Hexagon::V6_vgathermw
:
377 case Hexagon::V6_vgathermh
:
378 case Hexagon::V6_vgathermhw
:
379 case Hexagon::V6_vgathermwq
:
380 case Hexagon::V6_vgathermhq
:
381 case Hexagon::V6_vgathermhwq
:
385 ISJ
->Core
.setUnits(ISJ
->Core
.getUnits() & slotSingleLoad
);
388 else if (Summary
.loads
>= 1 && isMemReorderDisabled()) { // }:mem_noshuf
389 // Loads must keep the original order ONLY if
390 // isMemReorderDisabled() == true
391 if (slotLoadStore
< slotLastLoadStore
) {
392 // Error if no more slots available for loads.
393 reportError("invalid instruction packet: too many loads");
396 // Pin the load to the highest slot available to it.
397 ISJ
->Core
.setUnits(ISJ
->Core
.getUnits() & slotLoadStore
);
398 // Update the next highest slot available to loads.
403 // A single store must use slot #0.
404 if (HexagonMCInstrInfo::getDesc(MCII
, ID
).mayStore()) {
405 if (!Summary
.store0
) {
406 const bool PacketHasNoOnlySlot0
=
407 llvm::none_of(insts(), [&](HexagonInstr
const &I
) {
408 return I
.Core
.getUnits() == Slot0Mask
&&
409 I
.ID
->getOpcode() != ID
.getOpcode();
411 const bool SafeToMoveToSlot0
=
412 (Summary
.loads
== 0) ||
413 (!isMemReorderDisabled() && PacketHasNoOnlySlot0
);
415 if (Summary
.stores
== 1 && SafeToMoveToSlot0
)
416 // Pin the store to slot #0 only if isMemReorderDisabled() == false
417 ISJ
->Core
.setUnits(ISJ
->Core
.getUnits() & slotSingleStore
);
418 else if (Summary
.stores
>= 1) {
419 if (slotLoadStore
< slotLastLoadStore
) {
420 // Error if no more slots available for stores.
421 reportError("invalid instruction packet: too many stores");
424 // Pin the store to the highest slot available to it.
425 ISJ
->Core
.setUnits(ISJ
->Core
.getUnits() & slotLoadStore
);
426 // Update the next highest slot available to stores.
430 if (Summary
.store1
&& Summary
.stores
> 1) {
431 // Error if a single store with another store.
432 reportError("invalid instruction packet: too many stores");
441 HexagonShuffler::HexagonPacketSummary
HexagonShuffler::GetPacketSummary() {
442 HexagonPacketSummary Summary
= HexagonPacketSummary();
444 // Collect information from the insns in the packet.
445 for (iterator ISJ
= begin(); ISJ
!= end(); ++ISJ
) {
446 MCInst
const &ID
= ISJ
->getDesc();
448 if (HexagonMCInstrInfo::isRestrictSlot1AOK(MCII
, ID
))
449 Summary
.Slot1AOKLoc
= ID
.getLoc();
450 if (HexagonMCInstrInfo::isRestrictNoSlot1Store(MCII
, ID
))
451 Summary
.NoSlot1StoreLoc
= ID
.getLoc();
453 if (HexagonMCInstrInfo::prefersSlot3(MCII
, ID
)) {
455 Summary
.PrefSlot3Inst
= ISJ
;
457 Summary
.ReservedSlotMask
|=
458 HexagonMCInstrInfo::getOtherReservedSlots(MCII
, STI
, ID
);
460 switch (HexagonMCInstrInfo::getType(MCII
, ID
)) {
461 case HexagonII::TypeS_2op
:
462 case HexagonII::TypeS_3op
:
463 case HexagonII::TypeALU64
:
465 case HexagonII::TypeJ
:
466 Summary
.branchInsts
.push_back(ISJ
);
468 case HexagonII::TypeCVI_VM_VP_LDU
:
469 case HexagonII::TypeCVI_VM_LD
:
470 case HexagonII::TypeCVI_VM_TMP_LD
:
471 case HexagonII::TypeCVI_GATHER
:
472 case HexagonII::TypeCVI_GATHER_DV
:
473 case HexagonII::TypeCVI_GATHER_RST
:
474 ++Summary
.NonZCVIloads
;
476 case HexagonII::TypeCVI_ZW
:
477 ++Summary
.AllCVIloads
;
479 case HexagonII::TypeLD
:
482 if (ISJ
->Core
.getUnits() == slotSingleLoad
||
483 HexagonMCInstrInfo::getType(MCII
, ID
) == HexagonII::TypeCVI_VM_VP_LDU
)
485 if (HexagonMCInstrInfo::getDesc(MCII
, ID
).isReturn())
486 Summary
.branchInsts
.push_back(ISJ
);
488 case HexagonII::TypeCVI_VM_STU
:
489 case HexagonII::TypeCVI_VM_ST
:
490 case HexagonII::TypeCVI_VM_NEW_ST
:
491 case HexagonII::TypeCVI_SCATTER
:
492 case HexagonII::TypeCVI_SCATTER_DV
:
493 case HexagonII::TypeCVI_SCATTER_RST
:
494 case HexagonII::TypeCVI_SCATTER_NEW_RST
:
495 case HexagonII::TypeCVI_SCATTER_NEW_ST
:
498 case HexagonII::TypeST
:
501 if (ISJ
->Core
.getUnits() == slotSingleStore
||
502 HexagonMCInstrInfo::getType(MCII
, ID
) == HexagonII::TypeCVI_VM_STU
)
505 case HexagonII::TypeV4LDST
:
512 case HexagonII::TypeNCJ
:
513 ++Summary
.memory
; // NV insns are memory-like.
514 Summary
.branchInsts
.push_back(ISJ
);
516 case HexagonII::TypeV2LDST
:
517 if (HexagonMCInstrInfo::getDesc(MCII
, ID
).mayLoad()) {
520 if (ISJ
->Core
.getUnits() == slotSingleLoad
||
521 HexagonMCInstrInfo::getType(MCII
, ID
) ==
522 HexagonII::TypeCVI_VM_VP_LDU
)
525 assert(HexagonMCInstrInfo::getDesc(MCII
, ID
).mayStore());
530 case HexagonII::TypeCR
:
531 // Legacy conditional branch predicated on a register.
532 case HexagonII::TypeCJ
:
533 if (HexagonMCInstrInfo::getDesc(MCII
, ID
).isBranch())
534 Summary
.branchInsts
.push_back(ISJ
);
536 case HexagonII::TypeDUPLEX
: {
538 MCInst
const &Inst0
= *ID
.getOperand(0).getInst();
539 MCInst
const &Inst1
= *ID
.getOperand(1).getInst();
540 if (HexagonMCInstrInfo::getDesc(MCII
, Inst0
).isBranch())
541 Summary
.branchInsts
.push_back(ISJ
);
542 if (HexagonMCInstrInfo::getDesc(MCII
, Inst1
).isBranch())
543 Summary
.branchInsts
.push_back(ISJ
);
544 if (HexagonMCInstrInfo::getDesc(MCII
, Inst0
).isReturn())
545 Summary
.branchInsts
.push_back(ISJ
);
546 if (HexagonMCInstrInfo::getDesc(MCII
, Inst1
).isReturn())
547 Summary
.branchInsts
.push_back(ISJ
);
555 bool HexagonShuffler::ValidPacketMemoryOps(
556 HexagonPacketSummary
const &Summary
) const {
557 // Check if the packet is legal.
558 const unsigned ZCVIloads
= Summary
.AllCVIloads
- Summary
.NonZCVIloads
;
559 const bool ValidHVXMem
=
560 Summary
.NonZCVIloads
<= 1 && ZCVIloads
<= 1 && Summary
.CVIstores
<= 1;
561 const bool InvalidPacket
=
562 ((Summary
.load0
> 1 || Summary
.store0
> 1 || !ValidHVXMem
) ||
563 (Summary
.duplex
> 1 || (Summary
.duplex
&& Summary
.memory
)));
565 return !InvalidPacket
;
568 void HexagonShuffler::restrictPreferSlot3(HexagonPacketSummary
const &Summary
) {
569 // flag if an instruction requires to be in slot 3
570 const bool HasOnlySlot3
= llvm::any_of(insts(), [&](HexagonInstr
const &I
) {
571 return (I
.Core
.getUnits() == Slot3Mask
);
573 const bool NeedsPrefSlot3Shuffle
=
574 (Summary
.branchInsts
.size() <= 1 && !HasOnlySlot3
&&
575 Summary
.pSlot3Cnt
== 1 && Summary
.PrefSlot3Inst
);
577 if (!NeedsPrefSlot3Shuffle
)
580 HexagonInstr
*PrefSlot3Inst
= *Summary
.PrefSlot3Inst
;
581 // save off slot mask of instruction marked with A_PREFER_SLOT3
582 // and then pin it to slot #3
583 const unsigned saveUnits
= PrefSlot3Inst
->Core
.getUnits();
584 PrefSlot3Inst
->Core
.setUnits(saveUnits
& Slot3Mask
);
585 const bool HasShuffledPacket
= tryAuction(Summary
).hasValue();
586 if (HasShuffledPacket
)
589 PrefSlot3Inst
->Core
.setUnits(saveUnits
);
592 /// Check that the packet is legal and enforce relative insn order.
593 bool HexagonShuffler::check() {
594 const HexagonPacketSummary Summary
= GetPacketSummary();
595 if (!applySlotRestrictions(Summary
))
598 if (!ValidPacketMemoryOps(Summary
)) {
599 reportError("invalid instruction packet");
603 ValidResourceUsage(Summary
);
605 return !CheckFailure
;
608 llvm::Optional
<HexagonShuffler::HexagonPacket
>
609 HexagonShuffler::tryAuction(HexagonPacketSummary
const &Summary
) const {
610 HexagonPacket PacketResult
= Packet
;
611 HexagonUnitAuction
AuctionCore(Summary
.ReservedSlotMask
);
612 llvm::stable_sort(PacketResult
, HexagonInstr::lessCore
);
614 const bool ValidSlots
=
615 llvm::all_of(insts(PacketResult
), [&AuctionCore
](HexagonInstr
const &I
) {
616 return AuctionCore
.bid(I
.Core
.getUnits());
620 dbgs() << "Shuffle attempt: " << (ValidSlots
? "passed" : "failed")
622 for (HexagonInstr
const &ISJ
: insts(PacketResult
))
623 dbgs() << "\t" << HexagonMCInstrInfo::getName(MCII
, *ISJ
.ID
) << ": "
624 << llvm::format_hex(ISJ
.Core
.getUnits(), 4, true) << "\n";
627 Optional
<HexagonPacket
> Res
;
634 bool HexagonShuffler::shuffle() {
635 if (size() > HEXAGON_PACKET_SIZE
) {
636 // Ignore a packet with with more than what a packet can hold
637 // or with compound or duplex insns for now.
638 reportError(Twine("invalid instruction packet"));
642 // Check and prepare packet.
644 if (size() > 1 && (Ok
= check()))
645 // Reorder the handles for each slot.
646 for (unsigned nSlot
= 0, emptySlots
= 0; nSlot
< HEXAGON_PACKET_SIZE
;
649 unsigned slotSkip
, slotWeight
;
651 // Prioritize the handles considering their restrictions.
652 for (ISJ
= ISK
= Packet
.begin(), slotSkip
= slotWeight
= 0;
653 ISK
!= Packet
.end(); ++ISK
, ++slotSkip
)
654 if (slotSkip
< nSlot
- emptySlots
)
655 // Note which handle to begin at.
658 // Calculate the weight of the slot.
659 slotWeight
+= ISK
->Core
.setWeight(HEXAGON_PACKET_SIZE
- nSlot
- 1);
662 // Sort the packet, favoring source order,
663 // beginning after the previous slot.
664 std::stable_sort(ISJ
, Packet
.end());
671 for (HexagonInstr
const &ISJ
: insts()) {
672 dbgs().write_hex(ISJ
.Core
.getUnits());
673 if (ISJ
.CVI
.isValid()) {
675 dbgs().write_hex(ISJ
.CVI
.getUnits()) << '|';
676 dbgs() << ISJ
.CVI
.getLanes();
679 << HexagonMCInstrInfo::getDesc(MCII
, ISJ
.getDesc()).getOpcode()
687 void HexagonShuffler::reportError(Twine
const &Msg
) {
690 for (auto const &I
: AppliedRestrictions
) {
691 auto SM
= Context
.getSourceManager();
693 SM
->PrintMessage(I
.first
, SourceMgr::DK_Note
, I
.second
);
695 Context
.reportError(Loc
, Msg
);