71#define DEBUG_TYPE "machine-sink"
75 cl::desc(
"Split critical edges during machine sinking"),
80 cl::desc(
"Use block frequency info to find successors to sink"),
84 "machine-sink-split-probability-threshold",
86 "Percentage threshold for splitting single-instruction critical edge. "
87 "If the branch threshold is higher than this threshold, we allow "
88 "speculative execution of up to 1 instruction to avoid branching to "
89 "splitted critical edge"),
93 "machine-sink-load-instrs-threshold",
94 cl::desc(
"Do not try to find alias store for a load if there is a in-path "
95 "block whose instruction number is higher than this threshold."),
99 "machine-sink-load-blocks-threshold",
100 cl::desc(
"Do not try to find alias store for a load if the block number in "
101 "the straight line is higher than this threshold."),
106 cl::desc(
"Sink instructions into cycles to avoid "
111 "machine-sink-cycle-limit",
113 "The maximum number of instructions considered for cycle sinking."),
116STATISTIC(NumSunk,
"Number of machine instructions sunk");
117STATISTIC(NumCycleSunk,
"Number of machine instructions sunk into a cycle");
120STATISTIC(NumPostRACopySink,
"Number of copies sunk after RA");
126class MachineSinking {
164 using AllSuccsCache =
178 using SinkItem = std::pair<MachineInstr *, MachineBasicBlock *>;
197 CachedRegisterPressure;
199 bool EnableSinkAndFold;
208 : DT(DT), PDT(PDT), CI(CI), PSI(PSI), MBFI(MBFI), MBPI(MBPI),
AA(
AA),
209 LIS(LIS),
SI(
SI), LV(LV), MLI(MLI),
210 EnableSinkAndFold(EnableSinkAndFold) {}
214 void releaseMemory() {
215 CEBCandidates.
clear();
216 CEMergeCandidates.
clear();
246 AllSuccsCache &AllSuccessors);
256 bool &LocalUse)
const;
259 AllSuccsCache &AllSuccessors);
271 AllSuccsCache &AllSuccessors);
280 AllSuccsCache &AllSuccessors)
const;
283 bool UseCache =
true);
285 bool registerPressureSetExceedsLimit(
unsigned NRegs,
320char MachineSinkingLegacy::ID = 0;
345 if (!TII->isBasicBlockPrologue(*PI))
347 for (auto &MO : MI.operands()) {
350 Register Reg = MO.getReg();
354 if (Reg.isPhysical() &&
355 (TII->isIgnorableUse(MO) || (MRI && MRI->isConstantPhysReg(Reg))))
357 if (PI->modifiesRegister(Reg, TRI))
360 if (PI->readsRegister(Reg, TRI))
363 auto *DefOp = PI->findRegisterDefOperand(Reg, TRI, false, true);
364 if (DefOp && !DefOp->isDead())
373bool MachineSinking::PerformTrivialForwardCoalescing(
MachineInstr &
MI,
381 !
MRI->hasOneNonDBGUse(SrcReg))
384 const TargetRegisterClass *SRC =
MRI->getRegClass(SrcReg);
385 const TargetRegisterClass *DRC =
MRI->getRegClass(DstReg);
389 MachineInstr *
DefMI =
MRI->getVRegDef(SrcReg);
394 MRI->replaceRegWith(DstReg, SrcReg);
395 MI.eraseFromParent();
399 MRI->clearKillFlags(SrcReg);
405bool MachineSinking::PerformSinkAndFold(MachineInstr &
MI,
406 MachineBasicBlock *
MBB) {
407 if (
MI.isCopy() ||
MI.mayLoadOrStore() ||
408 MI.getOpcode() == TargetOpcode::REG_SEQUENCE)
416 bool SawStore =
true;
417 if (!
MI.isSafeToMove(SawStore))
422 if (
MI.isConvergent())
431 for (
const MachineOperand &MO :
MI.operands()) {
432 if (MO.isImm() || MO.isRegMask() || MO.isRegLiveOut() || MO.isMetadata() ||
433 MO.isMCSymbol() || MO.isDbgInstrRef() || MO.isCFIIndex() ||
434 MO.isIntrinsicID() || MO.isPredicate() || MO.isShuffleMask())
453 else if (UsedRegB == 0)
461 (
MRI->isConstantPhysReg(
Reg) ||
TII->isIgnorableUse(MO)))
471 using SinkInfo = std::pair<MachineInstr *, ExtAddrMode>;
475 const TargetRegisterClass *RC =
MRI->getRegClass(DefReg);
476 const TargetRegisterClass *RCA =
477 UsedRegA == 0 ? nullptr :
MRI->getRegClass(UsedRegA);
478 const TargetRegisterClass *RCB =
479 UsedRegB == 0 ? nullptr :
MRI->getRegClass(UsedRegB);
482 while (!Worklist.
empty()) {
485 for (MachineOperand &MO :
MRI->use_nodbg_operands(
Reg)) {
487 MachineInstr &UseInst = *MO.getParent();
490 if (
const MachineOperand &O = UseInst.
getOperand(0);
O.isReg())
508 if (!
TII->canFoldIntoAddrMode(UseInst,
Reg,
MI, AM))
519 const TargetRegisterClass *RCS =
MRI->getRegClass(
Reg);
525 if (RCA ==
nullptr) {
530 unsigned NRegs = !!RCA + !!RCB;
536 if (RCB ==
nullptr) {
537 if (registerPressureSetExceedsLimit(NRegs, RCA,
MBB))
539 }
else if (registerPressureSetExceedsLimit(1, RCA,
MBB) ||
540 registerPressureSetExceedsLimit(1, RCB,
MBB)) {
550 if (SinkInto.
empty())
554 for (
auto &[SinkDst, MaybeAM] : SinkInto) {
555 MachineInstr *
New =
nullptr;
558 if (SinkDst->isCopy()) {
571 Register DstReg = SinkDst->getOperand(0).getReg();
572 TII->reMaterialize(*SinkDst->getParent(), InsertPt, DstReg, 0,
MI);
573 New = &*std::prev(InsertPt);
574 if (!
New->getDebugLoc())
575 New->setDebugLoc(SinkDst->getDebugLoc());
581 MRI->clearKillFlags(UsedRegA);
583 MRI->clearKillFlags(UsedRegB);
586 New =
TII->emitLdStWithAddr(*SinkDst, MaybeAM);
592 MRI->clearKillFlags(R);
594 MRI->clearKillFlags(R);
598 if (SinkDst->mayStore() && !SinkDst->hasOrderedMemoryRef())
599 StoreInstrCache.clear();
600 SinkDst->eraseFromParent();
608 while (!Worklist.
empty()) {
610 for (MachineOperand &MO :
MRI->use_operands(
Reg)) {
611 MachineInstr *
U = MO.getParent();
612 assert((
U->isCopy() ||
U->isDebugInstr()) &&
613 "Only debug uses and copies must remain");
615 Worklist.
push_back(
U->getOperand(0).getReg());
621 for (MachineOperand *MO :
Cleanup) {
622 MachineInstr *
I = MO->getParent();
624 I->eraseFromParent();
631 MI.eraseFromParent();
639bool MachineSinking::AllUsesDominatedByBlock(
Register Reg,
640 MachineBasicBlock *
MBB,
641 MachineBasicBlock *DefMBB,
643 bool &LocalUse)
const {
647 if (
MRI->use_nodbg_empty(
Reg))
664 if (
all_of(
MRI->use_nodbg_operands(
Reg), [&](MachineOperand &MO) {
665 MachineInstr *UseInst = MO.getParent();
666 unsigned OpNo = MO.getOperandNo();
667 MachineBasicBlock *UseBlock = UseInst->getParent();
668 return UseBlock == MBB && UseInst->isPHI() &&
669 UseInst->getOperand(OpNo + 1).getMBB() == DefMBB;
675 for (MachineOperand &MO :
MRI->use_nodbg_operands(
Reg)) {
678 unsigned OpNo = &MO - &UseInst->
getOperand(0);
679 MachineBasicBlock *UseBlock = UseInst->
getParent();
680 if (UseInst->
isPHI()) {
684 }
else if (UseBlock == DefMBB) {
700 assert(
MI.mayLoad() &&
"Expected MI that loads!");
704 if (
MI.memoperands_empty())
709 if (PSV->isGOT() || PSV->isConstantPool())
715void MachineSinking::FindCycleSinkCandidates(
717 SmallVectorImpl<MachineInstr *> &Candidates) {
718 for (
auto &
MI : *BB) {
720 if (
MI.isMetaInstruction()) {
721 LLVM_DEBUG(
dbgs() <<
"CycleSink: not sinking meta instruction\n");
725 LLVM_DEBUG(
dbgs() <<
"CycleSink: Instruction not a candidate for this "
730 LLVM_DEBUG(
dbgs() <<
"CycleSink: Instruction is not cycle invariant\n");
733 bool DontMoveAcrossStore =
true;
734 if (!
MI.isSafeToMove(DontMoveAcrossStore)) {
735 LLVM_DEBUG(
dbgs() <<
"CycleSink: Instruction not safe to move.\n");
739 LLVM_DEBUG(
dbgs() <<
"CycleSink: Dont sink GOT or constant pool loads\n");
742 if (
MI.isConvergent())
745 const MachineOperand &MO =
MI.getOperand(0);
751 LLVM_DEBUG(
dbgs() <<
"CycleSink: Instruction added as candidate.\n");
763 .getCachedResult<ProfileSummaryAnalysis>(
776 MachineSinking Impl(EnableSinkAndFold, DT, PDT, LV, MLI,
SI, LIS, CI, PSI,
791 OS << MapClassName2PassName(
name());
792 if (EnableSinkAndFold)
793 OS <<
"<enable-sink-fold>";
803 auto *DT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
805 &getAnalysis<MachinePostDominatorTreeWrapperPass>().getPostDomTree();
806 auto *CI = &getAnalysis<MachineCycleInfoWrapperPass>().getCycleInfo();
807 auto *PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
810 ? &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI()
813 &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
814 auto *
AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
816 auto *LISWrapper = getAnalysisIfAvailable<LiveIntervalsWrapperPass>();
817 auto *LIS = LISWrapper ? &LISWrapper->getLIS() :
nullptr;
818 auto *SIWrapper = getAnalysisIfAvailable<SlotIndexesWrapperPass>();
819 auto *
SI = SIWrapper ? &SIWrapper->getSI() :
nullptr;
820 auto *LVWrapper = getAnalysisIfAvailable<LiveVariablesWrapperPass>();
821 auto *LV = LVWrapper ? &LVWrapper->getLV() :
nullptr;
822 auto *MLIWrapper = getAnalysisIfAvailable<MachineLoopInfoWrapperPass>();
823 auto *MLI = MLIWrapper ? &MLIWrapper->getLI() :
nullptr;
825 MachineSinking Impl(EnableSinkAndFold, DT, PDT, LV, MLI,
SI, LIS, CI, PSI,
840 bool EverMadeChange =
false;
843 bool MadeChange =
false;
846 CEBCandidates.clear();
847 CEMergeCandidates.clear();
854 MachineDomTreeUpdater::UpdateStrategy::Lazy);
855 for (
const auto &Pair : ToSplit) {
856 auto NewSucc = Pair.first->SplitCriticalEdge(
857 Pair.second, {LIS, SI, LV, MLI},
nullptr, &MDTU);
858 if (NewSucc !=
nullptr) {
875 EverMadeChange =
true;
880 SchedModel.
init(STI);
881 bool HasHighPressure;
883 DenseMap<SinkItem, MachineInstr *> SunkInstrs;
885 enum CycleSinkStage { COPY, LOW_LATENCY, AGGRESSIVE, END };
886 for (
unsigned Stage = CycleSinkStage::COPY; Stage != CycleSinkStage::END;
887 ++Stage, SunkInstrs.
clear()) {
888 HasHighPressure =
false;
890 for (
auto *
Cycle : Cycles) {
896 SmallVector<MachineInstr *, 8> Candidates;
897 FindCycleSinkCandidates(
Cycle, Preheader, Candidates);
906 if (Stage == CycleSinkStage::COPY) {
909 <<
"CycleSink: Limit reached of instructions to "
920 if (Stage == CycleSinkStage::LOW_LATENCY &&
921 !
TII->hasLowDefLatency(SchedModel, *
I, 0))
924 if (!aggressivelySinkIntoCycle(
Cycle, *
I, SunkInstrs))
926 EverMadeChange =
true;
931 if (!HasHighPressure)
932 HasHighPressure = registerPressureExceedsLimit(*Preheader);
934 if (!HasHighPressure)
939 HasStoreCache.clear();
940 StoreInstrCache.clear();
943 for (
auto I : RegsToClearKillFlags)
944 MRI->clearKillFlags(
I);
945 RegsToClearKillFlags.clear();
948 return EverMadeChange;
951bool MachineSinking::ProcessBlock(MachineBasicBlock &
MBB) {
961 bool MadeChange =
false;
964 AllSuccsCache AllSuccessors;
969 bool ProcessedBegin, SawStore =
false;
971 MachineInstr &
MI = *
I;
979 if (
MI.isDebugOrPseudoInstr() ||
MI.isFakeUse()) {
980 if (
MI.isDebugValue())
985 if (EnableSinkAndFold && PerformSinkAndFold(
MI, &
MBB)) {
994 if (PerformTrivialForwardCoalescing(
MI, &
MBB)) {
1005 }
while (!ProcessedBegin);
1007 SeenDbgUsers.clear();
1008 SeenDbgVars.clear();
1010 CachedRegisterPressure.clear();
1014void MachineSinking::ProcessDbgInst(MachineInstr &
MI) {
1017 assert(
MI.isDebugValue() &&
"Expected DBG_VALUE for processing");
1019 DebugVariable Var(
MI.getDebugVariable(),
MI.getDebugExpression(),
1020 MI.getDebugLoc()->getInlinedAt());
1021 bool SeenBefore = SeenDbgVars.contains(Var);
1023 for (MachineOperand &MO :
MI.debug_operands()) {
1025 SeenDbgUsers[MO.
getReg()].push_back(SeenDbgUser(&
MI, SeenBefore));
1029 SeenDbgVars.insert(Var);
1032bool MachineSinking::isWorthBreakingCriticalEdge(
1033 MachineInstr &
MI, MachineBasicBlock *From, MachineBasicBlock *To,
1034 MachineBasicBlock *&DeferredFromBlock) {
1040 if (!CEBCandidates.insert(std::make_pair(From, To)).second)
1051 for (
const auto &MO :
MI.all_defs()) {
1056 auto Key = std::make_pair(SrcReg, To);
1057 auto Res = CEMergeCandidates.try_emplace(
Key, From);
1062 DeferredFromBlock = Res.first->second;
1075 for (
const MachineOperand &MO :
MI.all_uses()) {
1088 if (
MRI->hasOneNonDBGUse(
Reg)) {
1101 return TII->shouldBreakCriticalEdgeToSink(
MI);
1104bool MachineSinking::isLegalToBreakCriticalEdge(MachineInstr &
MI,
1105 MachineBasicBlock *FromBB,
1106 MachineBasicBlock *ToBB,
1107 bool BreakPHIEdge) {
1116 if (FromCycle == ToCycle && FromCycle &&
1159 if (!BreakPHIEdge) {
1161 if (Pred != FromBB && !DT->
dominates(ToBB, Pred))
1168bool MachineSinking::PostponeSplitCriticalEdge(MachineInstr &
MI,
1169 MachineBasicBlock *FromBB,
1170 MachineBasicBlock *ToBB,
1171 bool BreakPHIEdge) {
1172 bool Status =
false;
1173 MachineBasicBlock *DeferredFromBB =
nullptr;
1174 if (isWorthBreakingCriticalEdge(
MI, FromBB, ToBB, DeferredFromBB)) {
1177 if ((!DeferredFromBB ||
1178 ToSplit.count(std::make_pair(DeferredFromBB, ToBB)) ||
1179 isLegalToBreakCriticalEdge(
MI, DeferredFromBB, ToBB, BreakPHIEdge)) &&
1180 isLegalToBreakCriticalEdge(
MI, FromBB, ToBB, BreakPHIEdge)) {
1181 ToSplit.insert(std::make_pair(FromBB, ToBB));
1183 ToSplit.insert(std::make_pair(DeferredFromBB, ToBB));
1191std::vector<unsigned> &
1192MachineSinking::getBBRegisterPressure(
const MachineBasicBlock &
MBB,
1199 auto RP = CachedRegisterPressure.find(&
MBB);
1200 if (UseCache && RP != CachedRegisterPressure.end())
1203 RegionPressure Pressure;
1204 RegPressureTracker RPTracker(Pressure);
1212 MII != MIE; --MII) {
1213 const MachineInstr &
MI = *std::prev(MII);
1214 if (
MI.isDebugOrPseudoInstr())
1216 RegisterOperands RegOpers;
1218 RPTracker.recedeSkipDebugValues();
1219 assert(&*RPTracker.getPos() == &
MI &&
"RPTracker sync error!");
1220 RPTracker.recede(RegOpers);
1223 RPTracker.closeRegion();
1225 if (RP != CachedRegisterPressure.end()) {
1226 CachedRegisterPressure[&
MBB] = RPTracker.getPressure().MaxSetPressure;
1227 return CachedRegisterPressure[&
MBB];
1230 auto It = CachedRegisterPressure.insert(
1231 std::make_pair(&
MBB, RPTracker.getPressure().MaxSetPressure));
1232 return It.first->second;
1235bool MachineSinking::registerPressureSetExceedsLimit(
1236 unsigned NRegs,
const TargetRegisterClass *RC,
1237 const MachineBasicBlock &
MBB) {
1238 unsigned Weight = NRegs *
TRI->getRegClassWeight(RC).RegWeight;
1239 const int *PS =
TRI->getRegClassPressureSets(RC);
1240 std::vector<unsigned> BBRegisterPressure = getBBRegisterPressure(
MBB);
1241 for (; *PS != -1; PS++)
1242 if (Weight + BBRegisterPressure[*PS] >=
1249bool MachineSinking::registerPressureExceedsLimit(
1250 const MachineBasicBlock &
MBB) {
1251 std::vector<unsigned> BBRegisterPressure = getBBRegisterPressure(
MBB,
false);
1253 for (
unsigned PS = 0; PS < BBRegisterPressure.size(); ++PS) {
1254 if (BBRegisterPressure[PS] >=
1264bool MachineSinking::isProfitableToSinkTo(
Register Reg, MachineInstr &
MI,
1265 MachineBasicBlock *
MBB,
1266 MachineBasicBlock *SuccToSinkTo,
1267 AllSuccsCache &AllSuccessors) {
1268 assert(SuccToSinkTo &&
"Invalid SinkTo Candidate BB");
1270 if (
MBB == SuccToSinkTo)
1283 bool NonPHIUse =
false;
1284 for (MachineInstr &UseInst :
MRI->use_nodbg_instructions(
Reg)) {
1285 MachineBasicBlock *UseBlock = UseInst.
getParent();
1286 if (UseBlock == SuccToSinkTo && !UseInst.
isPHI())
1294 bool BreakPHIEdge =
false;
1296 if (MachineBasicBlock *MBB2 =
1297 FindSuccToSinkTo(
MI, SuccToSinkTo, BreakPHIEdge, AllSuccessors))
1298 return isProfitableToSinkTo(
Reg,
MI, SuccToSinkTo, MBB2, AllSuccessors);
1309 for (
const MachineOperand &MO :
MI.operands()) {
1320 !
TII->isIgnorableUse(MO))
1328 bool LocalUse =
false;
1329 if (!AllUsesDominatedByBlock(
Reg, SuccToSinkTo,
MBB, BreakPHIEdge,
1347 if (registerPressureSetExceedsLimit(1,
MRI->getRegClass(
Reg),
1349 LLVM_DEBUG(
dbgs() <<
"register pressure exceed limit, not profitable.");
1363SmallVector<MachineBasicBlock *, 4> &
1364MachineSinking::GetAllSortedSuccessors(MachineInstr &
MI, MachineBasicBlock *
MBB,
1365 AllSuccsCache &AllSuccessors)
const {
1367 auto Succs = AllSuccessors.find(
MBB);
1368 if (Succs != AllSuccessors.end())
1369 return Succs->second;
1371 SmallVector<MachineBasicBlock *, 4> AllSuccs(
MBB->
successors());
1382 if (DTChild->getIDom()->getBlock() ==
MI.getParent() &&
1385 AllSuccs.push_back(DTChild->getBlock());
1390 AllSuccs, [&](
const MachineBasicBlock *L,
const MachineBasicBlock *R) {
1394 (!LHSFreq && !RHSFreq))
1396 return LHSFreq < RHSFreq;
1399 auto it = AllSuccessors.insert(std::make_pair(
MBB, AllSuccs));
1401 return it.first->second;
1406MachineSinking::FindSuccToSinkTo(MachineInstr &
MI, MachineBasicBlock *
MBB,
1408 AllSuccsCache &AllSuccessors) {
1409 assert(
MBB &&
"Invalid MachineBasicBlock!");
1416 MachineBasicBlock *SuccToSinkTo =
nullptr;
1417 for (
const MachineOperand &MO :
MI.operands()) {
1430 if (!
MRI->isConstantPhysReg(
Reg) && !
TII->isIgnorableUse(MO))
1432 }
else if (!MO.
isDead()) {
1442 if (!
TII->isSafeToMoveRegClassDefs(
MRI->getRegClass(
Reg)))
1450 bool LocalUse =
false;
1451 if (!AllUsesDominatedByBlock(
Reg, SuccToSinkTo,
MBB, BreakPHIEdge,
1462 for (MachineBasicBlock *SuccBlock :
1463 GetAllSortedSuccessors(
MI,
MBB, AllSuccessors)) {
1464 bool LocalUse =
false;
1465 if (AllUsesDominatedByBlock(
Reg, SuccBlock,
MBB, BreakPHIEdge,
1467 SuccToSinkTo = SuccBlock;
1478 if (!isProfitableToSinkTo(
Reg,
MI,
MBB, SuccToSinkTo, AllSuccessors))
1485 if (
MBB == SuccToSinkTo)
1490 if (SuccToSinkTo && SuccToSinkTo->
isEHPad())
1500 if (SuccToSinkTo && !
TII->isSafeToSink(
MI, SuccToSinkTo, CI))
1503 return SuccToSinkTo;
1518 auto *
MBB =
MI.getParent();
1519 if (
MBB->pred_size() != 1)
1522 auto *PredMBB = *
MBB->pred_begin();
1523 auto *PredBB = PredMBB->getBasicBlock();
1529 !PredBB->getTerminator()->getMetadata(LLVMContext::MD_make_implicit))
1534 bool OffsetIsScalable;
1535 if (!
TII->getMemOperandWithOffset(
MI, BaseOp,
Offset, OffsetIsScalable,
TRI))
1538 if (!BaseOp->
isReg())
1541 if (!(
MI.mayLoad() && !
MI.isPredicable()))
1544 MachineBranchPredicate MBP;
1545 if (
TII->analyzeBranchPredicate(*PredMBB, MBP,
false))
1548 return MBP.LHS.isReg() && MBP.RHS.isImm() && MBP.RHS.getImm() == 0 &&
1549 (MBP.Predicate == MachineBranchPredicate::PRED_NE ||
1550 MBP.Predicate == MachineBranchPredicate::PRED_EQ) &&
1551 MBP.LHS.getReg() == BaseOp->
getReg();
1568 auto CopyOperands =
TII.isCopyInstr(SinkInst);
1571 SrcMO = CopyOperands->Source;
1572 DstMO = CopyOperands->Destination;
1575 bool PostRA =
MRI.getNumVirtRegs() == 0;
1583 bool arePhysRegs = !
Reg.isVirtual();
1584 if (arePhysRegs != PostRA)
1591 if (DbgMO.getSubReg() != SrcMO->
getSubReg() ||
1592 DbgMO.getSubReg() != DstMO->getSubReg())
1598 if (PostRA &&
Reg != DstMO->getReg())
1602 DbgMO.setReg(SrcMO->
getReg());
1608using MIRegs = std::pair<MachineInstr *, SmallVector<Register, 2>>;
1616 if (!SuccToSinkTo.
empty() && InsertPos != SuccToSinkTo.
end())
1618 InsertPos->getDebugLoc()));
1624 SuccToSinkTo.
splice(InsertPos, ParentBlock,
MI,
1631 for (
const auto &DbgValueToSink : DbgValuesToSink) {
1634 SuccToSinkTo.
insert(InsertPos, NewDbgMI);
1636 bool PropagatedAllSunkOps =
true;
1640 PropagatedAllSunkOps =
false;
1645 if (!PropagatedAllSunkOps)
1652bool MachineSinking::hasStoreBetween(MachineBasicBlock *From,
1653 MachineBasicBlock *To, MachineInstr &
MI) {
1659 auto BlockPair = std::make_pair(From, To);
1663 if (
auto It = HasStoreCache.find(BlockPair); It != HasStoreCache.end())
1666 if (
auto It = StoreInstrCache.find(BlockPair); It != StoreInstrCache.end())
1668 return I->mayAlias(AA, MI, false);
1671 bool SawStore =
false;
1672 bool HasAliasedStore =
false;
1673 DenseSet<MachineBasicBlock *> HandledBlocks;
1674 DenseSet<MachineBasicBlock *> HandledDomBlocks;
1681 if (BB == To || BB == From)
1685 if (HandledBlocks.
count(BB))
1688 HandledBlocks.
insert(BB);
1691 if (!HandledDomBlocks.
count(BB))
1692 HandledDomBlocks.
insert(BB);
1698 for (
auto *DomBB : HandledDomBlocks) {
1699 if (DomBB != BB && DT->
dominates(DomBB, BB))
1700 HasStoreCache[std::make_pair(DomBB, To)] =
true;
1701 else if (DomBB != BB && DT->
dominates(BB, DomBB))
1702 HasStoreCache[std::make_pair(From, DomBB)] =
true;
1704 HasStoreCache[BlockPair] =
true;
1708 for (MachineInstr &
I : *BB) {
1711 if (
I.isCall() ||
I.hasOrderedMemoryRef()) {
1712 for (
auto *DomBB : HandledDomBlocks) {
1713 if (DomBB != BB && DT->
dominates(DomBB, BB))
1714 HasStoreCache[std::make_pair(DomBB, To)] =
true;
1715 else if (DomBB != BB && DT->
dominates(BB, DomBB))
1716 HasStoreCache[std::make_pair(From, DomBB)] =
true;
1718 HasStoreCache[BlockPair] =
true;
1728 if (
I.mayAlias(AA,
MI,
false))
1729 HasAliasedStore =
true;
1730 StoreInstrCache[BlockPair].push_back(&
I);
1737 HasStoreCache[BlockPair] =
false;
1738 return HasAliasedStore;
1746bool MachineSinking::aggressivelySinkIntoCycle(
1748 DenseMap<SinkItem, MachineInstr *> &SunkInstrs) {
1750 if (
I.getNumDefs() > 1)
1753 LLVM_DEBUG(
dbgs() <<
"AggressiveCycleSink: Finding sink block for: " <<
I);
1757 MachineOperand &DefMO =
I.getOperand(0);
1758 for (MachineInstr &
MI :
MRI->use_instructions(DefMO.
getReg())) {
1762 for (std::pair<RegSubRegPair, MachineInstr *> Entry :
Uses) {
1763 MachineInstr *
MI =
Entry.second;
1767 dbgs() <<
"AggressiveCycleSink: Not attempting to sink for PHI.\n");
1771 if (
MI->isPosition() ||
TII->isBasicBlockPrologue(*
MI)) {
1772 LLVM_DEBUG(
dbgs() <<
"AggressiveCycleSink: Use is BasicBlock prologue, "
1778 dbgs() <<
"AggressiveCycleSink: Use not in cycle, can't sink.\n");
1782 MachineBasicBlock *SinkBlock =
MI->getParent();
1783 MachineInstr *NewMI =
nullptr;
1784 SinkItem MapEntry(&
I, SinkBlock);
1786 auto SI = SunkInstrs.
find(MapEntry);
1790 if (SI != SunkInstrs.
end()) {
1791 LLVM_DEBUG(
dbgs() <<
"AggressiveCycleSink: Already sunk to block: "
1798 LLVM_DEBUG(
dbgs() <<
"AggressiveCycleSink: Sinking instruction to block: "
1801 NewMI =
I.
getMF()->CloneMachineInstr(&
I);
1803 const TargetRegisterClass *TRC =
MRI->getRegClass(DefMO.
getReg());
1804 Register DestReg =
MRI->createVirtualRegister(TRC);
1810 SunkInstrs.
insert({MapEntry, NewMI});
1814 for (MachineOperand &MO : NewMI->
all_uses()) {
1816 RegsToClearKillFlags.insert(MO.
getReg());
1831 I.eraseFromParent();
1837bool MachineSinking::SinkInstruction(MachineInstr &
MI,
bool &SawStore,
1838 AllSuccsCache &AllSuccessors) {
1844 if (!
MI.isSafeToMove(SawStore))
1849 if (
MI.isConvergent())
1865 bool BreakPHIEdge =
false;
1866 MachineBasicBlock *ParentBlock =
MI.getParent();
1867 MachineBasicBlock *SuccToSinkTo =
1868 FindSuccToSinkTo(
MI, ParentBlock, BreakPHIEdge, AllSuccessors);
1877 for (
const MachineOperand &MO :
MI.all_defs()) {
1885 LLVM_DEBUG(
dbgs() <<
"Sink instr " <<
MI <<
"\tinto block " << *SuccToSinkTo);
1892 bool TryBreak =
false;
1894 MI.mayLoad() ? hasStoreBetween(ParentBlock, SuccToSinkTo,
MI) :
true;
1895 if (!
MI.isSafeToMove(Store)) {
1896 LLVM_DEBUG(
dbgs() <<
" *** NOTE: Won't sink load along critical edge.\n");
1902 if (!TryBreak && !DT->
dominates(ParentBlock, SuccToSinkTo)) {
1908 if (!TryBreak && CI->
getCycle(SuccToSinkTo) &&
1922 bool Status = PostponeSplitCriticalEdge(
MI, ParentBlock, SuccToSinkTo,
1926 "break critical edge\n");
1937 PostponeSplitCriticalEdge(
MI, ParentBlock, SuccToSinkTo, BreakPHIEdge);
1940 "break critical edge\n");
1949 LLVM_DEBUG(
dbgs() <<
" *** Not sinking: prologue interference\n");
1955 for (
auto &MO :
MI.all_defs()) {
1958 auto It = SeenDbgUsers.find(MO.
getReg());
1959 if (It == SeenDbgUsers.end())
1963 auto &
Users = It->second;
1964 for (
auto &User :
Users) {
1965 MachineInstr *DbgMI =
User.getPointer();
1966 if (
User.getInt()) {
1981 if (
MI.getMF()->getFunction().getSubprogram() &&
MI.isCopy())
1982 SalvageUnsunkDebugUsersOfCopy(
MI, SuccToSinkTo);
1991 for (MachineOperand &MO :
MI.all_uses())
1992 RegsToClearKillFlags.insert(MO.
getReg());
1997void MachineSinking::SalvageUnsunkDebugUsersOfCopy(
1998 MachineInstr &
MI, MachineBasicBlock *TargetBlock) {
2005 SmallVector<MachineInstr *, 4> DbgDefUsers;
2007 const MachineRegisterInfo &
MRI =
MI.getMF()->getRegInfo();
2008 for (
auto &MO :
MI.all_defs()) {
2012 for (
auto &User :
MRI.use_instructions(MO.
getReg())) {
2017 if (
User.getParent() ==
MI.getParent())
2021 "DBG_VALUE user of vreg, but has no operand for it?");
2028 for (
auto *User : DbgDefUsers) {
2029 for (
auto &
Reg : DbgUseRegs) {
2030 for (
auto &DbgOp :
User->getDebugOperandsForReg(
Reg)) {
2031 DbgOp.setReg(
MI.getOperand(1).getReg());
2032 DbgOp.setSubReg(
MI.getOperand(1).getSubReg());
2074class PostRAMachineSinkingImpl {
2076 LiveRegUnits ModifiedRegUnits, UsedRegUnits;
2082 DenseMap<MCRegUnit, SmallVector<MIRegs, 2>> SeenDbgInstrs;
2086 bool tryToSinkCopy(MachineBasicBlock &BB, MachineFunction &MF,
2087 const TargetRegisterInfo *
TRI,
const TargetInstrInfo *
TII);
2090 bool run(MachineFunction &MF);
2093class PostRAMachineSinkingLegacy :
public MachineFunctionPass {
2095 bool runOnMachineFunction(MachineFunction &MF)
override;
2098 PostRAMachineSinkingLegacy() : MachineFunctionPass(
ID) {}
2099 StringRef getPassName()
const override {
return "PostRA Machine Sink"; }
2101 void getAnalysisUsage(AnalysisUsage &AU)
const override {
2106 MachineFunctionProperties getRequiredProperties()
const override {
2107 return MachineFunctionProperties().setNoVRegs();
2113char PostRAMachineSinkingLegacy::ID = 0;
2117 "PostRA Machine Sink",
false,
false)
2126static MachineBasicBlock *
2132 for (
auto *
SI : SinkableBBs) {
2133 if (aliasWithRegsInLiveIn(*
SI,
Reg,
TRI)) {
2153static MachineBasicBlock *
2159 for (
auto DefReg : DefedRegsInCopy) {
2162 if (!BB || (SingleBB && SingleBB != BB))
2173 for (
auto U : UsedOpsInCopy) {
2179 if (UI.killsRegister(SrcReg,
TRI)) {
2180 UI.clearRegisterKills(SrcReg,
TRI);
2192 for (
Register DefReg : DefedRegsInCopy)
2195 for (
auto U : UsedOpsInCopy)
2205 bool HasRegDependency =
false;
2206 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
2215 HasRegDependency =
true;
2224 }
else if (MO.
isUse()) {
2226 HasRegDependency =
true;
2232 return HasRegDependency;
2235bool PostRAMachineSinkingImpl::tryToSinkCopy(MachineBasicBlock &CurBB,
2236 MachineFunction &MF,
2237 const TargetRegisterInfo *
TRI,
2238 const TargetInstrInfo *
TII) {
2239 SmallPtrSet<MachineBasicBlock *, 2> SinkableBBs;
2243 for (MachineBasicBlock *SI : CurBB.
successors())
2244 if (!
SI->livein_empty() &&
SI->pred_size() == 1)
2247 if (SinkableBBs.
empty())
2254 ModifiedRegUnits.
clear();
2255 UsedRegUnits.
clear();
2256 SeenDbgInstrs.clear();
2260 SmallVector<unsigned, 2> UsedOpsInCopy;
2266 if (
MI.isDebugValue() && !
MI.isDebugRef()) {
2267 SmallDenseMap<MCRegUnit, SmallVector<Register, 2>, 4> MIUnits;
2268 bool IsValid =
true;
2269 for (MachineOperand &MO :
MI.debug_operands()) {
2274 ModifiedRegUnits, UsedRegUnits)) {
2280 for (MCRegUnit Unit :
TRI->regunits(MO.
getReg()))
2285 for (
auto &RegOps : MIUnits)
2286 SeenDbgInstrs[RegOps.first].emplace_back(&
MI,
2287 std::move(RegOps.second));
2293 if (!
TII->shouldPostRASink(
MI))
2296 if (
MI.isDebugOrPseudoInstr())
2303 if (!
MI.isCopy() || !
MI.getOperand(0).isRenamable()) {
2311 ModifiedRegUnits, UsedRegUnits)) {
2317 "Unexpect SrcReg or DefReg");
2318 MachineBasicBlock *SuccBB =
2328 "Unexpected predecessor");
2333 MapVector<MachineInstr *, MIRegs::second_type> DbgValsToSinkMap;
2334 for (
auto &MO :
MI.all_defs()) {
2335 for (MCRegUnit Unit :
TRI->regunits(MO.
getReg())) {
2336 for (
const auto &
MIRegs : SeenDbgInstrs.lookup(Unit)) {
2337 auto &Regs = DbgValsToSinkMap[
MIRegs.first];
2342 auto DbgValsToSink = DbgValsToSinkMap.
takeVector();
2351 LLVM_DEBUG(
dbgs() <<
" *** Not sinking: prologue interference\n");
2362 ++NumPostRACopySink;
2367bool PostRAMachineSinkingImpl::run(MachineFunction &MF) {
2380bool PostRAMachineSinkingLegacy::runOnMachineFunction(MachineFunction &MF) {
2384 return PostRAMachineSinkingImpl().run(MF);
2392 if (!PostRAMachineSinkingImpl().
run(MF))
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the DenseSet and SmallDenseSet classes.
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
static const HTTPClientCleanup Cleanup
static Register UseReg(const MachineOperand &MO)
const HexagonInstrInfo * TII
iv Induction Variable Users
static bool mayLoadFromGOTOrConstantPool(MachineInstr &MI)
Return true if this machine instruction loads from global offset table or constant pool.
static cl::opt< unsigned > SinkLoadInstsPerBlockThreshold("machine-sink-load-instrs-threshold", cl::desc("Do not try to find alias store for a load if there is a in-path " "block whose instruction number is higher than this threshold."), cl::init(2000), cl::Hidden)
static cl::opt< unsigned > SinkIntoCycleLimit("machine-sink-cycle-limit", cl::desc("The maximum number of instructions considered for cycle sinking."), cl::init(50), cl::Hidden)
TargetInstrInfo::RegSubRegPair RegSubRegPair
static void clearKillFlags(MachineInstr *MI, MachineBasicBlock &CurBB, const SmallVectorImpl< unsigned > &UsedOpsInCopy, const LiveRegUnits &UsedRegUnits, const TargetRegisterInfo *TRI)
static void performSink(MachineInstr &MI, MachineBasicBlock &SuccToSinkTo, MachineBasicBlock::iterator InsertPos, ArrayRef< MIRegs > DbgValuesToSink)
Sink an instruction and its associated debug instructions.
static cl::opt< bool > SplitEdges("machine-sink-split", cl::desc("Split critical edges during machine sinking"), cl::init(true), cl::Hidden)
static bool SinkingPreventsImplicitNullCheck(MachineInstr &MI, const TargetInstrInfo *TII, const TargetRegisterInfo *TRI)
Return true if MI is likely to be usable as a memory operation by the implicit null check optimizatio...
static cl::opt< bool > SinkInstsIntoCycle("sink-insts-to-avoid-spills", cl::desc("Sink instructions into cycles to avoid " "register spills"), cl::init(false), cl::Hidden)
static cl::opt< unsigned > SinkLoadBlocksThreshold("machine-sink-load-blocks-threshold", cl::desc("Do not try to find alias store for a load if the block number in " "the straight line is higher than this threshold."), cl::init(20), cl::Hidden)
static void updateLiveIn(MachineInstr *MI, MachineBasicBlock *SuccBB, const SmallVectorImpl< unsigned > &UsedOpsInCopy, const SmallVectorImpl< Register > &DefedRegsInCopy)
static bool hasRegisterDependency(MachineInstr *MI, SmallVectorImpl< unsigned > &UsedOpsInCopy, SmallVectorImpl< Register > &DefedRegsInCopy, LiveRegUnits &ModifiedRegUnits, LiveRegUnits &UsedRegUnits)
Register const TargetRegisterInfo * TRI
std::pair< MachineInstr *, SmallVector< Register, 2 > > MIRegs
Machine code static false bool blockPrologueInterferes(const MachineBasicBlock *BB, MachineBasicBlock::const_iterator End, const MachineInstr &MI, const TargetRegisterInfo *TRI, const TargetInstrInfo *TII, const MachineRegisterInfo *MRI)
Return true if a target defined block prologue instruction interferes with a sink candidate.
static cl::opt< unsigned > SplitEdgeProbabilityThreshold("machine-sink-split-probability-threshold", cl::desc("Percentage threshold for splitting single-instruction critical edge. " "If the branch threshold is higher than this threshold, we allow " "speculative execution of up to 1 instruction to avoid branching to " "splitted critical edge"), cl::init(40), cl::Hidden)
static bool attemptDebugCopyProp(MachineInstr &SinkInst, MachineInstr &DbgMI, Register Reg)
If the sunk instruction is a copy, try to forward the copy instead of leaving an 'undef' DBG_VALUE in...
static cl::opt< bool > UseBlockFreqInfo("machine-sink-bfi", cl::desc("Use block frequency info to find successors to sink"), cl::init(true), cl::Hidden)
static MachineBasicBlock * getSingleLiveInSuccBB(MachineBasicBlock &CurBB, const SmallPtrSetImpl< MachineBasicBlock * > &SinkableBBs, Register Reg, const TargetRegisterInfo *TRI)
This file implements a map that provides insertion order iteration.
Promote Memory to Register
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
This file defines the PointerIntPair class.
Remove Loads Into Fake Uses
This file implements a set that has insertion order iteration characteristics.
static bool ProcessBlock(BasicBlock &BB, DominatorTree &DT, LoopInfo &LI, AAResults &AA)
static bool SinkInstruction(Instruction *Inst, SmallPtrSetImpl< Instruction * > &Stores, DominatorTree &DT, LoopInfo &LI, AAResults &AA)
SinkInstruction - Determine whether it is safe to sink the specified machine instruction out of its c...
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Target-Independent Code Generator Pass Configuration Options pass.
A manager for alias analyses.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
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:
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
uint64_t getFrequency() const
Returns the frequency as a fixpoint number scaled by the entry frequency.
Represents analyses that only rely on functions' control flow.
static LLVM_ABI DebugLoc getMergedLocation(DebugLoc LocA, DebugLoc LocB)
When two instructions are combined into a single instruction we also need to combine the original loc...
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Implements a dense probed hash-table based set.
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
bool isReachableFromEntry(const NodeT *A) const
isReachableFromEntry - Return true if A is dominated by the entry block of the function containing it...
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
iterator_range< const_toplevel_iterator > toplevel_cycles() const
void splitCriticalEdge(BlockT *Pred, BlockT *Succ, BlockT *New)
unsigned getCycleDepth(const BlockT *Block) const
get the depth for the cycle which containing a given block.
CycleT * getCycle(const BlockT *Block) const
Find the innermost cycle containing a given block.
BlockT * getHeader() const
bool isReducible() const
Whether the cycle is a natural loop.
BlockT * getCyclePreheader() const
Return the preheader block for this cycle.
bool contains(const BlockT *Block) const
Return whether Block is contained in the cycle.
Module * getParent()
Get the module that this global value is contained inside of...
bool isAsCheapAsAMove(const MachineInstr &MI) const override
bool shouldSink(const MachineInstr &MI) const override
A set of register units used to track register liveness.
static void accumulateUsedDefed(const MachineInstr &MI, LiveRegUnits &ModifiedRegUnits, LiveRegUnits &UsedRegUnits, const TargetRegisterInfo *TRI)
For a machine instruction MI, adds all register units used in UsedRegUnits and defined or clobbered i...
bool available(MCRegister Reg) const
Returns true if no part of physical register Reg is live.
void init(const TargetRegisterInfo &TRI)
Initialize and clear the set.
LLVM_ABI void addLiveIns(const MachineBasicBlock &MBB)
Adds registers living into block MBB.
void clear()
Clears the set.
An RAII based helper class to modify MachineFunctionProperties when running pass.
bool isInlineAsmBrIndirectTarget() const
Returns true if this is the indirect dest of an INLINEASM_BR.
unsigned pred_size() const
bool isEHPad() const
Returns true if the block is a landing pad.
instr_iterator instr_begin()
MachineInstrBundleIterator< const MachineInstr > const_iterator
LLVM_ABI instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
LLVM_ABI iterator SkipPHIsAndLabels(iterator I)
Return the first instruction in MBB after I that is not a PHI or a label.
unsigned succ_size() const
LLVM_ABI void sortUniqueLiveIns()
Sorts and uniques the LiveIns vector.
pred_iterator pred_begin()
LLVM_ABI void removeLiveInOverlappedWith(MCRegister Reg)
Remove the specified register from any overlapped live in.
instr_iterator instr_end()
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
iterator_range< succ_iterator > successors()
LLVM_ABI bool isSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB is a successor of this block.
iterator_range< pred_iterator > predecessors()
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
LLVM_ABI bool isLiveIn(MCRegister Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
LLVM_ABI BlockFrequency getBlockFreq(const MachineBasicBlock *MBB) const
getblockFreq - Return block frequency.
LLVM_ABI void onEdgeSplit(const MachineBasicBlock &NewPredecessor, const MachineBasicBlock &NewSuccessor, const MachineBranchProbabilityInfo &MBPI)
incrementally calculate block frequencies when we split edges, to avoid full CFG traversal.
BranchProbability getEdgeProbability(const MachineBasicBlock *Src, const MachineBasicBlock *Dst) const
Legacy analysis pass which computes a MachineCycleInfo.
Analysis pass which computes a MachineDominatorTree.
Analysis pass which computes a MachineDominatorTree.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
bool dominates(const MachineInstr *A, const MachineInstr *B) const
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.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Representation of each machine instruction.
bool hasDebugOperandForReg(Register Reg) const
Returns whether this debug value has at least one debug operand with the register Reg.
void setDebugValueUndef()
Sets all register debug operands in this debug value instruction to be undef.
LLVM_ABI iterator_range< filter_iterator< const MachineOperand *, std::function< bool(const MachineOperand &Op)> > > getDebugOperandsForReg(Register Reg) const
Returns a range of all of the operands that correspond to a debug use of Reg.
bool mayLoadOrStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read or modify memory.
const MachineBasicBlock * getParent() const
bool isCopyLike() const
Return true if the instruction behaves like a copy.
bool isDebugInstr() const
LLVM_ABI void substituteRegister(Register FromReg, Register ToReg, unsigned SubIdx, const TargetRegisterInfo &RegInfo)
Replace all occurrences of FromReg with ToReg:SubIdx, properly composing subreg indices where necessa...
LLVM_ABI const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
filtered_mop_range all_uses()
Returns an iterator range over all operands that are (explicit or implicit) register uses.
const MachineOperand & getOperand(unsigned i) const
void setDebugLoc(DebugLoc DL)
Replace current source information with new such.
Analysis pass that exposes the MachineLoopInfo for a machine function.
A description of a memory reference used in the backend.
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
void setIsKill(bool Val=true)
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
Register getReg() const
getReg - Returns the register number.
MachinePostDominatorTree - an analysis pass wrapper for DominatorTree used to compute the post-domina...
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &)
void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
VectorType takeVector()
Clear the MapVector and return the underlying vector.
PointerIntPair - This class implements a pair of a pointer and small integer.
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
Analysis providing profile information.
Special value supplied for machine level alias analysis.
unsigned getRegPressureSetLimit(unsigned Idx) const
Get the register unit limit for the given pressure set index.
LLVM_ABI void runOnMachineFunction(const MachineFunction &MF, bool Rev=false)
runOnFunction - Prepare to answer questions about MF.
LLVM_ABI void collect(const MachineInstr &MI, const TargetRegisterInfo &TRI, const MachineRegisterInfo &MRI, bool TrackLaneMasks, bool IgnoreDead)
Analyze the given instruction MI and fill in the Uses, Defs and DeadDefs list based on the MachineOpe...
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
A vector that has set insertion semantics.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
TargetInstrInfo - Interface to description of machine instruction set.
Target-Independent Code Generator Pass Configuration Options.
bool getEnableSinkAndFold() const
bool contains(Register Reg) const
Return true if the specified register is included in this register class.
bool hasSuperClassEq(const TargetRegisterClass *RC) const
Returns true if RC is a super-class of or equal to this class.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Provide an instruction scheduling machine model to CodeGen passes.
LLVM_ABI void init(const TargetSubtargetInfo *TSInfo, bool EnableSModel=true, bool EnableSItins=true)
Initialize the machine model for instruction scheduling.
TargetSubtargetInfo - Generic base class for all target subtargets.
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
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.
An efficient, type-erasing, non-owning reference to a callable.
This class implements an extremely fast bulk output stream that can only output to a stream.
Abstract Attribute helper functions.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
initializer< Ty > init(const Ty &Val)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
@ User
could "use" a pointer
This is an optimization pass for GlobalISel generic memory operations.
void stable_sort(R &&Range)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
OuterAnalysisManagerProxy< ModuleAnalysisManager, MachineFunction > ModuleAnalysisManagerMachineFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
LLVM_ABI bool isCycleInvariant(const MachineCycle *Cycle, MachineInstr &I)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
LLVM_ABI bool shouldOptimizeForSize(const MachineFunction *MF, ProfileSummaryInfo *PSI, const MachineBlockFrequencyInfo *BFI, PGSOQueryType QueryType=PGSOQueryType::Other)
Returns true if machine function MF is suggested to be size-optimized based on the profile.
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...
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
auto reverse(ContainerTy &&C)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI char & PostRAMachineSinkingID
This pass perform post-ra machine sink for COPY instructions.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
DomTreeNodeBase< MachineBasicBlock > MachineDomTreeNode
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI char & MachineSinkingLegacyID
MachineSinking - This pass performs sinking on machine instructions.
iterator_range< df_iterator< T > > depth_first(const T &G)
AAResults AliasAnalysis
Temporary typedef for legacy code that uses a generic AliasAnalysis pointer or reference.
GenericCycleInfo< MachineSSAContext > MachineCycleInfo
MachineCycleInfo::CycleT MachineCycle
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
Represents a predicate at the MachineFunction level.
A pair composed of a register and a sub-register index.