56#define DEBUG_TYPE "packets"
59 cl::desc(
"Disable Hexagon packetizer pass"));
63 cl::desc(
"Allow slot1 store and slot0 load"));
67 cl::desc(
"Allow non-solo packetization of volatile memory references"));
71 cl::desc(
"Generate all instruction with TC"));
75 cl::desc(
"Disable vector double new-value-stores"));
85 HexagonPacketizer(
bool Min =
false)
88 void getAnalysisUsage(AnalysisUsage &AU)
const override {
91 AU.
addRequired<MachineBranchProbabilityInfoWrapperPass>();
99 StringRef getPassName()
const override {
return "Hexagon Packetizer"; }
100 bool runOnMachineFunction(MachineFunction &Fn)
override;
102 MachineFunctionProperties getRequiredProperties()
const override {
103 return MachineFunctionProperties().setNoVRegs();
107 const HexagonInstrInfo *HII =
nullptr;
108 const HexagonRegisterInfo *HRI =
nullptr;
109 const bool Minimal =
false;
114char HexagonPacketizer::ID = 0;
117 "Hexagon Packetizer",
false,
false)
133 addMutation(std::make_unique<HexagonSubtarget::UsrOverflowMutation>());
134 addMutation(std::make_unique<HexagonSubtarget::HVXMemLatencyMutation>());
135 addMutation(std::make_unique<HexagonSubtarget::BankConflictMutation>());
142 for (
auto &MO : FirstI.
operands()) {
143 if (!MO.isReg() || !MO.isDef())
159 InsertPt = std::next(BundleIt).getInstrIterator();
165 if (
MI.isBundledWithSucc()) {
172 MI.unbundleFromPred();
174 B.splice(InsertPt, &
B,
MI.getIterator());
180 for (++
I;
I !=
E &&
I->isBundledWithPred(); ++
I)
193 BundleIt->eraseFromParent();
202 HII = HST.getInstrInfo();
203 HRI = HST.getRegisterInfo();
204 auto &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
205 auto *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
207 &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
210 HII->genAllInsnTimingClasses(MF);
215 HexagonPacketizerList
Packetizer(MF, MLI, AA, MBPI, MinOnly);
228 for (MachineBasicBlock &MB : MF) {
235 if (HST.isTinyCoreWithDuplex())
236 HII->translateInstrsForDup(MF,
true);
239 for (
auto &MB : MF) {
240 auto Begin = MB.begin(), End = MB.end();
241 while (Begin != End) {
245 while (RB != End && HII->isSchedulingBoundary(*RB, &MB, MF))
250 while (RE != End && !HII->isSchedulingBoundary(*RE, &MB, MF))
264 if (HST.isTinyCoreWithDuplex())
265 HII->translateInstrsForDup(MF,
false);
285 auto *ExtMI =
MF.CreateMachineInstr(HII->get(Hexagon::A4_ext),
DebugLoc());
287 if (Reserve && Avail)
289 MF.deleteMachineInstr(ExtMI);
296 if (DepReg == HRI->getRARegister())
299 if (HII->isDeallocRet(
MI))
300 if (DepReg == HRI->getFrameRegister() || DepReg == HRI->getStackRegister())
310 if (MO.isReg() && MO.getReg() == DepReg && !MO.isImplicit())
323 return MI.getOpcode() == Hexagon::J2_jump;
327 switch (
MI.getOpcode()) {
328 case Hexagon::Y2_barrier:
335 return MI.getDesc().isTerminator() ||
MI.getDesc().isCall();
342 for (
auto *CSR =
TRI->getCalleeSavedRegs(&MF); CSR && *CSR; ++CSR)
343 if (
MI.modifiesRegister(*CSR,
TRI))
354 if (NewRC == &Hexagon::PredRegsRegClass) {
355 if (HII->isHVXVec(
MI) &&
MI.mayStore())
357 return HII->isPredicated(
MI) && HII->getDotNewPredOp(
MI,
nullptr) > 0;
360 return HII->mayBeNewStore(
MI);
370 int CurOpcode = HII->getDotCurOp(
MI);
371 MI.setDesc(HII->get(CurOpcode));
379 if (HII->isDotCurInst(*BI)) {
384 for (
auto &MO : BI->operands())
385 if (MO.isReg() && MO.getReg() ==
MI->getOperand(0).getReg())
392 MI->setDesc(HII->get(HII->getNonDotCurOp(*
MI)));
400 if (!HII->isHVXVec(
MI))
402 if (!HII->isHVXVec(*MII))
406 if (HII->isDotCurInst(
MI) && !HII->mayBeCurLoad(
MI))
409 if (!HII->mayBeCurLoad(
MI))
418 dbgs() <<
"in packet\n";);
421 dbgs() <<
"Checking CUR against ";
425 bool FoundMatch =
false;
426 for (
auto &MO : MJ.operands())
427 if (MO.isReg() && MO.getReg() == DestReg)
436 if (BI->readsRegister(DepReg,
MF.getSubtarget().getRegisterInfo()))
453 if (RC == &Hexagon::PredRegsRegClass)
454 NewOpcode = HII->getDotNewPredOp(
MI,
MBPI);
456 NewOpcode = HII->getDotNewOp(
MI);
457 MI.setDesc(HII->get(NewOpcode));
462 int NewOpcode = HII->getDotOldOp(
MI);
463 MI.setDesc(HII->get(NewOpcode));
468 unsigned Opc =
MI.getOpcode();
470 case Hexagon::S2_storerd_io:
471 case Hexagon::S2_storeri_io:
472 case Hexagon::S2_storerh_io:
473 case Hexagon::S2_storerb_io:
478 unsigned FrameSize =
MF.getFrameInfo().getStackSize();
481 if (HII->isValidOffset(
Opc, NewOff, HRI)) {
489 unsigned Opc =
MI.getOpcode();
491 case Hexagon::S2_storerd_io:
492 case Hexagon::S2_storeri_io:
493 case Hexagon::S2_storerh_io:
494 case Hexagon::S2_storerb_io:
499 unsigned FrameSize =
MF.getFrameInfo().getStackSize();
512 if (!HII->getBaseAndOffsetPosition(
MI, BPI, OPI))
515 if (!HII->getBaseAndOffsetPosition(MJ, BPJ, OPJ))
523 for (
const auto &PI : SUI->
Preds)
525 (PI.getKind() !=
SDep::Data || PI.getReg() != Reg))
528 if (!HII->getIncrementValue(MJ, Incr))
531 int64_t
Offset =
MI.getOperand(OPI).getImm();
532 if (!HII->isValidOffset(
MI.getOpcode(),
Offset+Incr, HRI))
535 MI.getOperand(OPI).setImm(
Offset + Incr);
544 if (!HII->getBaseAndOffsetPosition(
MI, BP,
OP))
546 MI.getOperand(
OP).setImm(ChangedOffset);
574 for (
auto &MO :
MI.operands())
575 if (MO.isReg() && MO.isDef())
576 DefRegsSet.
insert(MO.getReg());
578 for (
auto &MO :
MI.operands())
579 if (MO.isReg() && MO.isUse() && DefRegsSet.
count(MO.getReg()))
585 assert(Op1.
isReg() &&
"Post increment operand has be to a register.");
588 if (
MI.getDesc().mayStore()) {
591 assert(Op0.
isReg() &&
"Post increment operand has be to a register.");
596 llvm_unreachable(
"mayLoad or mayStore not set for Post Increment operation");
602 return MI.getOperand(
MI.getNumOperands()-1);
606 unsigned Opc =
MI.getOpcode();
608 case Hexagon::L4_loadrd_ap:
609 case Hexagon::L4_loadrb_ap:
610 case Hexagon::L4_loadrh_ap:
611 case Hexagon::L4_loadrub_ap:
612 case Hexagon::L4_loadruh_ap:
613 case Hexagon::L4_loadri_ap:
621 return MI.getOperand(1);
644 if (!HII->mayBeNewStore(
MI))
657 if (PacketRC == &Hexagon::DoubleRegsRegClass)
670 if (HII->isPostIncrement(
MI) &&
675 if (HII->isPostIncrement(PacketMI) && PacketMI.
mayLoad() &&
690 if (HII->isPredicated(PacketMI)) {
691 if (!HII->isPredicated(
MI))
696 unsigned predRegNumSrc = 0;
697 unsigned predRegNumDst = 0;
701 for (
auto &MO : PacketMI.
operands()) {
704 predRegNumSrc = MO.getReg();
705 predRegClass = HRI->getMinimalPhysRegClass(predRegNumSrc);
706 if (predRegClass == &Hexagon::PredRegsRegClass)
709 assert((predRegClass == &Hexagon::PredRegsRegClass) &&
710 "predicate register not found in a predicated PacketMI instruction");
713 for (
auto &MO :
MI.operands()) {
716 predRegNumDst = MO.getReg();
717 predRegClass = HRI->getMinimalPhysRegClass(predRegNumDst);
718 if (predRegClass == &Hexagon::PredRegsRegClass)
721 assert((predRegClass == &Hexagon::PredRegsRegClass) &&
722 "predicate register not found in a predicated MI instruction");
732 if (predRegNumDst != predRegNumSrc ||
733 HII->isDotNewInst(PacketMI) != HII->isDotNewInst(
MI) ||
746 unsigned StartCheck = 0;
755 if (&TempMI != &PacketMI && !StartCheck)
759 if (&TempMI == &PacketMI)
762 for (
auto &MO :
MI.operands())
773 if (!HII->isPostIncrement(
MI)) {
774 for (
unsigned opNum = 0; opNum <
MI.getNumOperands()-1; opNum++) {
785 for (
auto &MO : PacketMI.
operands()) {
786 if (MO.isRegMask() && MO.clobbersPhysReg(DepReg))
788 if (!MO.isReg() || !MO.isDef() || !MO.isImplicit())
791 if (R == DepReg || HRI->isSuperRegister(DepReg, R))
800 for (
auto &MO :
MI.operands()) {
801 if (MO.isReg() && MO.isUse() && MO.isImplicit() && MO.getReg() == DepReg)
811 const SUnit *PacketSU,
unsigned DepReg,
813 if (!HII->mayBeNewStore(
MI))
828 for (
auto &MO :
I.operands()) {
829 if (CheckDef && MO.isRegMask() && MO.clobbersPhysReg(DepReg))
831 if (!MO.isReg() || MO.getReg() != DepReg || !MO.isImplicit())
833 if (CheckDef == MO.isDef())
844 if (HII->isDotNewInst(
MI) && !HII->mayBeNewStore(
MI))
873 if (RC == &Hexagon::PredRegsRegClass)
874 return HII->predCanBeUsedAsDotNew(PI, DepReg);
876 if (RC != &Hexagon::PredRegsRegClass && !HII->mayBeNewStore(
MI))
881 int NewOpcode = (RC != &Hexagon::PredRegsRegClass) ? HII->getDotNewOp(
MI) :
882 HII->getDotNewPredOp(
MI,
MBPI);
885 bool ResourcesAvailable =
ResourceTracker->canReserveResources(*NewMI);
886 MF.deleteMachineInstr(NewMI);
887 if (!ResourcesAvailable)
916 if (!HII->isPredicated(*
I))
925 if (PacketSU->
isSucc(PacketSUDep)) {
926 for (
unsigned i = 0; i < PacketSU->
Succs.size(); ++i) {
927 auto &Dep = PacketSU->
Succs[i];
928 if (Dep.getSUnit() == PacketSUDep && Dep.getKind() ==
SDep::Anti &&
929 Dep.getReg() == DepReg)
945 for (
auto &
Op :
MI.operands()) {
946 if (
Op.isReg() &&
Op.getReg() &&
Op.isUse() &&
947 Hexagon::PredRegsRegClass.contains(
Op.getReg()))
989 if (PacketSU->
isSucc(SU)) {
990 for (
unsigned i = 0; i < PacketSU->
Succs.size(); ++i) {
991 auto Dep = PacketSU->
Succs[i];
996 if (Dep.getSUnit() == SU && Dep.getKind() ==
SDep::Data &&
997 Hexagon::PredRegsRegClass.contains(Dep.getReg())) {
1016 return PReg1 == PReg2 &&
1017 Hexagon::PredRegsRegClass.contains(PReg1) &&
1018 Hexagon::PredRegsRegClass.contains(PReg2) &&
1020 HII->isDotNewInst(MI1) == HII->isDotNewInst(MI2);
1026 PromotedToDotNew =
false;
1027 GlueToNewValueJump =
false;
1028 GlueAllocframeStore =
false;
1029 FoundSequentialDependence =
false;
1036 if (
MI.isDebugInstr())
1039 if (
MI.isCFIInstruction())
1043 if (
MI.isInlineAsm())
1046 if (
MI.isImplicitDef())
1053 return !IS->getUnits();
1061 if (
MI.isEHLabel() ||
MI.isCFIInstruction())
1075 if (HII->isSolo(
MI))
1078 if (
MI.getOpcode() == Hexagon::PATCHABLE_FUNCTION_ENTER ||
1079 MI.getOpcode() == Hexagon::PATCHABLE_FUNCTION_EXIT ||
1080 MI.getOpcode() == Hexagon::PATCHABLE_TAIL_CALL)
1083 if (
MI.getOpcode() == Hexagon::A2_nop)
1112 if (
MI.isInlineAsm())
1120 switch (
MI.getOpcode()) {
1121 case Hexagon::S2_storew_locked:
1122 case Hexagon::S4_stored_locked:
1123 case Hexagon::L2_loadw_locked:
1124 case Hexagon::L4_loadd_locked:
1125 case Hexagon::Y2_dccleana:
1126 case Hexagon::Y2_dccleaninva:
1127 case Hexagon::Y2_dcinva:
1128 case Hexagon::Y2_dczeroa:
1129 case Hexagon::Y4_l2fetch:
1130 case Hexagon::Y5_l2fetch: {
1134 unsigned TJ = HII.
getType(MJ);
1157 for (
auto &
B :
MF) {
1161 BundleIt =
MI.getIterator();
1162 if (!
MI.isInsideBundle())
1171 bool InsertBeforeBundle;
1172 if (
MI.isInlineAsm())
1174 else if (
MI.isDebugInstr())
1175 InsertBeforeBundle =
true;
1186 unsigned Opc =
MI.getOpcode();
1188 case Hexagon::Y2_barrier:
1189 case Hexagon::Y2_dcfetchbo:
1190 case Hexagon::Y4_l2fetch:
1191 case Hexagon::Y5_l2fetch:
1204 if (HII->isPredicated(
I) || HII->isPredicated(J))
1207 BitVector DeadDefs(Hexagon::NUM_TARGET_REGS);
1208 for (
auto &MO :
I.operands()) {
1209 if (!MO.isReg() || !MO.isDef() || !MO.isDead())
1211 DeadDefs[MO.getReg()] =
true;
1215 if (!MO.isReg() || !MO.isDef() || !MO.isDead())
1218 if (R != Hexagon::USR_OVF && DeadDefs[R])
1228 if ((HII->isSaveCalleeSavedRegsCall(
I) &&
1230 (HII->isSaveCalleeSavedRegsCall(J) &&
1242 if (
MI.isCall() || HII->isDeallocRet(
MI) || HII->isNewValueJump(
MI))
1244 if (HII->isPredicated(
MI) && HII->isPredicatedNew(
MI) && HII->isJumpR(
MI))
1249 if (HII->isLoopN(
I) && isBadForLoopN(J))
1251 if (HII->isLoopN(J) && isBadForLoopN(
I))
1256 return HII->isDeallocRet(
I) &&
1274 if (!OpJ.isRegMask())
1276 assert((J.
isCall() || HII->isTailCall(J)) &&
"Regmask on a non-call");
1279 if (OpJ.clobbersPhysReg(OpI.getReg()))
1281 }
else if (OpI.isRegMask()) {
1293 bool StoreI =
I.mayStore(), StoreJ = J.
mayStore();
1294 if ((SysI && StoreJ) || (SysJ && StoreI))
1297 if (StoreI && StoreJ) {
1298 if (HII->isNewValueInst(J) || HII->isMemOp(J) || HII->isMemOp(
I))
1303 bool MopStI = HII->isMemOp(
I) || StoreI;
1304 bool MopStJ = HII->isMemOp(J) || StoreJ;
1305 if (MopStI && MopStJ)
1309 return (StoreJ && HII->isDeallocRet(
I)) || (StoreI && HII->isDeallocRet(J));
1322 IgnoreDepMIs.clear();
1354 if (NextMII !=
I.getParent()->end() && HII->isNewValueJump(*NextMII)) {
1357 bool secondRegMatch =
false;
1361 if (NOp1.
isReg() &&
I.getOperand(0).getReg() == NOp1.
getReg())
1362 secondRegMatch =
true;
1378 if (PI->getOpcode() == Hexagon::S2_allocframe || PI->mayStore() ||
1379 HII->isLoopN(*PI)) {
1385 if (OpR.
isReg() && PI->modifiesRegister(OpR.
getReg(), HRI)) {
1391 GlueToNewValueJump =
true;
1400 for (
unsigned i = 0; i < SUJ->
Succs.size(); ++i) {
1401 if (FoundSequentialDependence)
1404 if (SUJ->
Succs[i].getSUnit() != SUI)
1423 unsigned DepReg = 0;
1426 DepReg = SUJ->
Succs[i].getReg();
1427 RC = HRI->getMinimalPhysRegClass(DepReg);
1430 if (
I.isCall() || HII->isJumpR(
I) ||
I.isReturn() || HII->isTailCall(
I)) {
1444 if (DepType ==
SDep::Data && HII->isDotCurInst(J)) {
1445 if (HII->isHVXVec(
I))
1453 PromotedToDotNew =
true;
1455 FoundSequentialDependence =
true;
1459 if (HII->isNewValueJump(
I))
1465 if (HII->isPredicated(
I) && HII->isPredicated(J) &&
1479 auto Itr =
find(IgnoreDepMIs, &J);
1480 if (Itr != IgnoreDepMIs.end()) {
1484 IgnoreDepMIs.push_back(&
I);
1496 if (
I.isConditionalBranch() && DepType !=
SDep::Data &&
1501 FoundSequentialDependence =
true;
1515 FoundSequentialDependence =
true;
1521 bool LoadI =
I.mayLoad(), StoreI =
I.mayStore();
1522 bool NVStoreJ = HII->isNewValueStore(J);
1523 bool NVStoreI = HII->isNewValueStore(
I);
1524 bool IsVecJ = HII->isHVXVec(J);
1525 bool IsVecI = HII->isHVXVec(
I);
1529 if (LoadJ && LoadI && HII->isPureSlot0(J)) {
1530 FoundSequentialDependence =
true;
1535 ((LoadJ && StoreI && !NVStoreI) ||
1536 (StoreJ && LoadI && !NVStoreJ)) &&
1537 (J.
getOpcode() != Hexagon::S2_allocframe &&
1538 I.getOpcode() != Hexagon::S2_allocframe) &&
1539 (J.
getOpcode() != Hexagon::L2_deallocframe &&
1540 I.getOpcode() != Hexagon::L2_deallocframe) &&
1541 (!HII->isMemOp(J) && !HII->isMemOp(
I)) && (!IsVecJ && !IsVecI))
1544 if (StoreJ && LoadI &&
alias(J,
I)) {
1545 FoundSequentialDependence =
true;
1550 if (!LoadJ || (!LoadI && !StoreI)) {
1553 FoundSequentialDependence =
true;
1568 unsigned Opc =
I.getOpcode();
1570 case Hexagon::S2_storerd_io:
1571 case Hexagon::S2_storeri_io:
1572 case Hexagon::S2_storerh_io:
1573 case Hexagon::S2_storerb_io:
1574 if (
I.getOperand(0).getReg() == HRI->getStackRegister()) {
1580 if (GlueAllocframeStore)
1600 if (
Op.isReg() &&
Op.isDef()) {
1604 }
else if (!
Op.isRegMask()) {
1608 FoundSequentialDependence =
true;
1620 FoundSequentialDependence =
true;
1625 if (FoundSequentialDependence) {
1640 if (Coexist && !Dependence)
1645 if (PromotedToDotNew)
1652 if (GlueAllocframeStore) {
1654 GlueAllocframeStore =
false;
1660 if (GlueToNewValueJump) {
1663 GlueToNewValueJump =
false;
1671 FoundSequentialDependence =
false;
1681 bool FoundLoad =
false;
1682 bool FoundStore =
false;
1685 unsigned Opc = MJ->getOpcode();
1686 if (
Opc == Hexagon::S2_allocframe ||
Opc == Hexagon::L2_deallocframe)
1688 if (HII->isMemOp(*MJ))
1692 if (MJ->mayStore() && !HII->isNewValueStore(*MJ))
1695 return FoundLoad && FoundStore;
1705 PacketStalls =
false;
1706 PacketStallCycles = 0;
1709 PacketStallCycles = std::max(PacketStallCycles,
calcStall(
MI));
1711 if (
MI.isImplicitDef()) {
1719 bool ExtMI = HII->isExtended(
MI) || HII->isConstExtended(
MI);
1722 if (GlueToNewValueJump) {
1732 bool ExtNvjMI = HII->isExtended(NvjMI) || HII->isConstExtended(NvjMI);
1739 if (Good && ExtNvjMI)
1765 if (PromotedToDotNew)
1767 if (GlueAllocframeStore) {
1769 GlueAllocframeStore =
false;
1784 dbgs() <<
"Finalizing packet:\n";
1800 OldPacketMIs.clear();
1803 for (
auto &
I :
make_range(HII->expandVGatherPseudo(*
MI), NextMI))
1804 OldPacketMIs.push_back(&
I);
1808 if (OldPacketMIs.size() > 1) {
1812 auto BundleMII = std::prev(FirstMI);
1813 if (memShufDisabled)
1814 HII->setBundleNoShuf(BundleMII);
1819 PacketHasDuplex =
false;
1820 PacketHasSLOT0OnlyInsn =
false;
1846 PacketHasSLOT0OnlyInsn |= HII->isPureSlot0(*MJ);
1848 int Opcode = HII->getDuplexOpcode(
MI,
false);
1852 if (HII->isDuplexPair(
MI, *MJ) && !PacketHasSLOT0OnlyInsn) {
1853 PacketHasDuplex =
true;
1860 MIRef.
setDesc(HII->get(Opcode));
1877 if (!OldPacketMIs.empty()) {
1878 auto *OldBB = OldPacketMIs.front()->getParent();
1879 auto *ThisBB =
I.getParent();
1880 if (
MLI->getLoopFor(OldBB) !=
MLI->getLoopFor(ThisBB))
1911 for (
auto &Pred : SUI->
Preds)
1912 if (Pred.getSUnit() == SUJ)
1913 if ((Pred.getLatency() == 0 && Pred.isAssignedRegDep()) ||
1914 HII->isNewValueJump(
I) || HII->isToBeScheduledASAP(*J,
I))
1920 for (
auto *J : OldPacketMIs) {
1922 for (
auto &Pred : SUI->
Preds)
1923 if (Pred.getSUnit() == SUJ && Pred.getLatency() > 1)
1924 return Pred.getLatency();
1936 return Latency > PacketStallCycles;
1945 return new HexagonPacketizer(Minimal);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements the BitVector class.
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file defines the DenseSet and SmallDenseSet classes.
cl::opt< bool > ScheduleInlineAsm("hexagon-sched-inline-asm", cl::Hidden, cl::init(false), cl::desc("Do not consider inline-asm a scheduling/" "packetization boundary."))
#define HEXAGON_LRFP_SIZE
cl::opt< bool > DisablePacketizer
static bool cannotCoexistAsymm(const MachineInstr &MI, const MachineInstr &MJ, const HexagonInstrInfo &HII)
static bool isDirectJump(const MachineInstr &MI)
static MachineBasicBlock::iterator moveInstrOut(MachineInstr &MI, MachineBasicBlock::iterator BundleIt, bool Before)
static bool isRegDependence(const SDep::Kind DepType)
static const MachineOperand & getStoreValueOperand(const MachineInstr &MI)
static cl::opt< bool > EnableGenAllInsnClass("enable-gen-insn", cl::Hidden, cl::desc("Generate all instruction with TC"))
static bool isControlFlow(const MachineInstr &MI)
static cl::opt< bool > DisableVecDblNVStores("disable-vecdbl-nv-stores", cl::Hidden, cl::desc("Disable vector double new-value-stores"))
static PredicateKind getPredicateSense(const MachineInstr &MI, const HexagonInstrInfo *HII)
Returns true if an instruction is predicated on p0 and false if it's predicated on !...
static unsigned getPredicatedRegister(MachineInstr &MI, const HexagonInstrInfo *QII)
Gets the predicate register of a predicated instruction.
cl::opt< bool > DisablePacketizer("disable-packetizer", cl::Hidden, cl::desc("Disable Hexagon packetizer pass"))
static cl::opt< bool > Slot1Store("slot1-store-slot0-load", cl::Hidden, cl::init(true), cl::desc("Allow slot1 store and slot0 load"))
static cl::opt< bool > PacketizeVolatiles("hexagon-packetize-volatiles", cl::Hidden, cl::init(true), cl::desc("Allow non-solo packetization of volatile memory references"))
static bool hasWriteToReadDep(const MachineInstr &FirstI, const MachineInstr &SecondI, const TargetRegisterInfo *TRI)
static bool doesModifyCalleeSavedReg(const MachineInstr &MI, const TargetRegisterInfo *TRI)
Returns true if the instruction modifies a callee-saved register.
static bool isLoadAbsSet(const MachineInstr &MI)
static const MachineOperand & getAbsSetOperand(const MachineInstr &MI)
static const MachineOperand & getPostIncrementOperand(const MachineInstr &MI, const HexagonInstrInfo *HII)
static bool isImplicitDependency(const MachineInstr &I, bool CheckDef, unsigned DepReg)
static bool isSchedBarrier(const MachineInstr &MI)
static bool isSystemInstr(const MachineInstr &MI)
Register const TargetRegisterInfo * TRI
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
uint64_t IntrinsicInst * II
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Implements a dense probed hash-table based set.
FunctionPass class - This class is used to implement most global optimizations.
bool isPredicated(const MachineInstr &MI) const override
Returns true if the instruction is already predicated.
bool isHVXMemWithAIndirect(const MachineInstr &I, const MachineInstr &J) const
bool isRestrictNoSlot1Store(const MachineInstr &MI) const
bool isPureSlot0(const MachineInstr &MI) const
bool isPostIncrement(const MachineInstr &MI) const override
Return true for post-incremented instructions.
uint64_t getType(const MachineInstr &MI) const
bool isPredicatedTrue(const MachineInstr &MI) const
bool isNewValueStore(const MachineInstr &MI) const
bool arePredicatesComplements(MachineInstr &MI1, MachineInstr &MI2)
bool updateOffset(SUnit *SUI, SUnit *SUJ)
Return true if we can update the offset in MI so that MI and MJ can be packetized together.
void endPacket(MachineBasicBlock *MBB, MachineBasicBlock::iterator MI) override
bool getmemShufDisabled()
HexagonPacketizerList(MachineFunction &MF, MachineLoopInfo &MLI, AAResults *AA, const MachineBranchProbabilityInfo *MBPI, bool Minimal)
bool isCallDependent(const MachineInstr &MI, SDep::Kind DepType, unsigned DepReg)
bool promoteToDotCur(MachineInstr &MI, SDep::Kind DepType, MachineBasicBlock::iterator &MII, const TargetRegisterClass *RC)
bool promoteToDotNew(MachineInstr &MI, SDep::Kind DepType, MachineBasicBlock::iterator &MII, const TargetRegisterClass *RC)
bool isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) override
bool canPromoteToDotCur(const MachineInstr &MI, const SUnit *PacketSU, unsigned DepReg, MachineBasicBlock::iterator &MII, const TargetRegisterClass *RC)
void useCalleesSP(MachineInstr &MI)
bool demoteToDotOld(MachineInstr &MI)
bool cannotCoexist(const MachineInstr &MI, const MachineInstr &MJ)
const MachineLoopInfo * MLI
bool isSoloInstruction(const MachineInstr &MI) override
bool isLegalToPruneDependencies(SUnit *SUI, SUnit *SUJ) override
void initPacketizerState() override
bool hasControlDependence(const MachineInstr &I, const MachineInstr &J)
bool restrictingDepExistInPacket(MachineInstr &, unsigned)
bool producesStall(const MachineInstr &MI)
void undoChangedOffset(MachineInstr &MI)
Undo the changed offset.
bool hasDualStoreDependence(const MachineInstr &I, const MachineInstr &J)
unsigned int calcStall(const MachineInstr &MI)
bool canPromoteToDotNew(const MachineInstr &MI, const SUnit *PacketSU, unsigned DepReg, MachineBasicBlock::iterator &MII, const TargetRegisterClass *RC)
bool canPromoteToNewValue(const MachineInstr &MI, const SUnit *PacketSU, unsigned DepReg, MachineBasicBlock::iterator &MII)
bool ignorePseudoInstruction(const MachineInstr &MI, const MachineBasicBlock *MBB) override
void unpacketizeSoloInstrs(MachineFunction &MF)
const MachineBranchProbabilityInfo * MBPI
A handle to the branch probability pass.
bool shouldAddToPacket(const MachineInstr &MI) override
bool canReserveResourcesForConstExt()
bool useCallersSP(MachineInstr &MI)
bool canPromoteToNewValueStore(const MachineInstr &MI, const MachineInstr &PacketMI, unsigned DepReg)
bool tryAllocateResourcesForConstExt(bool Reserve)
void setmemShufDisabled(bool val)
void reserveResourcesForConstExt()
MachineBasicBlock::iterator addToPacket(MachineInstr &MI) override
bool hasDeadDependence(const MachineInstr &I, const MachineInstr &J)
bool isNewifiable(const MachineInstr &MI, const TargetRegisterClass *NewRC)
bool hasRegMaskDependence(const MachineInstr &I, const MachineInstr &J)
const HexagonInstrInfo * getInstrInfo() const override
const HexagonRegisterInfo * getRegisterInfo() const override
bool hasV60OpsOnly() const
Describe properties that are true of each instruction in the target description file.
unsigned getSchedClass() const
Return the scheduling class for this instruction.
Instructions::iterator instr_iterator
Instructions::const_iterator const_instr_iterator
MachineInstrBundleIterator< MachineInstr > iterator
Analysis pass which computes a MachineDominatorTree.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineFunctionProperties & getProperties() const
Get the function properties.
instr_iterator getInstrIterator() const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool isTerminator(QueryType Type=AnyInBundle) const
Returns true if this instruction part of the terminator for a basic block.
bool isImplicitDef() const
bool readsRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr reads the specified register.
bool isBarrier(QueryType Type=AnyInBundle) const
Returns true if the specified instruction stops control flow from executing the instruction immediate...
bool isCall(QueryType Type=AnyInBundle) const
bool isBranch(QueryType Type=AnyInBundle) const
Returns true if this is a conditional, unconditional, or indirect branch.
bool modifiesRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr modifies (fully define or partially define) the specified register.
LLVM_ABI void unbundleFromPred()
Break bundle above this instruction.
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
LLVM_ABI void setDesc(const MCInstrDesc &TID)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one.
LLVM_ABI bool hasOrderedMemoryRef() const
Return true if this instruction may have an ordered or volatile memory reference, or if the informati...
bool mayStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly modify memory.
bool isBundledWithSucc() const
Return true if this instruction is part of a bundle, and it is not the last instruction in the bundle...
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Register getReg() const
getReg - Returns the register number.
Wrapper class representing virtual and physical registers.
Kind
These are the different kinds of scheduling dependencies.
@ Output
A register output-dependence (aka WAW).
@ Order
Any other ordering dependency.
@ Anti
A register anti-dependence (aka WAR).
@ Data
Regular data dependence (aka true-dependence).
Scheduling unit. This is a node in the scheduling DAG.
bool isSucc(const SUnit *N) const
Tests if node N is a successor of this node.
SmallVector< SDep, 4 > Succs
All sunit successors.
SmallVector< SDep, 4 > Preds
All sunit predecessors.
MachineInstr * getInstr() const
Returns the representative MachineInstr for this SUnit.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
VLIWPacketizerList(MachineFunction &MF, MachineLoopInfo &MLI, AAResults *AA)
void addMutation(std::unique_ptr< ScheduleDAGMutation > Mutation)
bool alias(const MachineInstr &MI1, const MachineInstr &MI2, bool UseTBAA=true) const
std::vector< MachineInstr * > CurrentPacketMIs
std::map< MachineInstr *, SUnit * > MIToSUnit
DFAPacketizer * ResourceTracker
std::pair< iterator, bool > insert(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI void finalizeBundle(MachineBasicBlock &MBB, MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
finalizeBundle - Finalize a machine instruction bundle which includes a sequence of instructions star...
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
std::string utohexstr(uint64_t X, bool LowerCase=false, unsigned Width=0)
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
FunctionPass * createHexagonPacketizer(bool Minimal)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
DWARFExpression::Operation Op