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"));
93 HexagonPacketizer(
bool Min =
false)
112 MachineFunctionProperties::Property::NoVRegs);
118 const bool Minimal =
false;
123char HexagonPacketizer::ID = 0;
126 "Hexagon Packetizer",
false,
false)
142 addMutation(std::make_unique<HexagonSubtarget::UsrOverflowMutation>());
143 addMutation(std::make_unique<HexagonSubtarget::HVXMemLatencyMutation>());
144 addMutation(std::make_unique<HexagonSubtarget::BankConflictMutation>());
151 for (
auto &MO : FirstI.
operands()) {
152 if (!MO.isReg() || !MO.isDef())
168 InsertPt = std::next(BundleIt).getInstrIterator();
174 if (
MI.isBundledWithSucc()) {
181 MI.unbundleFromPred();
183 B.splice(InsertPt, &
B,
MI.getIterator());
189 for (++
I;
I !=
E &&
I->isBundledWithPred(); ++
I)
202 BundleIt->eraseFromParent();
209 MachineFunctionProperties::Property::FailsVerification);
213 HRI = HST.getRegisterInfo();
214 auto &MLI = getAnalysis<MachineLoopInfo>();
215 auto *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
216 auto *MBPI = &getAnalysis<MachineBranchProbabilityInfo>();
219 HII->genAllInsnTimingClasses(MF);
244 if (HST.isTinyCoreWithDuplex())
245 HII->translateInstrsForDup(MF,
true);
248 for (
auto &MB : MF) {
249 auto Begin = MB.begin(),
End = MB.end();
250 while (Begin !=
End) {
254 while (RB !=
End && HII->isSchedulingBoundary(*RB, &MB, MF))
259 while (RE !=
End && !HII->isSchedulingBoundary(*RE, &MB, MF))
273 if (HST.isTinyCoreWithDuplex())
274 HII->translateInstrsForDup(MF,
false);
296 if (Reserve && Avail)
305 if (DepReg == HRI->getRARegister())
308 if (HII->isDeallocRet(
MI))
319 if (MO.isReg() && MO.getReg() == DepReg && !MO.isImplicit())
332 return MI.getOpcode() == Hexagon::J2_jump;
336 switch (
MI.getOpcode()) {
337 case Hexagon::Y2_barrier:
344 return MI.getDesc().isTerminator() ||
MI.getDesc().isCall();
351 for (
auto *CSR =
TRI->getCalleeSavedRegs(&MF); CSR && *CSR; ++CSR)
352 if (
MI.modifiesRegister(*CSR,
TRI))
363 if (NewRC == &Hexagon::PredRegsRegClass) {
364 if (HII->isHVXVec(
MI) &&
MI.mayStore())
366 return HII->isPredicated(
MI) && HII->getDotNewPredOp(
MI,
nullptr) > 0;
369 return HII->mayBeNewStore(
MI);
379 int CurOpcode = HII->getDotCurOp(
MI);
380 MI.setDesc(HII->get(CurOpcode));
388 if (HII->isDotCurInst(*BI)) {
393 for (
auto &MO : BI->operands())
394 if (MO.isReg() && MO.getReg() ==
MI->getOperand(0).getReg())
401 MI->setDesc(HII->get(HII->getNonDotCurOp(*
MI)));
409 if (!HII->isHVXVec(
MI))
411 if (!HII->isHVXVec(*MII))
415 if (HII->isDotCurInst(
MI) && !HII->mayBeCurLoad(
MI))
418 if (!HII->mayBeCurLoad(
MI))
427 dbgs() <<
"in packet\n";);
430 dbgs() <<
"Checking CUR against ";
434 bool FoundMatch =
false;
435 for (
auto &MO : MJ.operands())
436 if (MO.isReg() && MO.getReg() == DestReg)
462 if (RC == &Hexagon::PredRegsRegClass)
463 NewOpcode = HII->getDotNewPredOp(
MI,
MBPI);
465 NewOpcode = HII->getDotNewOp(
MI);
466 MI.setDesc(HII->get(NewOpcode));
471 int NewOpcode = HII->getDotOldOp(
MI);
472 MI.setDesc(HII->get(NewOpcode));
477 unsigned Opc =
MI.getOpcode();
479 case Hexagon::S2_storerd_io:
480 case Hexagon::S2_storeri_io:
481 case Hexagon::S2_storerh_io:
482 case Hexagon::S2_storerb_io:
490 if (HII->isValidOffset(Opc, NewOff, HRI)) {
498 unsigned Opc =
MI.getOpcode();
500 case Hexagon::S2_storerd_io:
501 case Hexagon::S2_storeri_io:
502 case Hexagon::S2_storerh_io:
503 case Hexagon::S2_storerb_io:
521 if (!HII->getBaseAndOffsetPosition(
MI, BPI, OPI))
524 if (!HII->getBaseAndOffsetPosition(MJ, BPJ, OPJ))
532 for (
const auto &PI : SUI->
Preds)
534 (PI.getKind() !=
SDep::Data || PI.getReg() != Reg))
537 if (!HII->getIncrementValue(MJ, Incr))
540 int64_t
Offset =
MI.getOperand(OPI).getImm();
541 if (!HII->isValidOffset(
MI.getOpcode(),
Offset+Incr, HRI))
544 MI.getOperand(OPI).setImm(
Offset + Incr);
553 if (!HII->getBaseAndOffsetPosition(
MI, BP,
OP))
555 MI.getOperand(
OP).setImm(ChangedOffset);
583 for (
auto &MO :
MI.operands())
584 if (MO.isReg() && MO.isDef())
585 DefRegsSet.
insert(MO.getReg());
587 for (
auto &MO :
MI.operands())
588 if (MO.isReg() && MO.isUse() && DefRegsSet.
count(MO.getReg()))
594 assert(Op1.
isReg() &&
"Post increment operand has be to a register.");
597 if (
MI.getDesc().mayStore()) {
600 assert(Op0.
isReg() &&
"Post increment operand has be to a register.");
605 llvm_unreachable(
"mayLoad or mayStore not set for Post Increment operation");
611 return MI.getOperand(
MI.getNumOperands()-1);
615 unsigned Opc =
MI.getOpcode();
617 case Hexagon::L4_loadrd_ap:
618 case Hexagon::L4_loadrb_ap:
619 case Hexagon::L4_loadrh_ap:
620 case Hexagon::L4_loadrub_ap:
621 case Hexagon::L4_loadruh_ap:
622 case Hexagon::L4_loadri_ap:
630 return MI.getOperand(1);
653 if (!HII->mayBeNewStore(
MI))
666 if (PacketRC == &Hexagon::DoubleRegsRegClass)
679 if (HII->isPostIncrement(
MI) &&
684 if (HII->isPostIncrement(PacketMI) && PacketMI.
mayLoad() &&
699 if (HII->isPredicated(PacketMI)) {
700 if (!HII->isPredicated(
MI))
705 unsigned predRegNumSrc = 0;
706 unsigned predRegNumDst = 0;
710 for (
auto &MO : PacketMI.
operands()) {
713 predRegNumSrc = MO.getReg();
714 predRegClass = HRI->getMinimalPhysRegClass(predRegNumSrc);
715 if (predRegClass == &Hexagon::PredRegsRegClass)
718 assert((predRegClass == &Hexagon::PredRegsRegClass) &&
719 "predicate register not found in a predicated PacketMI instruction");
722 for (
auto &MO :
MI.operands()) {
725 predRegNumDst = MO.getReg();
726 predRegClass = HRI->getMinimalPhysRegClass(predRegNumDst);
727 if (predRegClass == &Hexagon::PredRegsRegClass)
730 assert((predRegClass == &Hexagon::PredRegsRegClass) &&
731 "predicate register not found in a predicated MI instruction");
741 if (predRegNumDst != predRegNumSrc ||
742 HII->isDotNewInst(PacketMI) != HII->isDotNewInst(
MI) ||
755 unsigned StartCheck = 0;
764 if (&TempMI != &PacketMI && !StartCheck)
768 if (&TempMI == &PacketMI)
771 for (
auto &MO :
MI.operands())
782 if (!HII->isPostIncrement(
MI)) {
783 for (
unsigned opNum = 0; opNum <
MI.getNumOperands()-1; opNum++) {
794 for (
auto &MO : PacketMI.
operands()) {
795 if (MO.isRegMask() && MO.clobbersPhysReg(DepReg))
797 if (!MO.isReg() || !MO.isDef() || !MO.isImplicit())
800 if (R == DepReg || HRI->isSuperRegister(DepReg, R))
809 for (
auto &MO :
MI.operands()) {
810 if (MO.isReg() && MO.isUse() && MO.isImplicit() && MO.getReg() == DepReg)
820 const SUnit *PacketSU,
unsigned DepReg,
822 if (!HII->mayBeNewStore(
MI))
837 for (
auto &MO :
I.operands()) {
838 if (CheckDef && MO.isRegMask() && MO.clobbersPhysReg(DepReg))
840 if (!MO.isReg() || MO.getReg() != DepReg || !MO.isImplicit())
842 if (CheckDef == MO.isDef())
853 if (HII->isDotNewInst(
MI) && !HII->mayBeNewStore(
MI))
882 if (RC == &Hexagon::PredRegsRegClass)
883 return HII->predCanBeUsedAsDotNew(PI, DepReg);
885 if (RC != &Hexagon::PredRegsRegClass && !HII->mayBeNewStore(
MI))
890 int NewOpcode = (RC != &Hexagon::PredRegsRegClass) ? HII->getDotNewOp(
MI) :
891 HII->getDotNewPredOp(
MI,
MBPI);
896 if (!ResourcesAvailable)
925 if (!HII->isPredicated(*
I))
934 if (PacketSU->
isSucc(PacketSUDep)) {
935 for (
unsigned i = 0; i < PacketSU->
Succs.size(); ++i) {
936 auto &Dep = PacketSU->
Succs[i];
937 if (Dep.getSUnit() == PacketSUDep && Dep.getKind() ==
SDep::Anti &&
938 Dep.getReg() == DepReg)
954 for (
auto &
Op :
MI.operands()) {
955 if (
Op.isReg() &&
Op.getReg() &&
Op.isUse() &&
956 Hexagon::PredRegsRegClass.contains(
Op.getReg()))
998 if (PacketSU->
isSucc(SU)) {
999 for (
unsigned i = 0; i < PacketSU->
Succs.size(); ++i) {
1000 auto Dep = PacketSU->
Succs[i];
1005 if (Dep.getSUnit() == SU && Dep.getKind() ==
SDep::Data &&
1006 Hexagon::PredRegsRegClass.contains(Dep.getReg())) {
1025 return PReg1 == PReg2 &&
1026 Hexagon::PredRegsRegClass.contains(PReg1) &&
1027 Hexagon::PredRegsRegClass.contains(PReg2) &&
1029 HII->isDotNewInst(MI1) == HII->isDotNewInst(MI2);
1035 PromotedToDotNew =
false;
1036 GlueToNewValueJump =
false;
1037 GlueAllocframeStore =
false;
1038 FoundSequentialDependence =
false;
1045 if (
MI.isDebugInstr())
1048 if (
MI.isCFIInstruction())
1052 if (
MI.isInlineAsm())
1055 if (
MI.isImplicitDef())
1070 if (
MI.isEHLabel() ||
MI.isCFIInstruction())
1084 if (HII->isSolo(
MI))
1087 if (
MI.getOpcode() == Hexagon::PATCHABLE_FUNCTION_ENTER ||
1088 MI.getOpcode() == Hexagon::PATCHABLE_FUNCTION_EXIT ||
1089 MI.getOpcode() == Hexagon::PATCHABLE_TAIL_CALL)
1092 if (
MI.getOpcode() == Hexagon::A2_nop)
1121 if (
MI.isInlineAsm())
1129 switch (
MI.getOpcode()) {
1130 case Hexagon::S2_storew_locked:
1131 case Hexagon::S4_stored_locked:
1132 case Hexagon::L2_loadw_locked:
1133 case Hexagon::L4_loadd_locked:
1134 case Hexagon::Y2_dccleana:
1135 case Hexagon::Y2_dccleaninva:
1136 case Hexagon::Y2_dcinva:
1137 case Hexagon::Y2_dczeroa:
1138 case Hexagon::Y4_l2fetch:
1139 case Hexagon::Y5_l2fetch: {
1143 unsigned TJ = HII.
getType(MJ);
1166 for (
auto &
B :
MF) {
1170 BundleIt =
MI.getIterator();
1171 if (!
MI.isInsideBundle())
1180 bool InsertBeforeBundle;
1181 if (
MI.isInlineAsm())
1183 else if (
MI.isDebugValue())
1184 InsertBeforeBundle =
true;
1195 unsigned Opc =
MI.getOpcode();
1197 case Hexagon::Y2_barrier:
1198 case Hexagon::Y2_dcfetchbo:
1199 case Hexagon::Y4_l2fetch:
1200 case Hexagon::Y5_l2fetch:
1213 if (HII->isPredicated(
I) || HII->isPredicated(J))
1216 BitVector DeadDefs(Hexagon::NUM_TARGET_REGS);
1217 for (
auto &MO :
I.operands()) {
1218 if (!MO.isReg() || !MO.isDef() || !MO.isDead())
1220 DeadDefs[MO.getReg()] =
true;
1224 if (!MO.isReg() || !MO.isDef() || !MO.isDead())
1227 if (R != Hexagon::USR_OVF && DeadDefs[R])
1237 if ((HII->isSaveCalleeSavedRegsCall(
I) &&
1239 (HII->isSaveCalleeSavedRegsCall(J) &&
1251 if (
MI.isCall() || HII->isDeallocRet(
MI) || HII->isNewValueJump(
MI))
1253 if (HII->isPredicated(
MI) && HII->isPredicatedNew(
MI) && HII->isJumpR(
MI))
1258 if (HII->isLoopN(
I) && isBadForLoopN(J))
1260 if (HII->isLoopN(J) && isBadForLoopN(
I))
1265 return HII->isDeallocRet(
I) &&
1283 if (!OpJ.isRegMask())
1285 assert((J.
isCall() || HII->isTailCall(J)) &&
"Regmask on a non-call");
1288 if (OpJ.clobbersPhysReg(OpI.getReg()))
1290 }
else if (OpI.isRegMask()) {
1302 bool StoreI =
I.mayStore(), StoreJ = J.
mayStore();
1303 if ((SysI && StoreJ) || (SysJ && StoreI))
1306 if (StoreI && StoreJ) {
1307 if (HII->isNewValueInst(J) || HII->isMemOp(J) || HII->isMemOp(
I))
1312 bool MopStI = HII->isMemOp(
I) || StoreI;
1313 bool MopStJ = HII->isMemOp(J) || StoreJ;
1314 if (MopStI && MopStJ)
1318 return (StoreJ && HII->isDeallocRet(
I)) || (StoreI && HII->isDeallocRet(J));
1331 IgnoreDepMIs.clear();
1363 if (NextMII !=
I.getParent()->end() && HII->isNewValueJump(*NextMII)) {
1366 bool secondRegMatch =
false;
1370 if (NOp1.
isReg() &&
I.getOperand(0).getReg() == NOp1.
getReg())
1371 secondRegMatch =
true;
1387 if (PI->getOpcode() == Hexagon::S2_allocframe || PI->mayStore() ||
1388 HII->isLoopN(*PI)) {
1394 if (OpR.
isReg() && PI->modifiesRegister(OpR.
getReg(), HRI)) {
1400 GlueToNewValueJump =
true;
1409 for (
unsigned i = 0; i < SUJ->
Succs.size(); ++i) {
1410 if (FoundSequentialDependence)
1413 if (SUJ->
Succs[i].getSUnit() != SUI)
1432 unsigned DepReg = 0;
1435 DepReg = SUJ->
Succs[i].getReg();
1436 RC = HRI->getMinimalPhysRegClass(DepReg);
1439 if (
I.isCall() || HII->isJumpR(
I) ||
I.isReturn() || HII->isTailCall(
I)) {
1453 if (DepType ==
SDep::Data && HII->isDotCurInst(J)) {
1454 if (HII->isHVXVec(
I))
1462 PromotedToDotNew =
true;
1464 FoundSequentialDependence =
true;
1468 if (HII->isNewValueJump(
I))
1474 if (HII->isPredicated(
I) && HII->isPredicated(J) &&
1488 auto Itr =
find(IgnoreDepMIs, &J);
1489 if (Itr != IgnoreDepMIs.end()) {
1493 IgnoreDepMIs.push_back(&
I);
1505 if (
I.isConditionalBranch() && DepType !=
SDep::Data &&
1510 FoundSequentialDependence =
true;
1524 FoundSequentialDependence =
true;
1530 bool LoadI =
I.mayLoad(), StoreI =
I.mayStore();
1531 bool NVStoreJ = HII->isNewValueStore(J);
1532 bool NVStoreI = HII->isNewValueStore(
I);
1533 bool IsVecJ = HII->isHVXVec(J);
1534 bool IsVecI = HII->isHVXVec(
I);
1538 if (LoadJ && LoadI && HII->isPureSlot0(J)) {
1539 FoundSequentialDependence =
true;
1544 ((LoadJ && StoreI && !NVStoreI) ||
1545 (StoreJ && LoadI && !NVStoreJ)) &&
1546 (J.
getOpcode() != Hexagon::S2_allocframe &&
1547 I.getOpcode() != Hexagon::S2_allocframe) &&
1548 (J.
getOpcode() != Hexagon::L2_deallocframe &&
1549 I.getOpcode() != Hexagon::L2_deallocframe) &&
1550 (!HII->isMemOp(J) && !HII->isMemOp(
I)) && (!IsVecJ && !IsVecI))
1553 if (StoreJ && LoadI &&
alias(J,
I)) {
1554 FoundSequentialDependence =
true;
1559 if (!LoadJ || (!LoadI && !StoreI)) {
1562 FoundSequentialDependence =
true;
1577 unsigned Opc =
I.getOpcode();
1579 case Hexagon::S2_storerd_io:
1580 case Hexagon::S2_storeri_io:
1581 case Hexagon::S2_storerh_io:
1582 case Hexagon::S2_storerb_io:
1589 if (GlueAllocframeStore)
1609 if (
Op.isReg() &&
Op.isDef()) {
1613 }
else if (!
Op.isRegMask()) {
1617 FoundSequentialDependence =
true;
1629 FoundSequentialDependence =
true;
1634 if (FoundSequentialDependence) {
1654 if (PromotedToDotNew)
1661 if (GlueAllocframeStore) {
1663 GlueAllocframeStore =
false;
1669 if (GlueToNewValueJump) {
1672 GlueToNewValueJump =
false;
1680 FoundSequentialDependence =
false;
1690 bool FoundLoad =
false;
1691 bool FoundStore =
false;
1694 unsigned Opc = MJ->getOpcode();
1695 if (Opc == Hexagon::S2_allocframe || Opc == Hexagon::L2_deallocframe)
1697 if (HII->isMemOp(*MJ))
1701 if (MJ->mayStore() && !HII->isNewValueStore(*MJ))
1704 return FoundLoad && FoundStore;
1714 PacketStalls =
false;
1715 PacketStallCycles = 0;
1718 PacketStallCycles = std::max(PacketStallCycles,
calcStall(
MI));
1720 if (
MI.isImplicitDef()) {
1728 bool ExtMI = HII->isExtended(
MI) || HII->isConstExtended(
MI);
1731 if (GlueToNewValueJump) {
1741 bool ExtNvjMI = HII->isExtended(NvjMI) || HII->isConstExtended(NvjMI);
1748 if (Good && ExtNvjMI)
1774 if (PromotedToDotNew)
1776 if (GlueAllocframeStore) {
1778 GlueAllocframeStore =
false;
1793 dbgs() <<
"Finalizing packet:\n";
1795 for (MachineInstr *MI : CurrentPacketMIs) {
1796 unsigned R = ResourceTracker->getUsedResources(Idx++);
1797 dbgs() <<
" * [res:0x" << utohexstr(R) <<
"] " << *MI;
1802 bool memShufDisabled = getmemShufDisabled();
1803 if (memShufDisabled && !foundLSInPacket()) {
1804 setmemShufDisabled(
false);
1807 memShufDisabled = getmemShufDisabled();
1809 OldPacketMIs.clear();
1812 for (
auto &
I :
make_range(HII->expandVGatherPseudo(*
MI), NextMI))
1813 OldPacketMIs.push_back(&
I);
1815 CurrentPacketMIs.clear();
1817 if (OldPacketMIs.size() > 1) {
1821 auto BundleMII = std::prev(FirstMI);
1822 if (memShufDisabled)
1823 HII->setBundleNoShuf(BundleMII);
1825 setmemShufDisabled(
false);
1828 PacketHasDuplex =
false;
1829 PacketHasSLOT0OnlyInsn =
false;
1830 ResourceTracker->clearResources();
1855 PacketHasSLOT0OnlyInsn |= HII->isPureSlot0(*MJ);
1857 int Opcode = HII->getDuplexOpcode(
MI,
false);
1861 if (HII->isDuplexPair(
MI, *MJ) && !PacketHasSLOT0OnlyInsn) {
1862 PacketHasDuplex =
true;
1886 if (!OldPacketMIs.empty()) {
1887 auto *OldBB = OldPacketMIs.front()->getParent();
1888 auto *ThisBB =
I.getParent();
1920 for (
auto &Pred : SUI->
Preds)
1921 if (Pred.getSUnit() == SUJ)
1922 if ((Pred.getLatency() == 0 && Pred.isAssignedRegDep()) ||
1923 HII->isNewValueJump(
I) || HII->isToBeScheduledASAP(*J,
I))
1929 for (
auto *J : OldPacketMIs) {
1931 for (
auto &Pred : SUI->
Preds)
1932 if (Pred.getSUnit() == SUJ && Pred.getLatency() > 1)
1933 return Pred.getLatency();
1945 return Latency > PacketStallCycles;
1954 return new HexagonPacketizer(Minimal);
This file implements the BitVector class.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-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)
hexagon Hexagon Packetizer
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"))
cl::opt< bool > ScheduleInlineAsm
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)
unsigned const TargetRegisterInfo * TRI
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static constexpr uint32_t Opcode
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
const InstrItineraryData * getInstrItins() const
bool canReserveResources(const MCInstrDesc *MID)
void reserveResources(const MCInstrDesc *MID)
This class represents an Operation in the Expression.
Implements a dense probed hash-table based set.
Dependence - This class represents a dependence between two memory memory references in a function.
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 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)
Register getStackRegister() const
Register getFrameRegister(const MachineFunction &MF) const override
const HexagonInstrInfo * getInstrInfo() const override
bool hasV60OpsOnly() const
const InstrStage * beginStage(unsigned ItinClassIndx) const
Return the first stage of the itinerary.
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
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
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.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
virtual MachineFunctionProperties getRequiredProperties() const
Properties which a MachineFunction may have at a given point in time.
MachineFunctionProperties & set(Property P)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineInstr * CreateMachineInstr(const MCInstrDesc &MCID, DebugLoc DL, bool NoImplicit=false)
CreateMachineInstr - Allocate a new MachineInstr.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
void deleteMachineInstr(MachineInstr *MI)
DeleteMachineInstr - Delete the given MachineInstr.
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 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 modifiesRegister(Register Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr modifies (fully define or partially define) the specified register.
bool isBranch(QueryType Type=AnyInBundle) const
Returns true if this is a conditional, unconditional, or indirect branch.
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.
void setDesc(const MCInstrDesc &TID)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one.
iterator_range< mop_iterator > operands()
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 readsRegister(Register Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr reads the specified register.
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
MachineLoop * getLoopFor(const MachineBasicBlock *BB) const
Return the innermost loop that BB lives in.
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.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
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.
StringRef - Represent a constant reference to a string, i.e.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
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.
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.
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...
void initializeHexagonPacketizerPass(PassRegistry &)
FunctionPass * createHexagonPacketizer(bool Minimal)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FuncUnits getUnits() const
Returns the choice of FUs.