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<MachineLoopInfoWrapperPass>().getLI();
215 auto *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
217 &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
220 HII->genAllInsnTimingClasses(MF);
245 if (HST.isTinyCoreWithDuplex())
246 HII->translateInstrsForDup(MF,
true);
249 for (
auto &MB : MF) {
250 auto Begin = MB.begin(),
End = MB.end();
251 while (Begin !=
End) {
255 while (RB !=
End && HII->isSchedulingBoundary(*RB, &MB, MF))
260 while (RE !=
End && !HII->isSchedulingBoundary(*RE, &MB, MF))
274 if (HST.isTinyCoreWithDuplex())
275 HII->translateInstrsForDup(MF,
false);
297 if (Reserve && Avail)
306 if (DepReg == HRI->getRARegister())
309 if (HII->isDeallocRet(
MI))
320 if (MO.isReg() && MO.getReg() == DepReg && !MO.isImplicit())
333 return MI.getOpcode() == Hexagon::J2_jump;
337 switch (
MI.getOpcode()) {
338 case Hexagon::Y2_barrier:
345 return MI.getDesc().isTerminator() ||
MI.getDesc().isCall();
352 for (
auto *CSR =
TRI->getCalleeSavedRegs(&MF); CSR && *CSR; ++CSR)
353 if (
MI.modifiesRegister(*CSR,
TRI))
364 if (NewRC == &Hexagon::PredRegsRegClass) {
365 if (HII->isHVXVec(
MI) &&
MI.mayStore())
367 return HII->isPredicated(
MI) && HII->getDotNewPredOp(
MI,
nullptr) > 0;
370 return HII->mayBeNewStore(
MI);
380 int CurOpcode = HII->getDotCurOp(
MI);
381 MI.setDesc(HII->get(CurOpcode));
389 if (HII->isDotCurInst(*BI)) {
394 for (
auto &MO : BI->operands())
395 if (MO.isReg() && MO.getReg() ==
MI->getOperand(0).getReg())
402 MI->setDesc(HII->get(HII->getNonDotCurOp(*
MI)));
410 if (!HII->isHVXVec(
MI))
412 if (!HII->isHVXVec(*MII))
416 if (HII->isDotCurInst(
MI) && !HII->mayBeCurLoad(
MI))
419 if (!HII->mayBeCurLoad(
MI))
428 dbgs() <<
"in packet\n";);
431 dbgs() <<
"Checking CUR against ";
435 bool FoundMatch =
false;
436 for (
auto &MO : MJ.operands())
437 if (MO.isReg() && MO.getReg() == DestReg)
463 if (RC == &Hexagon::PredRegsRegClass)
464 NewOpcode = HII->getDotNewPredOp(
MI,
MBPI);
466 NewOpcode = HII->getDotNewOp(
MI);
467 MI.setDesc(HII->get(NewOpcode));
472 int NewOpcode = HII->getDotOldOp(
MI);
473 MI.setDesc(HII->get(NewOpcode));
478 unsigned Opc =
MI.getOpcode();
480 case Hexagon::S2_storerd_io:
481 case Hexagon::S2_storeri_io:
482 case Hexagon::S2_storerh_io:
483 case Hexagon::S2_storerb_io:
491 if (HII->isValidOffset(Opc, NewOff, HRI)) {
499 unsigned Opc =
MI.getOpcode();
501 case Hexagon::S2_storerd_io:
502 case Hexagon::S2_storeri_io:
503 case Hexagon::S2_storerh_io:
504 case Hexagon::S2_storerb_io:
522 if (!HII->getBaseAndOffsetPosition(
MI, BPI, OPI))
525 if (!HII->getBaseAndOffsetPosition(MJ, BPJ, OPJ))
533 for (
const auto &PI : SUI->
Preds)
535 (PI.getKind() !=
SDep::Data || PI.getReg() != Reg))
538 if (!HII->getIncrementValue(MJ, Incr))
541 int64_t
Offset =
MI.getOperand(OPI).getImm();
542 if (!HII->isValidOffset(
MI.getOpcode(),
Offset+Incr, HRI))
545 MI.getOperand(OPI).setImm(
Offset + Incr);
554 if (!HII->getBaseAndOffsetPosition(
MI, BP,
OP))
556 MI.getOperand(
OP).setImm(ChangedOffset);
584 for (
auto &MO :
MI.operands())
585 if (MO.isReg() && MO.isDef())
586 DefRegsSet.
insert(MO.getReg());
588 for (
auto &MO :
MI.operands())
589 if (MO.isReg() && MO.isUse() && DefRegsSet.
count(MO.getReg()))
595 assert(Op1.
isReg() &&
"Post increment operand has be to a register.");
598 if (
MI.getDesc().mayStore()) {
601 assert(Op0.
isReg() &&
"Post increment operand has be to a register.");
606 llvm_unreachable(
"mayLoad or mayStore not set for Post Increment operation");
612 return MI.getOperand(
MI.getNumOperands()-1);
616 unsigned Opc =
MI.getOpcode();
618 case Hexagon::L4_loadrd_ap:
619 case Hexagon::L4_loadrb_ap:
620 case Hexagon::L4_loadrh_ap:
621 case Hexagon::L4_loadrub_ap:
622 case Hexagon::L4_loadruh_ap:
623 case Hexagon::L4_loadri_ap:
631 return MI.getOperand(1);
654 if (!HII->mayBeNewStore(
MI))
667 if (PacketRC == &Hexagon::DoubleRegsRegClass)
680 if (HII->isPostIncrement(
MI) &&
685 if (HII->isPostIncrement(PacketMI) && PacketMI.
mayLoad() &&
700 if (HII->isPredicated(PacketMI)) {
701 if (!HII->isPredicated(
MI))
706 unsigned predRegNumSrc = 0;
707 unsigned predRegNumDst = 0;
711 for (
auto &MO : PacketMI.
operands()) {
714 predRegNumSrc = MO.getReg();
715 predRegClass = HRI->getMinimalPhysRegClass(predRegNumSrc);
716 if (predRegClass == &Hexagon::PredRegsRegClass)
719 assert((predRegClass == &Hexagon::PredRegsRegClass) &&
720 "predicate register not found in a predicated PacketMI instruction");
723 for (
auto &MO :
MI.operands()) {
726 predRegNumDst = MO.getReg();
727 predRegClass = HRI->getMinimalPhysRegClass(predRegNumDst);
728 if (predRegClass == &Hexagon::PredRegsRegClass)
731 assert((predRegClass == &Hexagon::PredRegsRegClass) &&
732 "predicate register not found in a predicated MI instruction");
742 if (predRegNumDst != predRegNumSrc ||
743 HII->isDotNewInst(PacketMI) != HII->isDotNewInst(
MI) ||
756 unsigned StartCheck = 0;
765 if (&TempMI != &PacketMI && !StartCheck)
769 if (&TempMI == &PacketMI)
772 for (
auto &MO :
MI.operands())
783 if (!HII->isPostIncrement(
MI)) {
784 for (
unsigned opNum = 0; opNum <
MI.getNumOperands()-1; opNum++) {
795 for (
auto &MO : PacketMI.
operands()) {
796 if (MO.isRegMask() && MO.clobbersPhysReg(DepReg))
798 if (!MO.isReg() || !MO.isDef() || !MO.isImplicit())
801 if (R == DepReg || HRI->isSuperRegister(DepReg, R))
810 for (
auto &MO :
MI.operands()) {
811 if (MO.isReg() && MO.isUse() && MO.isImplicit() && MO.getReg() == DepReg)
821 const SUnit *PacketSU,
unsigned DepReg,
823 if (!HII->mayBeNewStore(
MI))
838 for (
auto &MO :
I.operands()) {
839 if (CheckDef && MO.isRegMask() && MO.clobbersPhysReg(DepReg))
841 if (!MO.isReg() || MO.getReg() != DepReg || !MO.isImplicit())
843 if (CheckDef == MO.isDef())
854 if (HII->isDotNewInst(
MI) && !HII->mayBeNewStore(
MI))
883 if (RC == &Hexagon::PredRegsRegClass)
884 return HII->predCanBeUsedAsDotNew(PI, DepReg);
886 if (RC != &Hexagon::PredRegsRegClass && !HII->mayBeNewStore(
MI))
891 int NewOpcode = (RC != &Hexagon::PredRegsRegClass) ? HII->getDotNewOp(
MI) :
892 HII->getDotNewPredOp(
MI,
MBPI);
897 if (!ResourcesAvailable)
926 if (!HII->isPredicated(*
I))
935 if (PacketSU->
isSucc(PacketSUDep)) {
936 for (
unsigned i = 0; i < PacketSU->
Succs.size(); ++i) {
937 auto &Dep = PacketSU->
Succs[i];
938 if (Dep.getSUnit() == PacketSUDep && Dep.getKind() ==
SDep::Anti &&
939 Dep.getReg() == DepReg)
955 for (
auto &
Op :
MI.operands()) {
956 if (
Op.isReg() &&
Op.getReg() &&
Op.isUse() &&
957 Hexagon::PredRegsRegClass.contains(
Op.getReg()))
999 if (PacketSU->
isSucc(SU)) {
1000 for (
unsigned i = 0; i < PacketSU->
Succs.size(); ++i) {
1001 auto Dep = PacketSU->
Succs[i];
1006 if (Dep.getSUnit() == SU && Dep.getKind() ==
SDep::Data &&
1007 Hexagon::PredRegsRegClass.contains(Dep.getReg())) {
1026 return PReg1 == PReg2 &&
1027 Hexagon::PredRegsRegClass.contains(PReg1) &&
1028 Hexagon::PredRegsRegClass.contains(PReg2) &&
1030 HII->isDotNewInst(MI1) == HII->isDotNewInst(MI2);
1036 PromotedToDotNew =
false;
1037 GlueToNewValueJump =
false;
1038 GlueAllocframeStore =
false;
1039 FoundSequentialDependence =
false;
1046 if (
MI.isDebugInstr())
1049 if (
MI.isCFIInstruction())
1053 if (
MI.isInlineAsm())
1056 if (
MI.isImplicitDef())
1071 if (
MI.isEHLabel() ||
MI.isCFIInstruction())
1085 if (HII->isSolo(
MI))
1088 if (
MI.getOpcode() == Hexagon::PATCHABLE_FUNCTION_ENTER ||
1089 MI.getOpcode() == Hexagon::PATCHABLE_FUNCTION_EXIT ||
1090 MI.getOpcode() == Hexagon::PATCHABLE_TAIL_CALL)
1093 if (
MI.getOpcode() == Hexagon::A2_nop)
1122 if (
MI.isInlineAsm())
1130 switch (
MI.getOpcode()) {
1131 case Hexagon::S2_storew_locked:
1132 case Hexagon::S4_stored_locked:
1133 case Hexagon::L2_loadw_locked:
1134 case Hexagon::L4_loadd_locked:
1135 case Hexagon::Y2_dccleana:
1136 case Hexagon::Y2_dccleaninva:
1137 case Hexagon::Y2_dcinva:
1138 case Hexagon::Y2_dczeroa:
1139 case Hexagon::Y4_l2fetch:
1140 case Hexagon::Y5_l2fetch: {
1144 unsigned TJ = HII.
getType(MJ);
1167 for (
auto &
B :
MF) {
1171 BundleIt =
MI.getIterator();
1172 if (!
MI.isInsideBundle())
1181 bool InsertBeforeBundle;
1182 if (
MI.isInlineAsm())
1184 else if (
MI.isDebugInstr())
1185 InsertBeforeBundle =
true;
1196 unsigned Opc =
MI.getOpcode();
1198 case Hexagon::Y2_barrier:
1199 case Hexagon::Y2_dcfetchbo:
1200 case Hexagon::Y4_l2fetch:
1201 case Hexagon::Y5_l2fetch:
1214 if (HII->isPredicated(
I) || HII->isPredicated(J))
1217 BitVector DeadDefs(Hexagon::NUM_TARGET_REGS);
1218 for (
auto &MO :
I.operands()) {
1219 if (!MO.isReg() || !MO.isDef() || !MO.isDead())
1221 DeadDefs[MO.getReg()] =
true;
1225 if (!MO.isReg() || !MO.isDef() || !MO.isDead())
1228 if (R != Hexagon::USR_OVF && DeadDefs[R])
1238 if ((HII->isSaveCalleeSavedRegsCall(
I) &&
1240 (HII->isSaveCalleeSavedRegsCall(J) &&
1252 if (
MI.isCall() || HII->isDeallocRet(
MI) || HII->isNewValueJump(
MI))
1254 if (HII->isPredicated(
MI) && HII->isPredicatedNew(
MI) && HII->isJumpR(
MI))
1259 if (HII->isLoopN(
I) && isBadForLoopN(J))
1261 if (HII->isLoopN(J) && isBadForLoopN(
I))
1266 return HII->isDeallocRet(
I) &&
1284 if (!OpJ.isRegMask())
1286 assert((J.
isCall() || HII->isTailCall(J)) &&
"Regmask on a non-call");
1289 if (OpJ.clobbersPhysReg(OpI.getReg()))
1291 }
else if (OpI.isRegMask()) {
1303 bool StoreI =
I.mayStore(), StoreJ = J.
mayStore();
1304 if ((SysI && StoreJ) || (SysJ && StoreI))
1307 if (StoreI && StoreJ) {
1308 if (HII->isNewValueInst(J) || HII->isMemOp(J) || HII->isMemOp(
I))
1313 bool MopStI = HII->isMemOp(
I) || StoreI;
1314 bool MopStJ = HII->isMemOp(J) || StoreJ;
1315 if (MopStI && MopStJ)
1319 return (StoreJ && HII->isDeallocRet(
I)) || (StoreI && HII->isDeallocRet(J));
1332 IgnoreDepMIs.clear();
1364 if (NextMII !=
I.getParent()->end() && HII->isNewValueJump(*NextMII)) {
1367 bool secondRegMatch =
false;
1371 if (NOp1.
isReg() &&
I.getOperand(0).getReg() == NOp1.
getReg())
1372 secondRegMatch =
true;
1388 if (PI->getOpcode() == Hexagon::S2_allocframe || PI->mayStore() ||
1389 HII->isLoopN(*PI)) {
1395 if (OpR.
isReg() && PI->modifiesRegister(OpR.
getReg(), HRI)) {
1401 GlueToNewValueJump =
true;
1410 for (
unsigned i = 0; i < SUJ->
Succs.size(); ++i) {
1411 if (FoundSequentialDependence)
1414 if (SUJ->
Succs[i].getSUnit() != SUI)
1433 unsigned DepReg = 0;
1436 DepReg = SUJ->
Succs[i].getReg();
1437 RC = HRI->getMinimalPhysRegClass(DepReg);
1440 if (
I.isCall() || HII->isJumpR(
I) ||
I.isReturn() || HII->isTailCall(
I)) {
1454 if (DepType ==
SDep::Data && HII->isDotCurInst(J)) {
1455 if (HII->isHVXVec(
I))
1463 PromotedToDotNew =
true;
1465 FoundSequentialDependence =
true;
1469 if (HII->isNewValueJump(
I))
1475 if (HII->isPredicated(
I) && HII->isPredicated(J) &&
1489 auto Itr =
find(IgnoreDepMIs, &J);
1490 if (Itr != IgnoreDepMIs.end()) {
1494 IgnoreDepMIs.push_back(&
I);
1506 if (
I.isConditionalBranch() && DepType !=
SDep::Data &&
1511 FoundSequentialDependence =
true;
1525 FoundSequentialDependence =
true;
1531 bool LoadI =
I.mayLoad(), StoreI =
I.mayStore();
1532 bool NVStoreJ = HII->isNewValueStore(J);
1533 bool NVStoreI = HII->isNewValueStore(
I);
1534 bool IsVecJ = HII->isHVXVec(J);
1535 bool IsVecI = HII->isHVXVec(
I);
1539 if (LoadJ && LoadI && HII->isPureSlot0(J)) {
1540 FoundSequentialDependence =
true;
1545 ((LoadJ && StoreI && !NVStoreI) ||
1546 (StoreJ && LoadI && !NVStoreJ)) &&
1547 (J.
getOpcode() != Hexagon::S2_allocframe &&
1548 I.getOpcode() != Hexagon::S2_allocframe) &&
1549 (J.
getOpcode() != Hexagon::L2_deallocframe &&
1550 I.getOpcode() != Hexagon::L2_deallocframe) &&
1551 (!HII->isMemOp(J) && !HII->isMemOp(
I)) && (!IsVecJ && !IsVecI))
1554 if (StoreJ && LoadI &&
alias(J,
I)) {
1555 FoundSequentialDependence =
true;
1560 if (!LoadJ || (!LoadI && !StoreI)) {
1563 FoundSequentialDependence =
true;
1578 unsigned Opc =
I.getOpcode();
1580 case Hexagon::S2_storerd_io:
1581 case Hexagon::S2_storeri_io:
1582 case Hexagon::S2_storerh_io:
1583 case Hexagon::S2_storerb_io:
1590 if (GlueAllocframeStore)
1610 if (
Op.isReg() &&
Op.isDef()) {
1614 }
else if (!
Op.isRegMask()) {
1618 FoundSequentialDependence =
true;
1630 FoundSequentialDependence =
true;
1635 if (FoundSequentialDependence) {
1655 if (PromotedToDotNew)
1662 if (GlueAllocframeStore) {
1664 GlueAllocframeStore =
false;
1670 if (GlueToNewValueJump) {
1673 GlueToNewValueJump =
false;
1681 FoundSequentialDependence =
false;
1691 bool FoundLoad =
false;
1692 bool FoundStore =
false;
1695 unsigned Opc = MJ->getOpcode();
1696 if (Opc == Hexagon::S2_allocframe || Opc == Hexagon::L2_deallocframe)
1698 if (HII->isMemOp(*MJ))
1702 if (MJ->mayStore() && !HII->isNewValueStore(*MJ))
1705 return FoundLoad && FoundStore;
1715 PacketStalls =
false;
1716 PacketStallCycles = 0;
1719 PacketStallCycles = std::max(PacketStallCycles,
calcStall(
MI));
1721 if (
MI.isImplicitDef()) {
1729 bool ExtMI = HII->isExtended(
MI) || HII->isConstExtended(
MI);
1732 if (GlueToNewValueJump) {
1742 bool ExtNvjMI = HII->isExtended(NvjMI) || HII->isConstExtended(NvjMI);
1749 if (Good && ExtNvjMI)
1775 if (PromotedToDotNew)
1777 if (GlueAllocframeStore) {
1779 GlueAllocframeStore =
false;
1794 dbgs() <<
"Finalizing packet:\n";
1796 for (MachineInstr *MI : CurrentPacketMIs) {
1797 unsigned R = ResourceTracker->getUsedResources(Idx++);
1798 dbgs() <<
" * [res:0x" << utohexstr(R) <<
"] " << *MI;
1803 bool memShufDisabled = getmemShufDisabled();
1804 if (memShufDisabled && !foundLSInPacket()) {
1805 setmemShufDisabled(
false);
1808 memShufDisabled = getmemShufDisabled();
1810 OldPacketMIs.clear();
1813 for (
auto &
I :
make_range(HII->expandVGatherPseudo(*
MI), NextMI))
1814 OldPacketMIs.push_back(&
I);
1816 CurrentPacketMIs.clear();
1818 if (OldPacketMIs.size() > 1) {
1822 auto BundleMII = std::prev(FirstMI);
1823 if (memShufDisabled)
1824 HII->setBundleNoShuf(BundleMII);
1826 setmemShufDisabled(
false);
1829 PacketHasDuplex =
false;
1830 PacketHasSLOT0OnlyInsn =
false;
1831 ResourceTracker->clearResources();
1856 PacketHasSLOT0OnlyInsn |= HII->isPureSlot0(*MJ);
1858 int Opcode = HII->getDuplexOpcode(
MI,
false);
1862 if (HII->isDuplexPair(
MI, *MJ) && !PacketHasSLOT0OnlyInsn) {
1863 PacketHasDuplex =
true;
1870 MIRef.
setDesc(HII->get(Opcode));
1887 if (!OldPacketMIs.empty()) {
1888 auto *OldBB = OldPacketMIs.front()->getParent();
1889 auto *ThisBB =
I.getParent();
1921 for (
auto &Pred : SUI->
Preds)
1922 if (Pred.getSUnit() == SUJ)
1923 if ((Pred.getLatency() == 0 && Pred.isAssignedRegDep()) ||
1924 HII->isNewValueJump(
I) || HII->isToBeScheduledASAP(*J,
I))
1930 for (
auto *J : OldPacketMIs) {
1932 for (
auto &Pred : SUI->
Preds)
1933 if (Pred.getSUnit() == SUJ && Pred.getLatency() > 1)
1934 return Pred.getLatency();
1946 return Latency > PacketStallCycles;
1955 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")
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)
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)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
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
Analysis pass which computes a MachineDominatorTree.
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 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.
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 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.
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.