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)
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();
204 HRI = HST.getRegisterInfo();
205 auto &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
206 auto *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
208 &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
211 HII->genAllInsnTimingClasses(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);
288 if (Reserve && Avail)
297 if (DepReg == HRI->getRARegister())
300 if (HII->isDeallocRet(
MI))
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)
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:
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:
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);
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())
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:
1581 if (GlueAllocframeStore)
1601 if (
Op.isReg() &&
Op.isDef()) {
1605 }
else if (!
Op.isRegMask()) {
1609 FoundSequentialDependence =
true;
1621 FoundSequentialDependence =
true;
1626 if (FoundSequentialDependence) {
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";
1787 for (MachineInstr *MI : CurrentPacketMIs) {
1788 unsigned R = ResourceTracker->getUsedResources(Idx++);
1789 dbgs() <<
" * [res:0x" << utohexstr(R) <<
"] " << *MI;
1794 bool memShufDisabled = getmemShufDisabled();
1795 if (memShufDisabled && !foundLSInPacket()) {
1796 setmemShufDisabled(
false);
1799 memShufDisabled = getmemShufDisabled();
1801 OldPacketMIs.clear();
1804 for (
auto &
I :
make_range(HII->expandVGatherPseudo(*
MI), NextMI))
1805 OldPacketMIs.push_back(&
I);
1807 CurrentPacketMIs.clear();
1809 if (OldPacketMIs.size() > 1) {
1813 auto BundleMII = std::prev(FirstMI);
1814 if (memShufDisabled)
1815 HII->setBundleNoShuf(BundleMII);
1817 setmemShufDisabled(
false);
1820 PacketHasDuplex =
false;
1821 PacketHasSLOT0OnlyInsn =
false;
1822 ResourceTracker->clearResources();
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();
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< 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)
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.
A private abstract base class describing the concept of an individual alias analysis implementation.
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.
LLVM_ABI 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.
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.
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.
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 =0
Return the target's register information.
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.
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.
FuncUnits getUnits() const
Returns the choice of FUs.