Go to the documentation of this file.
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)
107 StringRef getPassName()
const override {
return "Hexagon Packetizer"; }
118 const bool Minimal =
false;
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();
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)
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();
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)
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);
545 ChangedOffset = Offset;
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;
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;
1869 MIRef.
setDesc(HII->get(Opcode));
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);
bool tryAllocateResourcesForConstExt(bool Reserve)
bool isBranch(QueryType Type=AnyInBundle) const
Returns true if this is a conditional, unconditional, or indirect branch.
bool isCallDependent(const MachineInstr &MI, SDep::Kind DepType, unsigned DepReg)
This is an optimization pass for GlobalISel generic memory operations.
bool isImplicitDef() const
static bool isControlFlow(const MachineInstr &MI)
bool canPromoteToNewValueStore(const MachineInstr &MI, const MachineInstr &PacketMI, unsigned DepReg)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
bool canReserveResourcesForConstExt()
static cl::opt< bool > DisablePacketizer("disable-packetizer", cl::Hidden, cl::desc("Disable Hexagon packetizer pass"))
MachineLoop * getLoopFor(const MachineBasicBlock *BB) const
Return the innermost loop that BB lives in.
bool alias(const MachineInstr &MI1, const MachineInstr &MI2, bool UseTBAA=true) const
static bool isImplicitDependency(const MachineInstr &I, bool CheckDef, unsigned DepReg)
static bool hasWriteToReadDep(const MachineInstr &FirstI, const MachineInstr &SecondI, const TargetRegisterInfo *TRI)
bool canReserveResources(const MCInstrDesc *MID)
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
void reserveResourcesForConstExt()
unsigned getSchedClass() const
Return the scheduling class for this instruction.
void initializeHexagonPacketizerPass(PassRegistry &)
unsigned getStackRegister() const
Reg
All possible values of the reg field in the ModR/M byte.
void setmemShufDisabled(bool val)
bool canPromoteToNewValue(const MachineInstr &MI, const SUnit *PacketSU, unsigned DepReg, MachineBasicBlock::iterator &MII)
@ Anti
A register anti-dependence (aka WAR).
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Dependence - This class represents a dependence between two memory memory references in a function.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Kind
These are the different kinds of scheduling dependencies.
MachineInstr * CreateMachineInstr(const MCInstrDesc &MCID, DebugLoc DL, bool NoImplicit=false)
CreateMachineInstr - Allocate a new MachineInstr.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
static cl::opt< bool > Slot1Store("slot1-store-slot0-load", cl::Hidden, cl::init(true), cl::desc("Allow slot1 store and slot0 load"))
bool isHVXMemWithAIndirect(const MachineInstr &I, const MachineInstr &J) const
bool demoteToDotOld(MachineInstr &MI)
bool isPredicated(const MachineInstr &MI) const override
Returns true if the instruction is already predicated.
SmallVector< SDep, 4 > Succs
All sunit successors.
Properties which a MachineFunction may have at a given point in time.
bool useCallersSP(MachineInstr &MI)
bool isNewValueStore(const MachineInstr &MI) const
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
static bool cannotCoexistAsymm(const MachineInstr &MI, const MachineInstr &MJ, const HexagonInstrInfo &HII)
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 !...
DFAPacketizer * ResourceTracker
std::pair< iterator, bool > insert(const ValueT &V)
bool isPostIncrement(const MachineInstr &MI) const override
Return true for post-incremented instructions.
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
unsigned const TargetRegisterInfo * TRI
#define HEXAGON_LRFP_SIZE
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
bool hasOrderedMemoryRef() const
Return true if this instruction may have an ordered or volatile memory reference, or if the informati...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
virtual const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const =0
Return a null-terminated list of all of the callee-saved registers on this target.
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...
void initPacketizerState() override
bool isPureSlot0(const MachineInstr &MI) const
bool isCall(QueryType Type=AnyInBundle) const
static bool isLoadAbsSet(const MachineInstr &MI)
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
bool ignorePseudoInstruction(const MachineInstr &MI, const MachineBasicBlock *MBB) override
static const MachineOperand & getAbsSetOperand(const MachineInstr &MI)
const MachineOperand & getOperand(unsigned i) const
static bool isDirectJump(const MachineInstr &MI)
bool isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) override
Represent the analysis usage information of a pass.
void deleteMachineInstr(MachineInstr *MI)
DeleteMachineInstr - Delete the given MachineInstr.
const MachineFunctionProperties & getProperties() const
Get the function properties.
Describe properties that are true of each instruction in the target description file.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
MachineOperand class - Representation of each machine instruction operand.
bool hasControlDependence(const MachineInstr &I, const MachineInstr &J)
MachineFunctionProperties & set(Property P)
Register getFrameRegister(const MachineFunction &MF) const override
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
uint64_t getType(const MachineInstr &MI) const
@ Output
A register output-dependence (aka WAW).
@ Data
Regular data dependence (aka true-dependence).
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
cl::opt< bool > ScheduleInlineAsm
static cl::opt< bool > PacketizeVolatiles("hexagon-packetize-volatiles", cl::Hidden, cl::init(true), cl::desc("Allow non-solo packetization of volatile memory references"))
bool promoteToDotNew(MachineInstr &MI, SDep::Kind DepType, MachineBasicBlock::iterator &MII, const TargetRegisterClass *RC)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
static MachineBasicBlock::iterator moveInstrOut(MachineInstr &MI, MachineBasicBlock::iterator BundleIt, bool Before)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
@ Order
Any other ordering dependency.
const HexagonInstrInfo * getInstrInfo() const override
instr_iterator getInstrIterator() const
FuncUnits getUnits() const
Returns the choice of FUs.
bool arePredicatesComplements(MachineInstr &MI1, MachineInstr &MI2)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
static bool isRegDependence(const SDep::Kind DepType)
static unsigned getPredicatedRegister(MachineInstr &MI, const HexagonInstrInfo *QII)
Gets the predicate register of a predicated instruction.
void unpacketizeSoloInstrs(MachineFunction &MF)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Representation of each machine instruction.
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
static bool isSchedBarrier(const MachineInstr &MI)
MachineInstr * getInstr() const
Returns the representative MachineInstr for this SUnit.
const MachineLoopInfo * MLI
initializer< Ty > init(const Ty &Val)
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...
const InstrItineraryData * getInstrItins() const
void unbundleFromPred()
Break bundle above this instruction.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
bool isNewifiable(const MachineInstr &MI, const TargetRegisterClass *NewRC)
Register getReg() const
getReg - Returns the register number.
bool hasV60OpsOnly() const
bool cannotCoexist(const MachineInstr &MI, const MachineInstr &MJ)
bool readsRegister(Register Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr reads the specified register.
MachineBasicBlock::iterator addToPacket(MachineInstr &MI) override
void useCalleesSP(MachineInstr &MI)
StringRef - Represent a constant reference to a string, i.e.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
bool isRestrictNoSlot1Store(const MachineInstr &MI) const
bool restrictingDepExistInPacket(MachineInstr &, unsigned)
bool isTerminator(QueryType Type=AnyInBundle) const
Returns true if this instruction part of the terminator for a basic block.
static bool doesModifyCalleeSavedReg(const MachineInstr &MI, const TargetRegisterInfo *TRI)
Returns true if the instruction modifies a callee-saved register.
Wrapper class representing virtual and physical registers.
bool modifiesRegister(Register Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr modifies (fully define or partially define) the specified register.
bool isLegalToPruneDependencies(SUnit *SUI, SUnit *SUJ) override
static const MachineOperand & getStoreValueOperand(const MachineInstr &MI)
void undoChangedOffset(MachineInstr &MI)
Undo the changed offset.
Function & getFunction()
Return the LLVM function that this machine code represents.
bool hasDeadDependence(const MachineInstr &I, const MachineInstr &J)
FunctionPass * createHexagonPacketizer(bool Minimal)
Iterator for intrusive lists based on ilist_node.
bool mayStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly modify memory.
const MachineBranchProbabilityInfo * MBPI
A handle to the branch probability pass.
hexagon Hexagon Packetizer
bool isSoloInstruction(const MachineInstr &MI) override
INITIALIZE_PASS_BEGIN(HexagonPacketizer, "hexagon-packetizer", "Hexagon Packetizer", false, false) INITIALIZE_PASS_END(HexagonPacketizer
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 setDesc(const MCInstrDesc &TID)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one.
bool isSucc(const SUnit *N) const
Tests if node N is a successor of this node.
std::map< MachineInstr *, SUnit * > MIToSUnit
bool isPredicatedTrue(const MachineInstr &MI) const
bool producesStall(const MachineInstr &MI)
bool canPromoteToDotCur(const MachineInstr &MI, const SUnit *PacketSU, unsigned DepReg, MachineBasicBlock::iterator &MII, const TargetRegisterClass *RC)
static cl::opt< bool > DisableVecDblNVStores("disable-vecdbl-nv-stores", cl::Hidden, cl::desc("Disable vector double new-value-stores"))
bool isBundledWithSucc() const
Return true if this instruction is part of a bundle, and it is not the last instruction in the bundle...
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
static bool isSystemInstr(const MachineInstr &MI)
static const MachineOperand & getPostIncrementOperand(const MachineInstr &MI, const HexagonInstrInfo *HII)
bool canPromoteToDotNew(const MachineInstr &MI, const SUnit *PacketSU, unsigned DepReg, MachineBasicBlock::iterator &MII, const TargetRegisterClass *RC)
FunctionPass class - This class is used to implement most global optimizations.
SmallVector< SDep, 4 > Preds
All sunit predecessors.
Scheduling unit. This is a node in the scheduling DAG.
bool promoteToDotCur(MachineInstr &MI, SDep::Kind DepType, MachineBasicBlock::iterator &MII, const TargetRegisterClass *RC)
static cl::opt< bool > EnableGenAllInsnClass("enable-gen-insn", cl::Hidden, cl::desc("Generate all instruction with TC"))
AnalysisUsage & addRequired()
const InstrStage * beginStage(unsigned ItinClassIndx) const
Return the first stage of the itinerary.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
MachineBasicBlock iterator that automatically skips over MIs that are inside bundles (i....
bool hasRegMaskDependence(const MachineInstr &I, const MachineInstr &J)
bool isBarrier(QueryType Type=AnyInBundle) const
Returns true if the specified instruction stops control flow from executing the instruction immediate...
iterator_range< mop_iterator > operands()
void reserveResources(const MCInstrDesc *MID)
std::vector< MachineInstr * > CurrentPacketMIs
unsigned getRARegister() const
void endPacket(MachineBasicBlock *MBB, MachineBasicBlock::iterator MI) override
unsigned int calcStall(const MachineInstr &MI)
bool hasDualStoreDependence(const MachineInstr &I, const MachineInstr &J)