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
);