68#define DEBUG_TYPE "machine-sink"
72 cl::desc(
"Split critical edges during machine sinking"),
77 cl::desc(
"Use block frequency info to find successors to sink"),
81 "machine-sink-split-probability-threshold",
83 "Percentage threshold for splitting single-instruction critical edge. "
84 "If the branch threshold is higher than this threshold, we allow "
85 "speculative execution of up to 1 instruction to avoid branching to "
86 "splitted critical edge"),
90 "machine-sink-load-instrs-threshold",
91 cl::desc(
"Do not try to find alias store for a load if there is a in-path "
92 "block whose instruction number is higher than this threshold."),
96 "machine-sink-load-blocks-threshold",
97 cl::desc(
"Do not try to find alias store for a load if the block number in "
98 "the straight line is higher than this threshold."),
103 cl::desc(
"Sink instructions into cycles to avoid "
108 "machine-sink-cycle-limit",
110 "The maximum number of instructions considered for cycle sinking."),
113STATISTIC(NumSunk,
"Number of machine instructions sunk");
114STATISTIC(NumCycleSunk,
"Number of machine instructions sunk into a cycle");
117STATISTIC(NumPostRACopySink,
"Number of copies sunk after RA");
123class MachineSinking {
157 using AllSuccsCache =
171 using SinkItem = std::pair<MachineInstr *, MachineBasicBlock *>;
190 CachedRegisterPressure;
192 bool EnableSinkAndFold;
201 : DT(DT), PDT(PDT), CI(CI), PSI(PSI), MBFI(MBFI), MBPI(MBPI),
AA(
AA),
202 RegClassInfo(RegClassInfo), MLI(MLI),
203 EnableSinkAndFold(EnableSinkAndFold) {}
207 void releaseMemory() {
208 CEBCandidates.
clear();
209 CEMergeCandidates.
clear();
239 AllSuccsCache &AllSuccessors);
249 bool &LocalUse)
const;
252 AllSuccsCache &AllSuccessors);
264 AllSuccsCache &AllSuccessors);
273 AllSuccsCache &AllSuccessors)
const;
276 bool UseCache =
true);
278 bool registerPressureSetExceedsLimit(
unsigned NRegs,
315char MachineSinkingLegacy::ID = 0;
341 if (!TII->isBasicBlockPrologue(*PI))
343 for (auto &MO : MI.operands()) {
346 Register Reg = MO.getReg();
350 if (Reg.isPhysical() &&
351 (TII->isIgnorableUse(MI, MI.getOperandNo(&MO)) ||
352 (MRI && MRI->isConstantPhysReg(Reg))))
354 if (PI->modifiesRegister(Reg, TRI))
357 if (PI->readsRegister(Reg, TRI))
360 auto *DefOp = PI->findRegisterDefOperand(Reg, TRI, false, true);
361 if (DefOp && !DefOp->isDead())
370bool MachineSinking::PerformTrivialForwardCoalescing(
MachineInstr &
MI,
392 MI.eraseFromParent();
398bool MachineSinking::PerformSinkAndFold(MachineInstr &
MI,
399 MachineBasicBlock *
MBB) {
400 if (
MI.isCopy() ||
MI.mayLoadOrStore() ||
401 MI.getOpcode() == TargetOpcode::REG_SEQUENCE)
409 bool SawStore =
true;
410 if (!
MI.isSafeToMove(SawStore))
415 if (
MI.isConvergent())
424 for (
const MachineOperand &MO :
MI.operands()) {
425 if (MO.isImm() || MO.isRegMask() || MO.isRegLiveOut() || MO.isMetadata() ||
426 MO.isMCSymbol() || MO.isDbgInstrRef() || MO.isCFIIndex() ||
427 MO.isIntrinsicID() || MO.isPredicate() || MO.isShuffleMask())
446 else if (UsedRegB == 0)
455 TII->isIgnorableUse(
MI,
MI.getOperandNo(&MO))))
465 using SinkInfo = std::pair<MachineInstr *, ExtAddrMode>;
476 while (!Worklist.
empty()) {
481 MachineInstr &UseInst = *MO.getParent();
484 if (
const MachineOperand &O = UseInst.
getOperand(0);
O.isReg())
505 return MO.isReg() && MO.getReg() == Reg;
509 if (!
TII->canFoldIntoAddrMode(UseInst,
Reg,
MI, AM))
526 if (RCA ==
nullptr) {
531 unsigned NRegs = !!RCA + !!RCB;
537 if (RCB ==
nullptr) {
538 if (registerPressureSetExceedsLimit(NRegs, RCA,
MBB))
540 }
else if (registerPressureSetExceedsLimit(1, RCA,
MBB) ||
541 registerPressureSetExceedsLimit(1, RCB,
MBB)) {
551 if (SinkInto.
empty())
555 for (
auto &[SinkDst, MaybeAM] : SinkInto) {
556 MachineInstr *
New =
nullptr;
559 if (SinkDst->isCopy()) {
572 Register DstReg = SinkDst->getOperand(0).getReg();
573 TII->reMaterialize(*SinkDst->getParent(), InsertPt, DstReg, 0,
MI);
574 New = &*std::prev(InsertPt);
575 if (!
New->getDebugLoc())
576 New->setDebugLoc(SinkDst->getDebugLoc());
579 New =
TII->emitLdStWithAddr(*SinkDst, MaybeAM);
583 if (SinkDst->mayStore() && !SinkDst->hasOrderedMemoryRef())
584 StoreInstrCache.clear();
585 SinkDst->eraseFromParent();
593 while (!Worklist.
empty()) {
597 assert((
U->isCopy() ||
U->isDebugInstr()) &&
598 "Only debug uses and copies must remain");
600 Worklist.
push_back(
U->getOperand(0).getReg());
606 for (MachineOperand *MO :
Cleanup) {
609 I->eraseFromParent();
616 MI.eraseFromParent();
624bool MachineSinking::AllUsesDominatedByBlock(
Register Reg,
625 MachineBasicBlock *
MBB,
626 MachineBasicBlock *DefMBB,
628 bool &LocalUse)
const {
650 MachineInstr *UseInst = MO.getParent();
651 unsigned OpNo = MO.getOperandNo();
652 MachineBasicBlock *UseBlock = UseInst->getParent();
653 return UseBlock == MBB && UseInst->isPHI() &&
654 UseInst->getOperand(OpNo + 1).getMBB() == DefMBB;
663 unsigned OpNo = &MO - &UseInst->
getOperand(0);
664 MachineBasicBlock *UseBlock = UseInst->
getParent();
665 if (UseInst->
isPHI()) {
669 }
else if (UseBlock == DefMBB) {
685 assert(
MI.mayLoad() &&
"Expected MI that loads!");
689 if (
MI.memoperands_empty())
694 if (PSV->isGOT() || PSV->isConstantPool())
700void MachineSinking::FindCycleSinkCandidates(
701 CycleRef Cycle, MachineBasicBlock *BB,
702 SmallVectorImpl<MachineInstr *> &Candidates) {
703 for (
auto &
MI : *BB) {
705 if (
MI.isMetaInstruction()) {
706 LLVM_DEBUG(
dbgs() <<
"CycleSink: not sinking meta instruction\n");
710 LLVM_DEBUG(
dbgs() <<
"CycleSink: Instruction not a candidate for this "
715 LLVM_DEBUG(
dbgs() <<
"CycleSink: Instruction is not cycle invariant\n");
718 bool DontMoveAcrossStore =
true;
719 if (!
MI.isSafeToMove(DontMoveAcrossStore)) {
720 LLVM_DEBUG(
dbgs() <<
"CycleSink: Instruction not safe to move.\n");
724 LLVM_DEBUG(
dbgs() <<
"CycleSink: Dont sink GOT or constant pool loads\n");
727 if (
MI.isConvergent())
730 const MachineOperand &MO =
MI.getOperand(0);
736 LLVM_DEBUG(
dbgs() <<
"CycleSink: Instruction added as candidate.\n");
748 .getCachedResult<ProfileSummaryAnalysis>(
759 MachineSinking Impl(EnableSinkAndFold, DT, PDT, MLI, CI, PSI, MBFI, MBPI,
AA,
774 OS << MapClassName2PassName(
name());
775 if (EnableSinkAndFold)
776 OS <<
"<enable-sink-fold>";
786 auto *DT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
788 &getAnalysis<MachinePostDominatorTreeWrapperPass>().getPostDomTree();
789 auto *CI = &getAnalysis<MachineCycleInfoWrapperPass>().getCycleInfo();
790 auto *PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
793 ? &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI()
796 &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
797 auto *
AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
799 auto *MLIWrapper = getAnalysisIfAvailable<MachineLoopInfoWrapperPass>();
800 auto *MLI = MLIWrapper ? &MLIWrapper->getLI() :
nullptr;
802 &getAnalysis<MachineRegisterClassInfoWrapperPass>().getRCI();
804 MachineSinking Impl(EnableSinkAndFold, DT, PDT, MLI, CI, PSI, MBFI, MBPI,
AA,
817 bool EverMadeChange =
false;
820 bool MadeChange =
false;
823 CEBCandidates.clear();
824 CEMergeCandidates.clear();
831 MachineDomTreeUpdater::UpdateStrategy::Lazy);
832 for (
const auto &Pair : ToSplit) {
833 auto NewSucc = Pair.first->SplitCriticalEdge(
834 Pair.second, {nullptr, nullptr, MLI}, &MDTU);
835 if (NewSucc !=
nullptr) {
852 EverMadeChange =
true;
857 SchedModel.
init(STI);
858 bool HasHighPressure;
860 DenseMap<SinkItem, MachineInstr *> SunkInstrs;
862 enum CycleSinkStage { COPY, LOW_LATENCY, AGGRESSIVE, END };
863 for (
unsigned Stage = CycleSinkStage::COPY; Stage != CycleSinkStage::END;
864 ++Stage, SunkInstrs.
clear()) {
865 HasHighPressure =
false;
867 for (
auto Cycle : Cycles) {
873 SmallVector<MachineInstr *, 8> Candidates;
874 FindCycleSinkCandidates(Cycle, Preheader, Candidates);
883 if (Stage == CycleSinkStage::COPY) {
886 <<
"CycleSink: Limit reached of instructions to "
897 if (Stage == CycleSinkStage::LOW_LATENCY &&
898 !
TII->hasLowDefLatency(SchedModel, *
I, 0))
901 if (!aggressivelySinkIntoCycle(Cycle, *
I, SunkInstrs))
903 EverMadeChange =
true;
908 if (!HasHighPressure)
909 HasHighPressure = registerPressureExceedsLimit(*Preheader);
911 if (!HasHighPressure)
916 HasStoreCache.clear();
917 StoreInstrCache.clear();
920 return EverMadeChange;
923bool MachineSinking::ProcessBlock(MachineBasicBlock &
MBB) {
933 bool MadeChange =
false;
936 AllSuccsCache AllSuccessors;
941 bool ProcessedBegin, SawStore =
false;
943 MachineInstr &
MI = *
I;
951 if (
MI.isDebugOrPseudoInstr() ||
MI.isFakeUse()) {
952 if (
MI.isDebugValue())
957 if (EnableSinkAndFold && PerformSinkAndFold(
MI, &
MBB)) {
966 if (PerformTrivialForwardCoalescing(
MI, &
MBB)) {
977 }
while (!ProcessedBegin);
979 SeenDbgUsers.clear();
982 CachedRegisterPressure.clear();
986void MachineSinking::ProcessDbgInst(MachineInstr &
MI) {
989 assert(
MI.isDebugValue() &&
"Expected DBG_VALUE for processing");
991 DebugVariable Var(
MI.getDebugVariable(),
MI.getDebugExpression(),
992 MI.getDebugLoc()->getInlinedAt());
993 bool SeenBefore = SeenDbgVars.contains(Var);
995 for (MachineOperand &MO :
MI.debug_operands()) {
997 SeenDbgUsers[MO.
getReg()].push_back(SeenDbgUser(&
MI, SeenBefore));
1001 SeenDbgVars.insert(Var);
1004bool MachineSinking::isWorthBreakingCriticalEdge(
1005 MachineInstr &
MI, MachineBasicBlock *From, MachineBasicBlock *To,
1006 MachineBasicBlock *&DeferredFromBlock) {
1012 if (!CEBCandidates.insert(std::make_pair(From, To)).second)
1023 for (
const auto &MO :
MI.all_defs()) {
1028 auto Key = std::make_pair(SrcReg, To);
1029 auto Res = CEMergeCandidates.try_emplace(
Key, From);
1034 DeferredFromBlock = Res.first->second;
1047 for (
const MachineOperand &MO :
MI.all_uses()) {
1072 return TII->shouldBreakCriticalEdgeToSink(
MI);
1075bool MachineSinking::isLegalToBreakCriticalEdge(MachineInstr &
MI,
1076 MachineBasicBlock *FromBB,
1077 MachineBasicBlock *ToBB,
1078 bool BreakPHIEdge) {
1083 CycleRef FromCycle = CI->
getCycle(FromBB);
1084 CycleRef ToCycle = CI->
getCycle(ToBB);
1087 if (FromCycle == ToCycle && FromCycle &&
1130 if (!BreakPHIEdge) {
1139bool MachineSinking::PostponeSplitCriticalEdge(MachineInstr &
MI,
1140 MachineBasicBlock *FromBB,
1141 MachineBasicBlock *ToBB,
1142 bool BreakPHIEdge) {
1143 bool Status =
false;
1144 MachineBasicBlock *DeferredFromBB =
nullptr;
1145 if (isWorthBreakingCriticalEdge(
MI, FromBB, ToBB, DeferredFromBB)) {
1148 if ((!DeferredFromBB ||
1149 ToSplit.count(std::make_pair(DeferredFromBB, ToBB)) ||
1150 isLegalToBreakCriticalEdge(
MI, DeferredFromBB, ToBB, BreakPHIEdge)) &&
1151 isLegalToBreakCriticalEdge(
MI, FromBB, ToBB, BreakPHIEdge)) {
1152 ToSplit.insert(std::make_pair(FromBB, ToBB));
1154 ToSplit.insert(std::make_pair(DeferredFromBB, ToBB));
1162std::vector<unsigned> &
1163MachineSinking::getBBRegisterPressure(
const MachineBasicBlock &
MBB,
1170 auto RP = CachedRegisterPressure.find(&
MBB);
1171 if (UseCache && RP != CachedRegisterPressure.end())
1174 RegionPressure Pressure;
1175 RegPressureTracker RPTracker(Pressure);
1183 MII != MIE; --MII) {
1184 const MachineInstr &
MI = *std::prev(MII);
1185 if (
MI.isDebugOrPseudoInstr())
1187 RegisterOperands RegOpers;
1189 RPTracker.recedeSkipDebugValues();
1190 assert(&*RPTracker.getPos() == &
MI &&
"RPTracker sync error!");
1191 RPTracker.recede(RegOpers);
1194 RPTracker.closeRegion();
1196 if (RP != CachedRegisterPressure.end()) {
1197 CachedRegisterPressure[&
MBB] = RPTracker.getPressure().MaxSetPressure;
1198 return CachedRegisterPressure[&
MBB];
1201 auto It = CachedRegisterPressure.insert(
1202 std::make_pair(&
MBB, RPTracker.getPressure().MaxSetPressure));
1203 return It.first->second;
1206bool MachineSinking::registerPressureSetExceedsLimit(
1208 const MachineBasicBlock &
MBB) {
1209 unsigned Weight = NRegs *
TRI->getRegClassWeight(RC).RegWeight;
1210 const int *PS =
TRI->getRegClassPressureSets(RC);
1211 std::vector<unsigned> BBRegisterPressure = getBBRegisterPressure(
MBB);
1212 for (; *PS != -1; PS++)
1213 if (Weight + BBRegisterPressure[*PS] >=
1220bool MachineSinking::registerPressureExceedsLimit(
1221 const MachineBasicBlock &
MBB) {
1222 std::vector<unsigned> BBRegisterPressure = getBBRegisterPressure(
MBB,
false);
1224 for (
unsigned PS = 0; PS < BBRegisterPressure.size(); ++PS) {
1234bool MachineSinking::isProfitableToSinkTo(
Register Reg, MachineInstr &
MI,
1235 MachineBasicBlock *
MBB,
1236 MachineBasicBlock *SuccToSinkTo,
1237 AllSuccsCache &AllSuccessors) {
1238 assert(SuccToSinkTo &&
"Invalid SinkTo Candidate BB");
1240 if (
MBB == SuccToSinkTo)
1253 bool NonPHIUse =
false;
1255 MachineBasicBlock *UseBlock = UseInst.
getParent();
1256 if (UseBlock == SuccToSinkTo && !UseInst.
isPHI())
1264 bool BreakPHIEdge =
false;
1266 if (MachineBasicBlock *MBB2 =
1267 FindSuccToSinkTo(
MI, SuccToSinkTo, BreakPHIEdge, AllSuccessors))
1268 return isProfitableToSinkTo(
Reg,
MI, SuccToSinkTo, MBB2, AllSuccessors);
1279 for (
const MachineOperand &MO :
MI.operands()) {
1290 !
TII->isIgnorableUse(
MI,
MI.getOperandNo(&MO)))
1298 bool LocalUse =
false;
1299 if (!AllUsesDominatedByBlock(
Reg, SuccToSinkTo,
MBB, BreakPHIEdge,
1311 if (Cycle != MCycle ||
1320 LLVM_DEBUG(
dbgs() <<
"register pressure exceed limit, not profitable.");
1334SmallVector<MachineBasicBlock *, 4> &
1335MachineSinking::GetAllSortedSuccessors(MachineInstr &
MI, MachineBasicBlock *
MBB,
1336 AllSuccsCache &AllSuccessors)
const {
1338 auto Succs = AllSuccessors.find(
MBB);
1339 if (Succs != AllSuccessors.end())
1340 return Succs->second;
1342 SmallVector<MachineBasicBlock *, 4> AllSuccs(
MBB->
successors());
1353 if (DTChild->getIDom()->getBlock() ==
MI.getParent() &&
1356 AllSuccs.push_back(DTChild->getBlock());
1361 AllSuccs, [&](
const MachineBasicBlock *L,
const MachineBasicBlock *R) {
1365 (!LHSFreq && !RHSFreq))
1367 return LHSFreq < RHSFreq;
1370 auto it = AllSuccessors.insert(std::make_pair(
MBB, AllSuccs));
1372 return it.first->second;
1377MachineSinking::FindSuccToSinkTo(MachineInstr &
MI, MachineBasicBlock *
MBB,
1379 AllSuccsCache &AllSuccessors) {
1380 assert(
MBB &&
"Invalid MachineBasicBlock!");
1387 MachineBasicBlock *SuccToSinkTo =
nullptr;
1388 for (
const MachineOperand &MO :
MI.operands()) {
1402 !
TII->isIgnorableUse(
MI,
MI.getOperandNo(&MO)))
1404 }
else if (!MO.
isDead()) {
1422 bool LocalUse =
false;
1423 if (!AllUsesDominatedByBlock(
Reg, SuccToSinkTo,
MBB, BreakPHIEdge,
1434 for (MachineBasicBlock *SuccBlock :
1435 GetAllSortedSuccessors(
MI,
MBB, AllSuccessors)) {
1436 bool LocalUse =
false;
1437 if (AllUsesDominatedByBlock(
Reg, SuccBlock,
MBB, BreakPHIEdge,
1439 SuccToSinkTo = SuccBlock;
1450 if (!isProfitableToSinkTo(
Reg,
MI,
MBB, SuccToSinkTo, AllSuccessors))
1457 if (
MBB == SuccToSinkTo)
1462 if (SuccToSinkTo && SuccToSinkTo->
isEHPad())
1472 if (SuccToSinkTo && !
TII->isSafeToSink(
MI, SuccToSinkTo, CI))
1475 return SuccToSinkTo;
1490 auto *
MBB =
MI.getParent();
1491 if (
MBB->pred_size() != 1)
1494 auto *PredMBB = *
MBB->pred_begin();
1495 auto *PredBB = PredMBB->getBasicBlock();
1501 !PredBB->getTerminator()->getMetadata(LLVMContext::MD_make_implicit))
1506 bool OffsetIsScalable;
1507 if (!
TII->getMemOperandWithOffset(
MI, BaseOp,
Offset, OffsetIsScalable))
1510 if (!BaseOp->
isReg())
1513 if (!(
MI.mayLoad() && !
MI.isPredicable()))
1516 MachineBranchPredicate MBP;
1517 if (
TII->analyzeBranchPredicate(*PredMBB, MBP,
false))
1520 return MBP.LHS.isReg() && MBP.RHS.isImm() && MBP.RHS.getImm() == 0 &&
1521 (MBP.Predicate == MachineBranchPredicate::PRED_NE ||
1522 MBP.Predicate == MachineBranchPredicate::PRED_EQ) &&
1523 MBP.LHS.getReg() == BaseOp->
getReg();
1540 auto CopyOperands =
TII.isCopyInstr(SinkInst);
1543 SrcMO = CopyOperands->Source;
1544 DstMO = CopyOperands->Destination;
1547 bool PostRA =
MRI.getNumVirtRegs() == 0;
1555 bool arePhysRegs = !
Reg.isVirtual();
1556 if (arePhysRegs != PostRA)
1563 if (DbgMO.getSubReg() != SrcMO->
getSubReg() ||
1564 DbgMO.getSubReg() != DstMO->getSubReg())
1570 if (PostRA &&
Reg != DstMO->getReg())
1574 DbgMO.setReg(SrcMO->
getReg());
1580using MIRegs = std::pair<MachineInstr *, SmallVector<Register, 2>>;
1588 if (SuccToSinkTo.
empty())
1596 SuccToSinkTo.
splice(InsertPos, ParentBlock,
MI,
1603 for (
const auto &DbgValueToSink : DbgValuesToSink) {
1606 SuccToSinkTo.
insert(InsertPos, NewDbgMI);
1608 bool PropagatedAllSunkOps =
true;
1612 PropagatedAllSunkOps =
false;
1617 if (!PropagatedAllSunkOps)
1624bool MachineSinking::hasStoreBetween(MachineBasicBlock *From,
1625 MachineBasicBlock *To, MachineInstr &
MI) {
1631 auto BlockPair = std::make_pair(From, To);
1635 if (
auto It = HasStoreCache.find(BlockPair); It != HasStoreCache.end())
1638 if (
auto It = StoreInstrCache.find(BlockPair); It != StoreInstrCache.end())
1640 return I->mayAlias(AA, MI, false);
1643 bool SawStore =
false;
1644 bool HasAliasedStore =
false;
1645 DenseSet<MachineBasicBlock *> HandledBlocks;
1646 DenseSet<MachineBasicBlock *> HandledDomBlocks;
1653 if (BB == To || BB == From)
1657 if (HandledBlocks.
count(BB))
1660 HandledBlocks.
insert(BB);
1663 if (!HandledDomBlocks.
count(BB))
1664 HandledDomBlocks.
insert(BB);
1670 for (
auto *DomBB : HandledDomBlocks) {
1671 if (DomBB != BB && DT->
dominates(DomBB, BB))
1672 HasStoreCache[std::make_pair(DomBB, To)] =
true;
1673 else if (DomBB != BB && DT->
dominates(BB, DomBB))
1674 HasStoreCache[std::make_pair(From, DomBB)] =
true;
1676 HasStoreCache[BlockPair] =
true;
1680 for (MachineInstr &
I : *BB) {
1683 if (
I.isCall() ||
I.hasOrderedMemoryRef()) {
1684 for (
auto *DomBB : HandledDomBlocks) {
1685 if (DomBB != BB && DT->
dominates(DomBB, BB))
1686 HasStoreCache[std::make_pair(DomBB, To)] =
true;
1687 else if (DomBB != BB && DT->
dominates(BB, DomBB))
1688 HasStoreCache[std::make_pair(From, DomBB)] =
true;
1690 HasStoreCache[BlockPair] =
true;
1700 if (
I.mayAlias(AA,
MI,
false))
1701 HasAliasedStore =
true;
1702 StoreInstrCache[BlockPair].push_back(&
I);
1709 HasStoreCache[BlockPair] =
false;
1710 return HasAliasedStore;
1718bool MachineSinking::aggressivelySinkIntoCycle(
1719 CycleRef Cycle, MachineInstr &
I,
1720 DenseMap<SinkItem, MachineInstr *> &SunkInstrs) {
1722 if (
I.getNumDefs() > 1)
1725 LLVM_DEBUG(
dbgs() <<
"AggressiveCycleSink: Finding sink block for: " <<
I);
1729 MachineOperand &DefMO =
I.getOperand(0);
1734 for (std::pair<RegSubRegPair, MachineInstr *> Entry :
Uses) {
1735 MachineInstr *
MI =
Entry.second;
1739 dbgs() <<
"AggressiveCycleSink: Not attempting to sink for PHI.\n");
1743 if (
MI->isPosition() ||
TII->isBasicBlockPrologue(*
MI)) {
1744 LLVM_DEBUG(
dbgs() <<
"AggressiveCycleSink: Use is BasicBlock prologue, "
1750 dbgs() <<
"AggressiveCycleSink: Use not in cycle, can't sink.\n");
1754 MachineBasicBlock *SinkBlock =
MI->getParent();
1755 MachineInstr *NewMI =
nullptr;
1756 SinkItem MapEntry(&
I, SinkBlock);
1758 auto SI = SunkInstrs.
find(MapEntry);
1762 if (SI != SunkInstrs.
end()) {
1763 LLVM_DEBUG(
dbgs() <<
"AggressiveCycleSink: Already sunk to block: "
1770 LLVM_DEBUG(
dbgs() <<
"AggressiveCycleSink: Sinking instruction to block: "
1773 NewMI =
I.
getMF()->CloneMachineInstr(&
I);
1782 SunkInstrs.
insert({MapEntry, NewMI});
1797 I.eraseFromParent();
1803bool MachineSinking::SinkInstruction(MachineInstr &
MI,
bool &SawStore,
1804 AllSuccsCache &AllSuccessors) {
1810 if (!
MI.isSafeToMove(SawStore))
1815 if (
MI.isConvergent())
1831 bool BreakPHIEdge =
false;
1832 MachineBasicBlock *ParentBlock =
MI.getParent();
1833 MachineBasicBlock *SuccToSinkTo =
1834 FindSuccToSinkTo(
MI, ParentBlock, BreakPHIEdge, AllSuccessors);
1843 for (
const MachineOperand &MO :
MI.all_defs()) {
1851 LLVM_DEBUG(
dbgs() <<
"Sink instr " <<
MI <<
"\tinto block " << *SuccToSinkTo);
1858 bool TryBreak =
false;
1860 MI.mayLoad() ? hasStoreBetween(ParentBlock, SuccToSinkTo,
MI) :
true;
1861 if (!
MI.isSafeToMove(
Store)) {
1862 LLVM_DEBUG(
dbgs() <<
" *** NOTE: Won't sink load along critical edge.\n");
1868 if (!TryBreak && !DT->
dominates(ParentBlock, SuccToSinkTo)) {
1874 if (!TryBreak && CI->
getCycle(SuccToSinkTo) &&
1888 bool Status = PostponeSplitCriticalEdge(
MI, ParentBlock, SuccToSinkTo,
1892 "break critical edge\n");
1903 PostponeSplitCriticalEdge(
MI, ParentBlock, SuccToSinkTo, BreakPHIEdge);
1906 "break critical edge\n");
1915 LLVM_DEBUG(
dbgs() <<
" *** Not sinking: prologue interference\n");
1921 for (
auto &MO :
MI.all_defs()) {
1924 auto It = SeenDbgUsers.find(MO.
getReg());
1925 if (It == SeenDbgUsers.end())
1929 auto &
Users = It->second;
1930 for (
auto &User :
Users) {
1931 MachineInstr *DbgMI =
User.getPointer();
1932 if (
User.getInt()) {
1947 if (
MI.getMF()->getFunction().getSubprogram() &&
MI.isCopy())
1948 SalvageUnsunkDebugUsersOfCopy(
MI, SuccToSinkTo);
1955void MachineSinking::SalvageUnsunkDebugUsersOfCopy(
1956 MachineInstr &
MI, MachineBasicBlock *TargetBlock) {
1963 SmallVector<MachineInstr *, 4> DbgDefUsers;
1966 for (
auto &MO :
MI.all_defs()) {
1975 if (
User.getParent() ==
MI.getParent())
1979 "DBG_VALUE user of vreg, but has no operand for it?");
1986 for (
auto *User : DbgDefUsers) {
1987 for (
auto &
Reg : DbgUseRegs) {
1988 for (
auto &DbgOp :
User->getDebugOperandsForReg(
Reg)) {
1989 DbgOp.setReg(
MI.getOperand(1).getReg());
1990 DbgOp.setSubReg(
MI.getOperand(1).getSubReg());
2032class PostRAMachineSinkingImpl {
2034 LiveRegUnits ModifiedRegUnits, UsedRegUnits;
2040 DenseMap<MCRegUnit, SmallVector<MIRegs, 2>> SeenDbgInstrs;
2045 const TargetRegisterInfo *
TRI,
const TargetInstrInfo *
TII);
2051class PostRAMachineSinkingLegacy :
public MachineFunctionPass {
2056 PostRAMachineSinkingLegacy() : MachineFunctionPass(
ID) {}
2057 StringRef getPassName()
const override {
return "PostRA Machine Sink"; }
2059 void getAnalysisUsage(AnalysisUsage &AU)
const override {
2064 MachineFunctionProperties getRequiredProperties()
const override {
2065 return MachineFunctionProperties().setNoVRegs();
2071char PostRAMachineSinkingLegacy::ID = 0;
2075 "PostRA Machine Sink",
false,
false)
2084static MachineBasicBlock *
2090 for (
auto *
SI : SinkableBBs) {
2091 if (aliasWithRegsInLiveIn(*
SI,
Reg,
TRI)) {
2111static MachineBasicBlock *
2117 for (
auto DefReg : DefedRegsInCopy) {
2120 if (!BB || (SingleBB && SingleBB != BB))
2131 for (
auto U : UsedOpsInCopy) {
2137 if (UI.killsRegister(SrcReg,
TRI)) {
2138 UI.clearRegisterKills(SrcReg,
TRI);
2150 for (
Register DefReg : DefedRegsInCopy)
2153 for (
auto U : UsedOpsInCopy)
2163 bool HasRegDependency =
false;
2164 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
2173 HasRegDependency =
true;
2182 }
else if (MO.
isUse()) {
2184 HasRegDependency =
true;
2190 return HasRegDependency;
2193bool PostRAMachineSinkingImpl::tryToSinkCopy(MachineBasicBlock &CurBB,
2195 const TargetRegisterInfo *
TRI,
2196 const TargetInstrInfo *
TII) {
2197 SmallPtrSet<MachineBasicBlock *, 2> SinkableBBs;
2201 for (MachineBasicBlock *SI : CurBB.
successors())
2202 if (!
SI->livein_empty() &&
SI->pred_size() == 1 && !
SI->isEHPad())
2205 if (SinkableBBs.
empty())
2212 ModifiedRegUnits.
clear();
2213 UsedRegUnits.
clear();
2214 SeenDbgInstrs.clear();
2218 SmallVector<unsigned, 2> UsedOpsInCopy;
2224 if (
MI.isDebugValue() && !
MI.isDebugRef()) {
2225 SmallDenseMap<MCRegUnit, SmallVector<Register, 2>, 4> MIUnits;
2226 bool IsValid =
true;
2227 for (MachineOperand &MO :
MI.debug_operands()) {
2232 ModifiedRegUnits, UsedRegUnits)) {
2238 for (MCRegUnit Unit :
TRI->regunits(MO.
getReg()))
2243 for (
auto &RegOps : MIUnits)
2244 SeenDbgInstrs[RegOps.first].emplace_back(&
MI,
2245 std::move(RegOps.second));
2251 if (!
TII->shouldPostRASink(
MI)) {
2257 if (
MI.isDebugOrPseudoInstr())
2264 if (!
MI.isCopy() || !
MI.getOperand(0).isRenamable()) {
2272 ModifiedRegUnits, UsedRegUnits)) {
2278 "Unexpect SrcReg or DefReg");
2279 MachineBasicBlock *SuccBB =
2289 "Unexpected predecessor");
2294 MapVector<MachineInstr *, MIRegs::second_type> DbgValsToSinkMap;
2295 for (
auto &MO :
MI.all_defs()) {
2296 for (MCRegUnit Unit :
TRI->regunits(MO.
getReg())) {
2297 for (
const auto &
MIRegs : SeenDbgInstrs.lookup(Unit)) {
2298 auto &Regs = DbgValsToSinkMap[
MIRegs.first];
2303 auto DbgValsToSink = DbgValsToSinkMap.
takeVector();
2312 LLVM_DEBUG(
dbgs() <<
" *** Not sinking: prologue interference\n");
2323 ++NumPostRACopySink;
2341bool PostRAMachineSinkingLegacy::runOnMachineFunction(
MachineFunction &MF) {
2345 return PostRAMachineSinkingImpl().run(MF);
2353 if (!PostRAMachineSinkingImpl().
run(MF))
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.
ManagedStatic< 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.
MachineRegisterInfo & MRI
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:
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.
Opaque handle to a cycle within a GenericCycleInfo that wraps the cycle's preorder index.
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...
static DebugLoc getDropped()
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
bool isReducible(CycleRef C) const
BlockT * getCyclePreheader(CycleRef C) const
Return the preheader block for C.
void splitCriticalEdge(BlockT *Pred, BlockT *Succ, BlockT *New)
bool contains(CycleRef Outer, CycleRef Inner) const
Returns true iff Outer contains Inner. O(1). Non-strict.
unsigned getCycleDepth(const BlockT *Block) const
Return the depth of the innermost cycle containing Block, or 0 if it is not contained in any cycle.
BlockT * getHeader(CycleRef C) const
CycleRef getCycle(const BlockT *Block) const
Find the innermost cycle containing Block.
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.
bool hasSuperClassEq(const MCRegisterClass *RC) const
Returns true if RC is a super-class of or equal to this class.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
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.
LLVM_ABI DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any debug instructions.
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.
LLVM_ABI 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.
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.
void setSubReg(unsigned subReg)
unsigned getSubReg() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
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,...
LLVM_ABI bool hasOneNonDBGUse(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug use of the specified register.
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI LLVM_READONLY MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
iterator_range< use_nodbg_iterator > use_nodbg_operands(Register Reg) const
bool use_nodbg_empty(Register RegNo) const
use_nodbg_empty - Return true if there are no non-Debug instructions using the specified register.
MachineBasicBlock * getDefBlock(Register Reg) const
Return the machine basic block in which the specified virtual register is defined,...
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
iterator_range< use_instr_nodbg_iterator > use_nodbg_instructions(Register Reg) const
const MachineFunction & getMF() const
bool hasOneDef(Register RegNo) const
Return true if there is exactly one operand defining the specified register.
iterator_range< use_instr_iterator > use_instructions(Register Reg) const
LLVM_ABI bool isConstantPhysReg(MCRegister PhysReg) const
Returns true if PhysReg is unallocatable and constant throughout the function.
iterator_range< use_iterator > use_operands(Register Reg) const
LLVM_ABI void replaceRegWith(Register FromReg, Register ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
LLVM_ABI PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &)
LLVM_ABI 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.
LLVM_ABI 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 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.
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
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.
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.
@ Store
The extracted value is stored (ExtractElement only).
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 bool isCycleInvariant(const MachineCycleInfo &CI, CycleRef Cycle, MachineInstr &I)
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
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
LLVM_ABI char & MachineSinkingLegacyID
MachineSinking - This pass performs sinking on machine instructions.
iterator_range< df_iterator< T > > depth_first(const T &G)
@ End
Run the machine verifier once, at the end of the pipeline.
AAResults AliasAnalysis
Temporary typedef for legacy code that uses a generic AliasAnalysis pointer or reference.
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
MCRegisterClass TargetRegisterClass
Represents a predicate at the MachineFunction level.
A pair composed of a register and a sub-register index.