56#define DEBUG_TYPE "packets"
60 cl::desc(
"Disable Hexagon packetizer pass"));
64 cl::desc(
"Allow slot1 store and slot0 load"));
68 cl::desc(
"Allow non-solo packetization of volatile memory references"));
72 cl::desc(
"Generate all instruction with TC"));
76 cl::desc(
"Disable vector double new-value-stores"));
86 HexagonPacketizer(
bool Min =
false)
89 void getAnalysisUsage(AnalysisUsage &AU)
const override {
92 AU.
addRequired<MachineBranchProbabilityInfoWrapperPass>();
100 StringRef getPassName()
const override {
return "Hexagon Packetizer"; }
101 bool runOnMachineFunction(MachineFunction &Fn)
override;
103 MachineFunctionProperties getRequiredProperties()
const override {
104 return MachineFunctionProperties().setNoVRegs();
108 const HexagonInstrInfo *HII =
nullptr;
109 const HexagonRegisterInfo *HRI =
nullptr;
110 const bool Minimal =
false;
115char HexagonPacketizer::ID = 0;
118 "Hexagon Packetizer",
false,
false)
134 addMutation(std::make_unique<HexagonSubtarget::UsrOverflowMutation>());
135 addMutation(std::make_unique<HexagonSubtarget::HVXMemLatencyMutation>());
136 addMutation(std::make_unique<HexagonSubtarget::BankConflictMutation>());
143 for (
auto &MO : FirstI.
operands()) {
144 if (!MO.isReg() || !MO.isDef())
160 InsertPt = std::next(BundleIt).getInstrIterator();
166 if (
MI.isBundledWithSucc()) {
173 MI.unbundleFromPred();
175 B.splice(InsertPt, &
B,
MI.getIterator());
181 for (++
I;
I !=
E &&
I->isBundledWithPred(); ++
I)
194 BundleIt->eraseFromParent();
203 HII = HST.getInstrInfo();
204 HRI = HST.getRegisterInfo();
205 auto &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
206 auto *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
208 &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
211 HII->genAllInsnTimingClasses(MF);
216 HexagonPacketizerList
Packetizer(MF, MLI, AA, MBPI, MinOnly);
229 for (MachineBasicBlock &MB : MF) {
236 if (HST.isTinyCoreWithDuplex())
237 HII->translateInstrsForDup(MF,
true);
240 for (
auto &MB : MF) {
241 auto Begin = MB.begin(), End = MB.end();
242 while (Begin != End) {
246 while (RB != End && HII->isSchedulingBoundary(*RB, &MB, MF))
251 while (RE != End && !HII->isSchedulingBoundary(*RE, &MB, MF))
265 if (HST.isTinyCoreWithDuplex())
266 HII->translateInstrsForDup(MF,
false);
286 auto *ExtMI =
MF.CreateMachineInstr(HII->get(Hexagon::A4_ext),
DebugLoc());
288 if (Reserve && Avail)
290 MF.deleteMachineInstr(ExtMI);
297 if (DepReg == HRI->getRARegister())
300 if (HII->isDeallocRet(
MI))
301 if (DepReg == HRI->getFrameRegister() || DepReg == HRI->getStackRegister())
311 if (MO.isReg() && MO.getReg() == DepReg && !MO.isImplicit())
324 return MI.getOpcode() == Hexagon::J2_jump;
328 switch (
MI.getOpcode()) {
329 case Hexagon::Y2_barrier:
336 return MI.getDesc().isTerminator() ||
MI.getDesc().isCall();
343 for (
auto *CSR =
TRI->getCalleeSavedRegs(&MF); CSR && *CSR; ++CSR)
344 if (
MI.modifiesRegister(*CSR,
TRI))
355 if (NewRC == &Hexagon::PredRegsRegClass) {
356 if (HII->isHVXVec(
MI) &&
MI.mayStore())
358 return HII->isPredicated(
MI) && HII->getDotNewPredOp(
MI,
nullptr) > 0;
361 return HII->mayBeNewStore(
MI);
371 int CurOpcode = HII->getDotCurOp(
MI);
372 MI.setDesc(HII->get(CurOpcode));
380 if (HII->isDotCurInst(*BI)) {
385 for (
auto &MO : BI->operands())
386 if (MO.isReg() && MO.getReg() ==
MI->getOperand(0).getReg())
393 MI->setDesc(HII->get(HII->getNonDotCurOp(*
MI)));
401 if (!HII->isHVXVec(
MI))
403 if (!HII->isHVXVec(*MII))
407 if (HII->isDotCurInst(
MI) && !HII->mayBeCurLoad(
MI))
410 if (!HII->mayBeCurLoad(
MI))
419 dbgs() <<
"in packet\n";);
422 dbgs() <<
"Checking CUR against ";
426 bool FoundMatch =
false;
427 for (
auto &MO : MJ.operands())
428 if (MO.isReg() && MO.getReg() == DestReg)
437 if (BI->readsRegister(DepReg,
MF.getSubtarget().getRegisterInfo()))
454 if (RC == &Hexagon::PredRegsRegClass)
455 NewOpcode = HII->getDotNewPredOp(
MI,
MBPI);
457 NewOpcode = HII->getDotNewOp(
MI);
458 MI.setDesc(HII->get(NewOpcode));
463 int NewOpcode = HII->getDotOldOp(
MI);
464 MI.setDesc(HII->get(NewOpcode));
469 unsigned Opc =
MI.getOpcode();
471 case Hexagon::S2_storerd_io:
472 case Hexagon::S2_storeri_io:
473 case Hexagon::S2_storerh_io:
474 case Hexagon::S2_storerb_io:
479 unsigned FrameSize =
MF.getFrameInfo().getStackSize();
482 if (HII->isValidOffset(
Opc, NewOff, HRI)) {
490 unsigned Opc =
MI.getOpcode();
492 case Hexagon::S2_storerd_io:
493 case Hexagon::S2_storeri_io:
494 case Hexagon::S2_storerh_io:
495 case Hexagon::S2_storerb_io:
500 unsigned FrameSize =
MF.getFrameInfo().getStackSize();
513 if (!HII->getBaseAndOffsetPosition(
MI, BPI, OPI))
516 if (!HII->getBaseAndOffsetPosition(MJ, BPJ, OPJ))
524 for (
const auto &PI : SUI->
Preds)
526 (PI.getKind() !=
SDep::Data || PI.getReg() != Reg))
529 if (!HII->getIncrementValue(MJ, Incr))
532 int64_t
Offset =
MI.getOperand(OPI).getImm();
533 if (!HII->isValidOffset(
MI.getOpcode(),
Offset+Incr, HRI))
536 MI.getOperand(OPI).setImm(
Offset + Incr);
545 if (!HII->getBaseAndOffsetPosition(
MI, BP,
OP))
547 MI.getOperand(
OP).setImm(ChangedOffset);
575 for (
auto &MO :
MI.operands())
576 if (MO.isReg() && MO.isDef())
577 DefRegsSet.
insert(MO.getReg());
579 for (
auto &MO :
MI.operands())
580 if (MO.isReg() && MO.isUse() && DefRegsSet.
count(MO.getReg()))
586 assert(Op1.
isReg() &&
"Post increment operand has be to a register.");
589 if (
MI.getDesc().mayStore()) {
592 assert(Op0.
isReg() &&
"Post increment operand has be to a register.");
597 llvm_unreachable(
"mayLoad or mayStore not set for Post Increment operation");
603 return MI.getOperand(
MI.getNumOperands()-1);
607 unsigned Opc =
MI.getOpcode();
609 case Hexagon::L4_loadrd_ap:
610 case Hexagon::L4_loadrb_ap:
611 case Hexagon::L4_loadrh_ap:
612 case Hexagon::L4_loadrub_ap:
613 case Hexagon::L4_loadruh_ap:
614 case Hexagon::L4_loadri_ap:
622 return MI.getOperand(1);
645 if (!HII->mayBeNewStore(
MI))
658 if (PacketRC == &Hexagon::DoubleRegsRegClass)
671 if (HII->isPostIncrement(
MI) &&
676 if (HII->isPostIncrement(PacketMI) && PacketMI.
mayLoad() &&
691 if (HII->isPredicated(PacketMI)) {
692 if (!HII->isPredicated(
MI))
697 unsigned predRegNumSrc = 0;
698 unsigned predRegNumDst = 0;
702 for (
auto &MO : PacketMI.
operands()) {
705 predRegNumSrc = MO.getReg();
706 predRegClass = HRI->getMinimalPhysRegClass(predRegNumSrc);
707 if (predRegClass == &Hexagon::PredRegsRegClass)
710 assert((predRegClass == &Hexagon::PredRegsRegClass) &&
711 "predicate register not found in a predicated PacketMI instruction");
714 for (
auto &MO :
MI.operands()) {
717 predRegNumDst = MO.getReg();
718 predRegClass = HRI->getMinimalPhysRegClass(predRegNumDst);
719 if (predRegClass == &Hexagon::PredRegsRegClass)
722 assert((predRegClass == &Hexagon::PredRegsRegClass) &&
723 "predicate register not found in a predicated MI instruction");
733 if (predRegNumDst != predRegNumSrc ||
734 HII->isDotNewInst(PacketMI) != HII->isDotNewInst(
MI) ||
747 unsigned StartCheck = 0;
756 if (&TempMI != &PacketMI && !StartCheck)
760 if (&TempMI == &PacketMI)
763 for (
auto &MO :
MI.operands())
774 if (!HII->isPostIncrement(
MI)) {
775 for (
unsigned opNum = 0; opNum <
MI.getNumOperands()-1; opNum++) {
786 for (
auto &MO : PacketMI.
operands()) {
787 if (MO.isRegMask() && MO.clobbersPhysReg(DepReg))
789 if (!MO.isReg() || !MO.isDef() || !MO.isImplicit())
792 if (R == DepReg || HRI->isSuperRegister(DepReg, R))
801 for (
auto &MO :
MI.operands()) {
802 if (MO.isReg() && MO.isUse() && MO.isImplicit() && MO.getReg() == DepReg)
812 const SUnit *PacketSU,
unsigned DepReg,
814 if (!HII->mayBeNewStore(
MI))
829 for (
auto &MO :
I.operands()) {
830 if (CheckDef && MO.isRegMask() && MO.clobbersPhysReg(DepReg))
832 if (!MO.isReg() || MO.getReg() != DepReg || !MO.isImplicit())
834 if (CheckDef == MO.isDef())
845 if (HII->isDotNewInst(
MI) && !HII->mayBeNewStore(
MI))
874 if (RC == &Hexagon::PredRegsRegClass)
875 return HII->predCanBeUsedAsDotNew(PI, DepReg);
877 if (RC != &Hexagon::PredRegsRegClass && !HII->mayBeNewStore(
MI))
882 int NewOpcode = (RC != &Hexagon::PredRegsRegClass) ? HII->getDotNewOp(
MI) :
883 HII->getDotNewPredOp(
MI,
MBPI);
886 bool ResourcesAvailable =
ResourceTracker->canReserveResources(*NewMI);
887 MF.deleteMachineInstr(NewMI);
888 if (!ResourcesAvailable)
917 if (!HII->isPredicated(*
I))
926 if (PacketSU->
isSucc(PacketSUDep)) {
927 for (
unsigned i = 0; i < PacketSU->
Succs.size(); ++i) {
928 auto &Dep = PacketSU->
Succs[i];
929 if (Dep.getSUnit() == PacketSUDep && Dep.getKind() ==
SDep::Anti &&
930 Dep.getReg() == DepReg)
946 for (
auto &
Op :
MI.operands()) {
947 if (
Op.isReg() &&
Op.getReg() &&
Op.isUse() &&
948 Hexagon::PredRegsRegClass.contains(
Op.getReg()))
990 if (PacketSU->
isSucc(SU)) {
991 for (
unsigned i = 0; i < PacketSU->
Succs.size(); ++i) {
992 auto Dep = PacketSU->
Succs[i];
997 if (Dep.getSUnit() == SU && Dep.getKind() ==
SDep::Data &&
998 Hexagon::PredRegsRegClass.contains(Dep.getReg())) {
1017 return PReg1 == PReg2 &&
1018 Hexagon::PredRegsRegClass.contains(PReg1) &&
1019 Hexagon::PredRegsRegClass.contains(PReg2) &&
1021 HII->isDotNewInst(MI1) == HII->isDotNewInst(MI2);
1027 PromotedToDotNew =
false;
1028 GlueToNewValueJump =
false;
1029 GlueAllocframeStore =
false;
1030 FoundSequentialDependence =
false;
1037 if (
MI.isDebugInstr())
1040 if (
MI.isCFIInstruction())
1044 if (
MI.isInlineAsm())
1047 if (
MI.isImplicitDef())
1054 return !IS->getUnits();
1062 if (
MI.isEHLabel() ||
MI.isCFIInstruction())
1076 if (HII->isSolo(
MI))
1079 if (
MI.getOpcode() == Hexagon::PATCHABLE_FUNCTION_ENTER ||
1080 MI.getOpcode() == Hexagon::PATCHABLE_FUNCTION_EXIT ||
1081 MI.getOpcode() == Hexagon::PATCHABLE_TAIL_CALL)
1084 if (
MI.getOpcode() == Hexagon::A2_nop)
1113 if (
MI.isInlineAsm())
1121 switch (
MI.getOpcode()) {
1122 case Hexagon::S2_storew_locked:
1123 case Hexagon::S4_stored_locked:
1124 case Hexagon::L2_loadw_locked:
1125 case Hexagon::L4_loadd_locked:
1126 case Hexagon::Y2_dccleana:
1127 case Hexagon::Y2_dccleaninva:
1128 case Hexagon::Y2_dcinva:
1129 case Hexagon::Y2_dczeroa:
1130 case Hexagon::Y4_l2fetch:
1131 case Hexagon::Y5_l2fetch: {
1135 unsigned TJ = HII.
getType(MJ);
1158 for (
auto &
B :
MF) {
1162 BundleIt =
MI.getIterator();
1163 if (!
MI.isInsideBundle())
1172 bool InsertBeforeBundle;
1173 if (
MI.isInlineAsm())
1175 else if (
MI.isDebugInstr())
1176 InsertBeforeBundle =
true;
1187 unsigned Opc =
MI.getOpcode();
1189 case Hexagon::Y2_barrier:
1190 case Hexagon::Y2_dcfetchbo:
1191 case Hexagon::Y4_l2fetch:
1192 case Hexagon::Y5_l2fetch:
1205 if (HII->isPredicated(
I) || HII->isPredicated(J))
1208 BitVector DeadDefs(Hexagon::NUM_TARGET_REGS);
1209 for (
auto &MO :
I.operands()) {
1210 if (!MO.isReg() || !MO.isDef() || !MO.isDead())
1212 DeadDefs[MO.getReg()] =
true;
1216 if (!MO.isReg() || !MO.isDef() || !MO.isDead())
1219 if (R != Hexagon::USR_OVF && DeadDefs[R])
1229 if ((HII->isSaveCalleeSavedRegsCall(
I) &&
1231 (HII->isSaveCalleeSavedRegsCall(J) &&
1243 if (
MI.isCall() || HII->isDeallocRet(
MI) || HII->isNewValueJump(
MI))
1245 if (HII->isPredicated(
MI) && HII->isPredicatedNew(
MI) && HII->isJumpR(
MI))
1250 if (HII->isLoopN(
I) && isBadForLoopN(J))
1252 if (HII->isLoopN(J) && isBadForLoopN(
I))
1257 return HII->isDeallocRet(
I) &&
1275 if (!OpJ.isRegMask())
1277 assert((J.
isCall() || HII->isTailCall(J)) &&
"Regmask on a non-call");
1280 if (OpJ.clobbersPhysReg(OpI.getReg()))
1282 }
else if (OpI.isRegMask()) {
1294 bool StoreI =
I.mayStore(), StoreJ = J.
mayStore();
1295 if ((SysI && StoreJ) || (SysJ && StoreI))
1298 if (StoreI && StoreJ) {
1299 if (HII->isNewValueInst(J) || HII->isMemOp(J) || HII->isMemOp(
I))
1304 bool MopStI = HII->isMemOp(
I) || StoreI;
1305 bool MopStJ = HII->isMemOp(J) || StoreJ;
1306 if (MopStI && MopStJ)
1310 return (StoreJ && HII->isDeallocRet(
I)) || (StoreI && HII->isDeallocRet(J));
1323 IgnoreDepMIs.clear();
1355 if (NextMII !=
I.getParent()->end() && HII->isNewValueJump(*NextMII)) {
1358 bool secondRegMatch =
false;
1362 if (NOp1.
isReg() &&
I.getOperand(0).getReg() == NOp1.
getReg())
1363 secondRegMatch =
true;
1379 if (PI->getOpcode() == Hexagon::S2_allocframe || PI->mayStore() ||
1380 HII->isLoopN(*PI)) {
1386 if (OpR.
isReg() && PI->modifiesRegister(OpR.
getReg(), HRI)) {
1392 GlueToNewValueJump =
true;
1401 for (
unsigned i = 0; i < SUJ->
Succs.size(); ++i) {
1402 if (FoundSequentialDependence)
1405 if (SUJ->
Succs[i].getSUnit() != SUI)
1424 unsigned DepReg = 0;
1427 DepReg = SUJ->
Succs[i].getReg();
1428 RC = HRI->getMinimalPhysRegClass(DepReg);
1431 if (
I.isCall() || HII->isJumpR(
I) ||
I.isReturn() || HII->isTailCall(
I)) {
1445 if (DepType ==
SDep::Data && HII->isDotCurInst(J)) {
1446 if (HII->isHVXVec(
I))
1454 PromotedToDotNew =
true;
1456 FoundSequentialDependence =
true;
1460 if (HII->isNewValueJump(
I))
1466 if (HII->isPredicated(
I) && HII->isPredicated(J) &&
1480 auto Itr =
find(IgnoreDepMIs, &J);
1481 if (Itr != IgnoreDepMIs.end()) {
1485 IgnoreDepMIs.push_back(&
I);
1497 if (
I.isConditionalBranch() && DepType !=
SDep::Data &&
1502 FoundSequentialDependence =
true;
1516 FoundSequentialDependence =
true;
1522 bool LoadI =
I.mayLoad(), StoreI =
I.mayStore();
1523 bool NVStoreJ = HII->isNewValueStore(J);
1524 bool NVStoreI = HII->isNewValueStore(
I);
1525 bool IsVecJ = HII->isHVXVec(J);
1526 bool IsVecI = HII->isHVXVec(
I);
1530 if (LoadJ && LoadI && HII->isPureSlot0(J)) {
1531 FoundSequentialDependence =
true;
1536 ((LoadJ && StoreI && !NVStoreI) ||
1537 (StoreJ && LoadI && !NVStoreJ)) &&
1538 (J.
getOpcode() != Hexagon::S2_allocframe &&
1539 I.getOpcode() != Hexagon::S2_allocframe) &&
1540 (J.
getOpcode() != Hexagon::L2_deallocframe &&
1541 I.getOpcode() != Hexagon::L2_deallocframe) &&
1542 (!HII->isMemOp(J) && !HII->isMemOp(
I)) && (!IsVecJ && !IsVecI))
1545 if (StoreJ && LoadI &&
alias(J,
I)) {
1546 FoundSequentialDependence =
true;
1551 if (!LoadJ || (!LoadI && !StoreI)) {
1554 FoundSequentialDependence =
true;
1569 unsigned Opc =
I.getOpcode();
1571 case Hexagon::S2_storerd_io:
1572 case Hexagon::S2_storeri_io:
1573 case Hexagon::S2_storerh_io:
1574 case Hexagon::S2_storerb_io:
1575 if (
I.getOperand(0).getReg() == HRI->getStackRegister()) {
1581 if (GlueAllocframeStore)
1601 if (
Op.isReg() &&
Op.isDef()) {
1605 }
else if (!
Op.isRegMask()) {
1609 FoundSequentialDependence =
true;
1621 FoundSequentialDependence =
true;
1626 if (FoundSequentialDependence) {
1641 if (Coexist && !Dependence)
1646 if (PromotedToDotNew)
1653 if (GlueAllocframeStore) {
1655 GlueAllocframeStore =
false;
1661 if (GlueToNewValueJump) {
1664 GlueToNewValueJump =
false;
1672 FoundSequentialDependence =
false;
1682 bool FoundLoad =
false;
1683 bool FoundStore =
false;
1686 unsigned Opc = MJ->getOpcode();
1687 if (
Opc == Hexagon::S2_allocframe ||
Opc == Hexagon::L2_deallocframe)
1689 if (HII->isMemOp(*MJ))
1693 if (MJ->mayStore() && !HII->isNewValueStore(*MJ))
1696 return FoundLoad && FoundStore;
1706 PacketStalls =
false;
1707 PacketStallCycles = 0;
1710 PacketStallCycles = std::max(PacketStallCycles,
calcStall(
MI));
1712 if (
MI.isImplicitDef()) {
1720 bool ExtMI = HII->isExtended(
MI) || HII->isConstExtended(
MI);
1723 if (GlueToNewValueJump) {
1733 bool ExtNvjMI = HII->isExtended(NvjMI) || HII->isConstExtended(NvjMI);
1740 if (Good && ExtNvjMI)
1766 if (PromotedToDotNew)
1768 if (GlueAllocframeStore) {
1770 GlueAllocframeStore =
false;
1785 dbgs() <<
"Finalizing packet:\n";
1801 OldPacketMIs.clear();
1804 for (
auto &
I :
make_range(HII->expandVGatherPseudo(*
MI), NextMI))
1805 OldPacketMIs.push_back(&
I);
1809 if (OldPacketMIs.size() > 1) {
1813 auto BundleMII = std::prev(FirstMI);
1814 if (memShufDisabled)
1815 HII->setBundleNoShuf(BundleMII);
1820 PacketHasDuplex =
false;
1821 PacketHasSLOT0OnlyInsn =
false;
1847 PacketHasSLOT0OnlyInsn |= HII->isPureSlot0(*MJ);
1849 int Opcode = HII->getDuplexOpcode(
MI,
false);
1853 if (HII->isDuplexPair(
MI, *MJ) && !PacketHasSLOT0OnlyInsn) {
1854 PacketHasDuplex =
true;
1861 MIRef.
setDesc(HII->get(Opcode));
1878 if (!OldPacketMIs.empty()) {
1879 auto *OldBB = OldPacketMIs.front()->getParent();
1880 auto *ThisBB =
I.getParent();
1881 if (
MLI->getLoopFor(OldBB) !=
MLI->getLoopFor(ThisBB))
1912 for (
auto &Pred : SUI->
Preds)
1913 if (Pred.getSUnit() == SUJ)
1914 if ((Pred.getLatency() == 0 && Pred.isAssignedRegDep()) ||
1915 HII->isNewValueJump(
I) || HII->isToBeScheduledASAP(*J,
I))
1921 for (
auto *J : OldPacketMIs) {
1923 for (
auto &Pred : SUI->
Preds)
1924 if (Pred.getSUnit() == SUJ && Pred.getLatency() > 1)
1925 return Pred.getLatency();
1937 return Latency > PacketStallCycles;
1946 return new HexagonPacketizer(Minimal);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements the BitVector class.
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file defines the DenseSet and SmallDenseSet classes.
cl::opt< bool > ScheduleInlineAsm("hexagon-sched-inline-asm", cl::Hidden, cl::init(false), cl::desc("Do not consider inline-asm a scheduling/" "packetization boundary."))
#define HEXAGON_LRFP_SIZE
static bool cannotCoexistAsymm(const MachineInstr &MI, const MachineInstr &MJ, const HexagonInstrInfo &HII)
static bool isDirectJump(const MachineInstr &MI)
static MachineBasicBlock::iterator moveInstrOut(MachineInstr &MI, MachineBasicBlock::iterator BundleIt, bool Before)
static bool isRegDependence(const SDep::Kind DepType)
static const MachineOperand & getStoreValueOperand(const MachineInstr &MI)
static cl::opt< bool > EnableGenAllInsnClass("enable-gen-insn", cl::Hidden, cl::desc("Generate all instruction with TC"))
static bool isControlFlow(const MachineInstr &MI)
static cl::opt< bool > DisableVecDblNVStores("disable-vecdbl-nv-stores", cl::Hidden, cl::desc("Disable vector double new-value-stores"))
static PredicateKind getPredicateSense(const MachineInstr &MI, const HexagonInstrInfo *HII)
Returns true if an instruction is predicated on p0 and false if it's predicated on !...
static unsigned getPredicatedRegister(MachineInstr &MI, const HexagonInstrInfo *QII)
Gets the predicate register of a predicated instruction.
static cl::opt< bool > DisablePacketizer("disable-packetizer", cl::Hidden, cl::desc("Disable Hexagon packetizer pass"))
static cl::opt< bool > Slot1Store("slot1-store-slot0-load", cl::Hidden, cl::init(true), cl::desc("Allow slot1 store and slot0 load"))
static cl::opt< bool > PacketizeVolatiles("hexagon-packetize-volatiles", cl::Hidden, cl::init(true), cl::desc("Allow non-solo packetization of volatile memory references"))
static bool hasWriteToReadDep(const MachineInstr &FirstI, const MachineInstr &SecondI, const TargetRegisterInfo *TRI)
static bool doesModifyCalleeSavedReg(const MachineInstr &MI, const TargetRegisterInfo *TRI)
Returns true if the instruction modifies a callee-saved register.
static bool isLoadAbsSet(const MachineInstr &MI)
static const MachineOperand & getAbsSetOperand(const MachineInstr &MI)
static const MachineOperand & getPostIncrementOperand(const MachineInstr &MI, const HexagonInstrInfo *HII)
static bool isImplicitDependency(const MachineInstr &I, bool CheckDef, unsigned DepReg)
static bool isSchedBarrier(const MachineInstr &MI)
static bool isSystemInstr(const MachineInstr &MI)
Register const TargetRegisterInfo * TRI
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
uint64_t IntrinsicInst * II
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Implements a dense probed hash-table based set.
FunctionPass class - This class is used to implement most global optimizations.
bool isPredicated(const MachineInstr &MI) const override
Returns true if the instruction is already predicated.
bool isHVXMemWithAIndirect(const MachineInstr &I, const MachineInstr &J) const
bool isRestrictNoSlot1Store(const MachineInstr &MI) const
bool isPureSlot0(const MachineInstr &MI) const
bool isPostIncrement(const MachineInstr &MI) const override
Return true for post-incremented instructions.
uint64_t getType(const MachineInstr &MI) const
bool isPredicatedTrue(const MachineInstr &MI) const
bool isNewValueStore(const MachineInstr &MI) const
bool arePredicatesComplements(MachineInstr &MI1, MachineInstr &MI2)
bool updateOffset(SUnit *SUI, SUnit *SUJ)
Return true if we can update the offset in MI so that MI and MJ can be packetized together.
void endPacket(MachineBasicBlock *MBB, MachineBasicBlock::iterator MI) override
bool getmemShufDisabled()
HexagonPacketizerList(MachineFunction &MF, MachineLoopInfo &MLI, AAResults *AA, const MachineBranchProbabilityInfo *MBPI, bool Minimal)
bool isCallDependent(const MachineInstr &MI, SDep::Kind DepType, unsigned DepReg)
bool promoteToDotCur(MachineInstr &MI, SDep::Kind DepType, MachineBasicBlock::iterator &MII, const TargetRegisterClass *RC)
bool promoteToDotNew(MachineInstr &MI, SDep::Kind DepType, MachineBasicBlock::iterator &MII, const TargetRegisterClass *RC)
bool isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) override
bool canPromoteToDotCur(const MachineInstr &MI, const SUnit *PacketSU, unsigned DepReg, MachineBasicBlock::iterator &MII, const TargetRegisterClass *RC)
void useCalleesSP(MachineInstr &MI)
bool demoteToDotOld(MachineInstr &MI)
bool cannotCoexist(const MachineInstr &MI, const MachineInstr &MJ)
const MachineLoopInfo * MLI
bool isSoloInstruction(const MachineInstr &MI) override
bool isLegalToPruneDependencies(SUnit *SUI, SUnit *SUJ) override
void initPacketizerState() override
bool hasControlDependence(const MachineInstr &I, const MachineInstr &J)
bool restrictingDepExistInPacket(MachineInstr &, unsigned)
bool producesStall(const MachineInstr &MI)
void undoChangedOffset(MachineInstr &MI)
Undo the changed offset.
bool hasDualStoreDependence(const MachineInstr &I, const MachineInstr &J)
unsigned int calcStall(const MachineInstr &MI)
bool canPromoteToDotNew(const MachineInstr &MI, const SUnit *PacketSU, unsigned DepReg, MachineBasicBlock::iterator &MII, const TargetRegisterClass *RC)
bool canPromoteToNewValue(const MachineInstr &MI, const SUnit *PacketSU, unsigned DepReg, MachineBasicBlock::iterator &MII)
bool ignorePseudoInstruction(const MachineInstr &MI, const MachineBasicBlock *MBB) override
void unpacketizeSoloInstrs(MachineFunction &MF)
const MachineBranchProbabilityInfo * MBPI
A handle to the branch probability pass.
bool shouldAddToPacket(const MachineInstr &MI) override
bool canReserveResourcesForConstExt()
bool useCallersSP(MachineInstr &MI)
bool canPromoteToNewValueStore(const MachineInstr &MI, const MachineInstr &PacketMI, unsigned DepReg)
bool tryAllocateResourcesForConstExt(bool Reserve)
void setmemShufDisabled(bool val)
void reserveResourcesForConstExt()
MachineBasicBlock::iterator addToPacket(MachineInstr &MI) override
bool hasDeadDependence(const MachineInstr &I, const MachineInstr &J)
bool isNewifiable(const MachineInstr &MI, const TargetRegisterClass *NewRC)
bool hasRegMaskDependence(const MachineInstr &I, const MachineInstr &J)
const HexagonInstrInfo * getInstrInfo() const override
const HexagonRegisterInfo * getRegisterInfo() const override
bool hasV60OpsOnly() const
Describe properties that are true of each instruction in the target description file.
unsigned getSchedClass() const
Return the scheduling class for this instruction.
Instructions::iterator instr_iterator
Instructions::const_iterator const_instr_iterator
MachineInstrBundleIterator< MachineInstr > iterator
Analysis pass which computes a MachineDominatorTree.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineFunctionProperties & getProperties() const
Get the function properties.
instr_iterator getInstrIterator() const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool isTerminator(QueryType Type=AnyInBundle) const
Returns true if this instruction part of the terminator for a basic block.
bool isImplicitDef() const
bool readsRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr reads the specified register.
bool isBarrier(QueryType Type=AnyInBundle) const
Returns true if the specified instruction stops control flow from executing the instruction immediate...
bool isCall(QueryType Type=AnyInBundle) const
bool isBranch(QueryType Type=AnyInBundle) const
Returns true if this is a conditional, unconditional, or indirect branch.
bool modifiesRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr modifies (fully define or partially define) the specified register.
LLVM_ABI void unbundleFromPred()
Break bundle above this instruction.
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
LLVM_ABI void setDesc(const MCInstrDesc &TID)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one.
LLVM_ABI bool hasOrderedMemoryRef() const
Return true if this instruction may have an ordered or volatile memory reference, or if the informati...
bool mayStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly modify memory.
bool isBundledWithSucc() const
Return true if this instruction is part of a bundle, and it is not the last instruction in the bundle...
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Register getReg() const
getReg - Returns the register number.
Wrapper class representing virtual and physical registers.
Kind
These are the different kinds of scheduling dependencies.
@ Output
A register output-dependence (aka WAW).
@ Order
Any other ordering dependency.
@ Anti
A register anti-dependence (aka WAR).
@ Data
Regular data dependence (aka true-dependence).
Scheduling unit. This is a node in the scheduling DAG.
bool isSucc(const SUnit *N) const
Tests if node N is a successor of this node.
SmallVector< SDep, 4 > Succs
All sunit successors.
SmallVector< SDep, 4 > Preds
All sunit predecessors.
MachineInstr * getInstr() const
Returns the representative MachineInstr for this SUnit.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
VLIWPacketizerList(MachineFunction &MF, MachineLoopInfo &MLI, AAResults *AA)
void addMutation(std::unique_ptr< ScheduleDAGMutation > Mutation)
bool alias(const MachineInstr &MI1, const MachineInstr &MI2, bool UseTBAA=true) const
std::vector< MachineInstr * > CurrentPacketMIs
std::map< MachineInstr *, SUnit * > MIToSUnit
DFAPacketizer * ResourceTracker
std::pair< iterator, bool > insert(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI void finalizeBundle(MachineBasicBlock &MBB, MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
finalizeBundle - Finalize a machine instruction bundle which includes a sequence of instructions star...
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
std::string utohexstr(uint64_t X, bool LowerCase=false, unsigned Width=0)
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
FunctionPass * createHexagonPacketizer(bool Minimal)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
DWARFExpression::Operation Op