65#define DEBUG_TYPE "machine-sink"
69 cl::desc(
"Split critical edges during machine sinking"),
74 cl::desc(
"Use block frequency info to find successors to sink"),
78 "machine-sink-split-probability-threshold",
80 "Percentage threshold for splitting single-instruction critical edge. "
81 "If the branch threshold is higher than this threshold, we allow "
82 "speculative execution of up to 1 instruction to avoid branching to "
83 "splitted critical edge"),
87 "machine-sink-load-instrs-threshold",
88 cl::desc(
"Do not try to find alias store for a load if there is a in-path "
89 "block whose instruction number is higher than this threshold."),
93 "machine-sink-load-blocks-threshold",
94 cl::desc(
"Do not try to find alias store for a load if the block number in "
95 "the straight line is higher than this threshold."),
100 cl::desc(
"Sink instructions into cycles to avoid "
105 "machine-sink-cycle-limit",
107 "The maximum number of instructions considered for cycle sinking."),
110STATISTIC(NumSunk,
"Number of machine instructions sunk");
111STATISTIC(NumCycleSunk,
"Number of machine instructions sunk into a cycle");
114STATISTIC(NumPostRACopySink,
"Number of copies sunk after RA");
150 using AllSuccsCache =
181 CachedRegisterPressure;
183 bool EnableSinkAndFold;
210 CEBCandidates.
clear();
211 CEMergeCandidates.
clear();
241 AllSuccsCache &AllSuccessors);
251 bool &LocalUse)
const;
254 AllSuccsCache &AllSuccessors);
263 AllSuccsCache &AllSuccessors);
272 AllSuccsCache &AllSuccessors)
const;
276 bool registerPressureSetExceedsLimit(
unsigned NRegs,
283char MachineSinking::ID = 0;
308 if (!
TII->isBasicBlockPrologue(*PI))
310 for (
auto &MO :
MI.operands()) {
317 if (
Reg.isPhysical() &&
318 (
TII->isIgnorableUse(MO) || (
MRI &&
MRI->isConstantPhysReg(
Reg))))
320 if (PI->modifiesRegister(
Reg,
TRI))
323 if (PI->readsRegister(
Reg,
TRI))
326 auto *DefOp = PI->findRegisterDefOperand(
Reg,
TRI,
false,
true);
327 if (DefOp && !DefOp->isDead())
336bool MachineSinking::PerformTrivialForwardCoalescing(
MachineInstr &
MI,
344 !
MRI->hasOneNonDBGUse(SrcReg))
357 MRI->replaceRegWith(DstReg, SrcReg);
358 MI.eraseFromParent();
362 MRI->clearKillFlags(SrcReg);
370 if (
MI.isCopy() ||
MI.mayLoadOrStore() ||
371 MI.getOpcode() == TargetOpcode::REG_SEQUENCE)
379 bool SawStore =
true;
380 if (!
MI.isSafeToMove(SawStore))
385 if (
MI.isConvergent())
395 if (MO.isImm() || MO.isRegMask() || MO.isRegLiveOut() || MO.isMetadata() ||
396 MO.isMCSymbol() || MO.isDbgInstrRef() || MO.isCFIIndex() ||
397 MO.isIntrinsicID() || MO.isPredicate() || MO.isShuffleMask())
406 if (
Reg.isVirtual()) {
416 else if (UsedRegB == 0)
423 if (
Reg.isPhysical() && MO.isUse() &&
424 (
MRI->isConstantPhysReg(
Reg) ||
TII->isIgnorableUse(MO)))
434 using SinkInfo = std::pair<MachineInstr *, ExtAddrMode>;
440 UsedRegA == 0 ? nullptr :
MRI->getRegClass(UsedRegA);
442 UsedRegB == 0 ? nullptr :
MRI->getRegClass(UsedRegB);
445 while (!Worklist.
empty()) {
471 if (!
TII->canFoldIntoAddrMode(UseInst,
Reg,
MI, AM))
488 if (RCA ==
nullptr) {
493 unsigned NRegs = !!RCA + !!RCB;
499 if (RCB ==
nullptr) {
500 if (registerPressureSetExceedsLimit(NRegs, RCA,
MBB))
502 }
else if (registerPressureSetExceedsLimit(1, RCA,
MBB) ||
503 registerPressureSetExceedsLimit(1, RCB,
MBB)) {
513 if (SinkInto.
empty())
517 for (
auto &[SinkDst, MaybeAM] : SinkInto) {
521 if (SinkDst->isCopy()) {
534 Register DstReg = SinkDst->getOperand(0).getReg();
535 TII->reMaterialize(*SinkDst->getParent(), InsertPt, DstReg, 0,
MI, *
TRI);
536 New = &*std::prev(InsertPt);
537 if (!
New->getDebugLoc())
538 New->setDebugLoc(SinkDst->getDebugLoc());
544 MRI->clearKillFlags(UsedRegA);
546 MRI->clearKillFlags(UsedRegB);
549 New =
TII->emitLdStWithAddr(*SinkDst, MaybeAM);
555 MRI->clearKillFlags(R);
557 MRI->clearKillFlags(R);
561 if (SinkDst->mayStore() && !SinkDst->hasOrderedMemoryRef())
562 StoreInstrCache.
clear();
563 SinkDst->eraseFromParent();
571 while (!Worklist.
empty()) {
575 assert((
U->isCopy() ||
U->isDebugInstr()) &&
576 "Only debug uses and copies must remain");
578 Worklist.
push_back(
U->getOperand(0).getReg());
587 I->eraseFromParent();
594 MI.eraseFromParent();
602bool MachineSinking::AllUsesDominatedByBlock(
Register Reg,
606 bool &LocalUse)
const {
607 assert(
Reg.isVirtual() &&
"Only makes sense for vregs");
610 if (
MRI->use_nodbg_empty(
Reg))
628 MachineInstr *UseInst = MO.getParent();
629 unsigned OpNo = MO.getOperandNo();
630 MachineBasicBlock *UseBlock = UseInst->getParent();
631 return UseBlock == MBB && UseInst->isPHI() &&
632 UseInst->getOperand(OpNo + 1).getMBB() == DefMBB;
641 unsigned OpNo = &MO - &UseInst->
getOperand(0);
643 if (UseInst->
isPHI()) {
647 }
else if (UseBlock == DefMBB) {
663 assert(
MI.mayLoad() &&
"Expected MI that loads!");
667 if (
MI.memoperands_empty())
672 if (PSV->isGOT() || PSV->isConstantPool())
678void MachineSinking::FindCycleSinkCandidates(
681 for (
auto &
MI : *BB) {
684 LLVM_DEBUG(
dbgs() <<
"CycleSink: Instruction not a candidate for this "
689 LLVM_DEBUG(
dbgs() <<
"CycleSink: Instruction is not cycle invariant\n");
692 bool DontMoveAcrossStore =
true;
693 if (!
MI.isSafeToMove(DontMoveAcrossStore)) {
694 LLVM_DEBUG(
dbgs() <<
"CycleSink: Instruction not safe to move.\n");
698 LLVM_DEBUG(
dbgs() <<
"CycleSink: Dont sink GOT or constant pool loads\n");
701 if (
MI.isConvergent())
710 LLVM_DEBUG(
dbgs() <<
"CycleSink: Instruction added as candidate.\n");
725 DT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
726 PDT = &getAnalysis<MachinePostDominatorTreeWrapperPass>().getPostDomTree();
727 CI = &getAnalysis<MachineCycleInfoWrapperPass>().getCycleInfo();
728 PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
730 ? &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI()
732 MBPI = &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
733 AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
738 bool EverMadeChange =
false;
741 bool MadeChange =
false;
744 CEBCandidates.
clear();
745 CEMergeCandidates.
clear();
752 MachineDomTreeUpdater::UpdateStrategy::Lazy);
753 for (
const auto &Pair : ToSplit) {
755 Pair.first->SplitCriticalEdge(Pair.second, *
this,
nullptr, &MDTU);
756 if (NewSucc !=
nullptr) {
773 EverMadeChange =
true;
778 for (
auto *
Cycle : Cycles) {
785 FindCycleSinkCandidates(
Cycle, Preheader, Candidates);
793 LLVM_DEBUG(
dbgs() <<
"CycleSink: Limit reached of instructions to "
798 if (!SinkIntoCycle(
Cycle, *
I))
800 EverMadeChange =
true;
806 HasStoreCache.
clear();
807 StoreInstrCache.
clear();
810 for (
auto I : RegsToClearKillFlags)
811 MRI->clearKillFlags(
I);
812 RegsToClearKillFlags.clear();
814 return EverMadeChange;
827 bool MadeChange =
false;
830 AllSuccsCache AllSuccessors;
835 bool ProcessedBegin, SawStore =
false;
845 if (
MI.isDebugOrPseudoInstr() ||
MI.isFakeUse()) {
846 if (
MI.isDebugValue())
851 if (EnableSinkAndFold && PerformSinkAndFold(
MI, &
MBB)) {
860 if (PerformTrivialForwardCoalescing(
MI, &
MBB)) {
871 }
while (!ProcessedBegin);
873 SeenDbgUsers.
clear();
876 CachedRegisterPressure.
clear();
883 assert(
MI.isDebugValue() &&
"Expected DBG_VALUE for processing");
886 MI.getDebugLoc()->getInlinedAt());
887 bool SeenBefore = SeenDbgVars.
contains(Var);
891 SeenDbgUsers[MO.
getReg()].push_back(SeenDbgUser(&
MI, SeenBefore));
898bool MachineSinking::isWorthBreakingCriticalEdge(
906 if (!CEBCandidates.
insert(std::make_pair(
From, To)).second)
917 for (
const auto &MO :
MI.all_defs()) {
922 auto Key = std::make_pair(SrcReg, To);
928 DeferredFromBlock = Res.first->second;
933 if (
From->isSuccessor(To) &&
948 if (
Reg.isPhysical())
954 if (
MRI->hasOneNonDBGUse(
Reg)) {
967 return TII->shouldBreakCriticalEdgeToSink(
MI);
982 if (FromCycle == ToCycle && FromCycle &&
1025 if (!BreakPHIEdge) {
1027 if (Pred != FromBB && !DT->
dominates(ToBB, Pred))
1037 bool BreakPHIEdge) {
1040 if (isWorthBreakingCriticalEdge(
MI, FromBB, ToBB, DeferredFromBB)) {
1043 if ((!DeferredFromBB ||
1044 ToSplit.count(std::make_pair(DeferredFromBB, ToBB)) ||
1045 isLegalToBreakCriticalEdge(
MI, DeferredFromBB, ToBB, BreakPHIEdge)) &&
1046 isLegalToBreakCriticalEdge(
MI, FromBB, ToBB, BreakPHIEdge)) {
1047 ToSplit.
insert(std::make_pair(FromBB, ToBB));
1049 ToSplit.insert(std::make_pair(DeferredFromBB, ToBB));
1057std::vector<unsigned> &
1063 auto RP = CachedRegisterPressure.
find(&
MBB);
1064 if (RP != CachedRegisterPressure.
end())
1076 MII != MIE; --MII) {
1078 if (
MI.isDebugInstr() ||
MI.isPseudoProbe())
1082 RPTracker.recedeSkipDebugValues();
1083 assert(&*RPTracker.getPos() == &
MI &&
"RPTracker sync error!");
1084 RPTracker.recede(RegOpers);
1087 RPTracker.closeRegion();
1088 auto It = CachedRegisterPressure.
insert(
1089 std::make_pair(&
MBB, RPTracker.getPressure().MaxSetPressure));
1090 return It.first->second;
1093bool MachineSinking::registerPressureSetExceedsLimit(
1096 unsigned Weight = NRegs *
TRI->getRegClassWeight(RC).RegWeight;
1097 const int *PS =
TRI->getRegClassPressureSets(RC);
1098 std::vector<unsigned> BBRegisterPressure = getBBRegisterPressure(
MBB);
1099 for (; *PS != -1; PS++)
1100 if (Weight + BBRegisterPressure[*PS] >=
1110 AllSuccsCache &AllSuccessors) {
1111 assert(SuccToSinkTo &&
"Invalid SinkTo Candidate BB");
1113 if (
MBB == SuccToSinkTo)
1126 bool NonPHIUse =
false;
1129 if (UseBlock == SuccToSinkTo && !UseInst.
isPHI())
1137 bool BreakPHIEdge =
false;
1140 FindSuccToSinkTo(
MI, SuccToSinkTo, BreakPHIEdge, AllSuccessors))
1141 return isProfitableToSinkTo(
Reg,
MI, SuccToSinkTo, MBB2, AllSuccessors);
1160 if (
Reg.isPhysical()) {
1163 !
TII->isIgnorableUse(MO))
1171 bool LocalUse =
false;
1172 if (!AllUsesDominatedByBlock(
Reg, SuccToSinkTo,
MBB, BreakPHIEdge,
1190 if (registerPressureSetExceedsLimit(1,
MRI->getRegClass(
Reg),
1192 LLVM_DEBUG(
dbgs() <<
"register pressure exceed limit, not profitable.");
1208 AllSuccsCache &AllSuccessors)
const {
1210 auto Succs = AllSuccessors.find(
MBB);
1211 if (Succs != AllSuccessors.end())
1212 return Succs->second;
1225 if (DTChild->getIDom()->getBlock() ==
MI.getParent() &&
1228 AllSuccs.push_back(DTChild->getBlock());
1237 (!LHSFreq && !RHSFreq))
1239 return LHSFreq < RHSFreq;
1242 auto it = AllSuccessors.insert(std::make_pair(
MBB, AllSuccs));
1244 return it.first->second;
1251 AllSuccsCache &AllSuccessors) {
1252 assert(
MBB &&
"Invalid MachineBasicBlock!");
1268 if (
Reg.isPhysical()) {
1273 if (!
MRI->isConstantPhysReg(
Reg) && !
TII->isIgnorableUse(MO))
1275 }
else if (!MO.
isDead()) {
1285 if (!
TII->isSafeToMoveRegClassDefs(
MRI->getRegClass(
Reg)))
1293 bool LocalUse =
false;
1294 if (!AllUsesDominatedByBlock(
Reg, SuccToSinkTo,
MBB, BreakPHIEdge,
1306 GetAllSortedSuccessors(
MI,
MBB, AllSuccessors)) {
1307 bool LocalUse =
false;
1308 if (AllUsesDominatedByBlock(
Reg, SuccBlock,
MBB, BreakPHIEdge,
1310 SuccToSinkTo = SuccBlock;
1321 if (!isProfitableToSinkTo(
Reg,
MI,
MBB, SuccToSinkTo, AllSuccessors))
1328 if (
MBB == SuccToSinkTo)
1333 if (SuccToSinkTo && SuccToSinkTo->
isEHPad())
1343 if (SuccToSinkTo && !
TII->isSafeToSink(
MI, SuccToSinkTo, CI))
1346 return SuccToSinkTo;
1361 auto *
MBB =
MI.getParent();
1366 auto *PredBB = PredMBB->getBasicBlock();
1372 !PredBB->getTerminator()->getMetadata(LLVMContext::MD_make_implicit))
1377 bool OffsetIsScalable;
1378 if (!
TII->getMemOperandWithOffset(
MI, BaseOp,
Offset, OffsetIsScalable,
TRI))
1381 if (!BaseOp->
isReg())
1384 if (!(
MI.mayLoad() && !
MI.isPredicable()))
1387 MachineBranchPredicate MBP;
1388 if (
TII->analyzeBranchPredicate(*PredMBB, MBP,
false))
1391 return MBP.LHS.isReg() && MBP.RHS.isImm() && MBP.RHS.getImm() == 0 &&
1392 (MBP.Predicate == MachineBranchPredicate::PRED_NE ||
1393 MBP.Predicate == MachineBranchPredicate::PRED_EQ) &&
1394 MBP.LHS.getReg() == BaseOp->
getReg();
1411 auto CopyOperands =
TII.isCopyInstr(SinkInst);
1414 SrcMO = CopyOperands->Source;
1415 DstMO = CopyOperands->Destination;
1418 bool PostRA =
MRI.getNumVirtRegs() == 0;
1426 bool arePhysRegs = !
Reg.isVirtual();
1427 if (arePhysRegs != PostRA)
1434 if (DbgMO.getSubReg() != SrcMO->
getSubReg() ||
1435 DbgMO.getSubReg() != DstMO->getSubReg())
1441 if (PostRA &&
Reg != DstMO->getReg())
1445 DbgMO.setReg(SrcMO->
getReg());
1451using MIRegs = std::pair<MachineInstr *, SmallVector<unsigned, 2>>;
1459 if (!SuccToSinkTo.
empty() && InsertPos != SuccToSinkTo.
end())
1461 InsertPos->getDebugLoc()));
1467 SuccToSinkTo.
splice(InsertPos, ParentBlock,
MI,
1474 for (
const auto &DbgValueToSink : DbgValuesToSink) {
1477 SuccToSinkTo.
insert(InsertPos, NewDbgMI);
1479 bool PropagatedAllSunkOps =
true;
1480 for (
unsigned Reg : DbgValueToSink.second) {
1483 PropagatedAllSunkOps =
false;
1488 if (!PropagatedAllSunkOps)
1502 auto BlockPair = std::make_pair(
From, To);
1506 if (
auto It = HasStoreCache.
find(BlockPair); It != HasStoreCache.
end())
1509 if (
auto It = StoreInstrCache.
find(BlockPair); It != StoreInstrCache.
end())
1511 return I->mayAlias(AA, MI, false);
1514 bool SawStore =
false;
1515 bool HasAliasedStore =
false;
1524 if (BB == To || BB ==
From)
1528 if (HandledBlocks.
count(BB))
1531 HandledBlocks.
insert(BB);
1534 if (!HandledDomBlocks.
count(BB))
1535 HandledDomBlocks.
insert(BB);
1541 for (
auto *DomBB : HandledDomBlocks) {
1542 if (DomBB != BB && DT->
dominates(DomBB, BB))
1543 HasStoreCache[std::make_pair(DomBB, To)] =
true;
1544 else if (DomBB != BB && DT->
dominates(BB, DomBB))
1545 HasStoreCache[std::make_pair(
From, DomBB)] =
true;
1547 HasStoreCache[BlockPair] =
true;
1554 if (
I.isCall() ||
I.hasOrderedMemoryRef()) {
1555 for (
auto *DomBB : HandledDomBlocks) {
1556 if (DomBB != BB && DT->
dominates(DomBB, BB))
1557 HasStoreCache[std::make_pair(DomBB, To)] =
true;
1558 else if (DomBB != BB && DT->
dominates(BB, DomBB))
1559 HasStoreCache[std::make_pair(
From, DomBB)] =
true;
1561 HasStoreCache[BlockPair] =
true;
1571 if (
I.mayAlias(AA,
MI,
false))
1572 HasAliasedStore =
true;
1573 StoreInstrCache[BlockPair].push_back(&
I);
1580 HasStoreCache[BlockPair] =
false;
1581 return HasAliasedStore;
1590 assert(Preheader &&
"Cycle sink needs a preheader block");
1592 bool CanSink =
true;
1598 LLVM_DEBUG(
dbgs() <<
"CycleSink: Use not in cycle, can't sink.\n");
1613 SinkBlock =
MI.getParent();
1620 LLVM_DEBUG(
dbgs() <<
"CycleSink: Can't find nearest dominator\n");
1624 LLVM_DEBUG(
dbgs() <<
"CycleSink: Setting nearest common dom block: "
1633 LLVM_DEBUG(
dbgs() <<
"CycleSink: Not sinking, can't find sink block.\n");
1636 if (SinkBlock == Preheader) {
1638 dbgs() <<
"CycleSink: Not sinking, sink block is the preheader\n");
1643 dbgs() <<
"CycleSink: Not Sinking, block too large to analyse.\n");
1654 RegsToClearKillFlags.insert(MO.
getReg());
1659 assert(!
I.isDebugInstr() &&
"Should not sink debug inst");
1666bool MachineSinking::SinkInstruction(
MachineInstr &
MI,
bool &SawStore,
1667 AllSuccsCache &AllSuccessors) {
1673 if (!
MI.isSafeToMove(SawStore))
1678 if (
MI.isConvergent())
1694 bool BreakPHIEdge =
false;
1697 FindSuccToSinkTo(
MI, ParentBlock, BreakPHIEdge, AllSuccessors);
1708 if (
Reg == 0 || !
Reg.isPhysical())
1714 LLVM_DEBUG(
dbgs() <<
"Sink instr " <<
MI <<
"\tinto block " << *SuccToSinkTo);
1721 bool TryBreak =
false;
1723 MI.mayLoad() ? hasStoreBetween(ParentBlock, SuccToSinkTo,
MI) :
true;
1724 if (!
MI.isSafeToMove(Store)) {
1725 LLVM_DEBUG(
dbgs() <<
" *** NOTE: Won't sink load along critical edge.\n");
1731 if (!TryBreak && !DT->
dominates(ParentBlock, SuccToSinkTo)) {
1737 if (!TryBreak && CI->
getCycle(SuccToSinkTo) &&
1751 bool Status = PostponeSplitCriticalEdge(
MI, ParentBlock, SuccToSinkTo,
1755 "break critical edge\n");
1766 PostponeSplitCriticalEdge(
MI, ParentBlock, SuccToSinkTo, BreakPHIEdge);
1769 "break critical edge\n");
1778 LLVM_DEBUG(
dbgs() <<
" *** Not sinking: prologue interference\n");
1784 for (
auto &MO :
MI.all_defs()) {
1794 if (
User.getInt()) {
1809 if (
MI.getMF()->getFunction().getSubprogram() &&
MI.isCopy())
1810 SalvageUnsunkDebugUsersOfCopy(
MI, SuccToSinkTo);
1820 RegsToClearKillFlags.insert(MO.
getReg());
1825void MachineSinking::SalvageUnsunkDebugUsersOfCopy(
1836 for (
auto &MO :
MI.all_defs()) {
1845 if (
User.getParent() ==
MI.getParent())
1849 "DBG_VALUE user of vreg, but has no operand for it?");
1856 for (
auto *
User : DbgDefUsers) {
1857 for (
auto &
Reg : DbgUseRegs) {
1858 for (
auto &
DbgOp :
User->getDebugOperandsForReg(
Reg)) {
1859 DbgOp.setReg(
MI.getOperand(1).getReg());
1860 DbgOp.setSubReg(
MI.getOperand(1).getSubReg());
1917 MachineFunctionProperties::Property::NoVRegs);
1937char PostRAMachineSinking::ID = 0;
1941 "PostRA Machine Sink",
false,
false)
1956 for (
auto *SI : SinkableBBs) {
1957 if (aliasWithRegsInLiveIn(*SI,
Reg,
TRI)) {
1971 if (!SinkableBBs.
count(SI) && aliasWithRegsInLiveIn(*SI,
Reg,
TRI))
1983 for (
auto DefReg : DefedRegsInCopy) {
1986 if (!BB || (SingleBB && SingleBB != BB))
1997 for (
auto U : UsedOpsInCopy) {
2003 if (UI.killsRegister(SrcReg,
TRI)) {
2004 UI.clearRegisterKills(SrcReg,
TRI);
2018 for (
unsigned DefReg : DefedRegsInCopy)
2021 for (
auto U : UsedOpsInCopy)
2031 bool HasRegDependency =
false;
2032 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
2041 HasRegDependency =
true;
2050 }
else if (MO.
isUse()) {
2052 HasRegDependency =
true;
2058 return HasRegDependency;
2070 if (!
SI->livein_empty() &&
SI->pred_size() == 1)
2073 if (SinkableBBs.
empty())
2076 bool Changed =
false;
2080 ModifiedRegUnits.clear();
2081 UsedRegUnits.clear();
2082 SeenDbgInstrs.clear();
2092 if (
MI.isDebugValue() && !
MI.isDebugRef()) {
2094 bool IsValid =
true;
2100 ModifiedRegUnits, UsedRegUnits)) {
2107 MIUnits[Unit].push_back(MO.
getReg());
2111 for (
auto &RegOps : MIUnits)
2112 SeenDbgInstrs[RegOps.first].emplace_back(&
MI,
2113 std::move(RegOps.second));
2118 if (
MI.isDebugOrPseudoInstr())
2125 if (!
MI.isCopy() || !
MI.getOperand(0).isRenamable()) {
2133 ModifiedRegUnits, UsedRegUnits)) {
2139 "Unexpect SrcReg or DefReg");
2150 "Unexpected predecessor");
2156 for (
auto &MO :
MI.all_defs()) {
2158 for (
const auto &
MIRegs : SeenDbgInstrs.lookup(Unit)) {
2159 auto &Regs = DbgValsToSinkMap[
MIRegs.first];
2161 Regs.push_back(
Reg);
2165 auto DbgValsToSink = DbgValsToSinkMap.
takeVector();
2174 LLVM_DEBUG(
dbgs() <<
" *** Not sinking: prologue interference\n");
2185 ++NumPostRACopySink;
2194 bool Changed =
false;
2198 ModifiedRegUnits.init(*
TRI);
2199 UsedRegUnits.init(*
TRI);
2201 Changed |= tryToSinkCopy(BB, MF,
TRI,
TII);
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder MachineInstrBuilder & DefMI
BlockVerifier::State From
COFF::MachineTypes Machine
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
const HexagonInstrInfo * TII
iv Induction Variable Users
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 void clearKillFlags(MachineInstr *MI, MachineBasicBlock &CurBB, SmallVectorImpl< unsigned > &UsedOpsInCopy, LiveRegUnits &UsedRegUnits, const TargetRegisterInfo *TRI)
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)
unsigned 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 mayLoadFromGOTOrConstantPool(MachineInstr &MI)
Return true if this machine instruction loads from global offset table or constant pool.
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 bool hasRegisterDependency(MachineInstr *MI, SmallVectorImpl< unsigned > &UsedOpsInCopy, SmallVectorImpl< unsigned > &DefedRegsInCopy, LiveRegUnits &ModifiedRegUnits, LiveRegUnits &UsedRegUnits)
static void updateLiveIn(MachineInstr *MI, MachineBasicBlock *SuccBB, SmallVectorImpl< unsigned > &UsedOpsInCopy, SmallVectorImpl< unsigned > &DefedRegsInCopy)
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 MachineBasicBlock * getSingleLiveInSuccBB(MachineBasicBlock &CurBB, const SmallPtrSetImpl< MachineBasicBlock * > &SinkableBBs, unsigned Reg, const TargetRegisterInfo *TRI)
static cl::opt< bool > UseBlockFreqInfo("machine-sink-bfi", cl::desc("Use block frequency info to find successors to sink"), cl::init(true), cl::Hidden)
std::pair< MachineInstr *, SmallVector< unsigned, 2 > > MIRegs
This file implements a map that provides insertion order iteration.
#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.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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 wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
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.
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),...
static DILocation * getMergedLocation(DILocation *LocA, DILocation *LocB)
When two instructions are combined into a single instruction we also need to combine the original loc...
Identifies a unique instance of a variable.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Implements a dense probed hash-table based set.
Base class for the actual dominator tree node.
iterator_range< iterator > children()
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
Instruction * findNearestCommonDominator(Instruction *I1, Instruction *I2) const
Find the nearest instruction I that dominates both I1 and I2, in the sense that a result produced bef...
bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
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.
A possibly irreducible generalization of a Loop.
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.
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(MCPhysReg Reg) const
Returns true if no part of physical register Reg is live.
void addLiveIns(const MachineBasicBlock &MBB)
Adds registers living into block MBB.
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()
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
iterator SkipPHIsAndLabels(iterator I)
Return the first instruction in MBB after I that is not a PHI or a label.
void removeLiveIn(MCRegister Reg, LaneBitmask LaneMask=LaneBitmask::getAll())
Remove the specified register from the live in set.
unsigned succ_size() const
void sortUniqueLiveIns()
Sorts and uniques the LiveIns vector.
pred_iterator pred_begin()
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()
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 '...
bool sizeWithoutDebugLargerThan(unsigned Limit) const
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...
BlockFrequency getBlockFreq(const MachineBasicBlock *MBB) const
getblockFreq - Return block frequency.
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.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
virtual MachineFunctionProperties getRequiredProperties() const
Properties which a MachineFunction may have at a given point in time.
MachineFunctionProperties & set(Property P)
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.
MachineInstr * CloneMachineInstr(const MachineInstr *Orig)
Create a new MachineInstr which is a copy of Orig, identical in all ways except the instruction has n...
Representation of each machine instruction.
static iterator_range< filter_iterator< Operand *, std::function< bool(Operand &Op)> > > getDebugOperandsForReg(Instruction *MI, Register Reg)
Returns a range of all of the operands that correspond to a debug use of Reg.
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.
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.
const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
const MachineOperand & getOperand(unsigned i) const
A description of a memory reference used in the backend.
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
bool readsReg() const
readsReg - Returns true if this operand reads the previous value of its register.
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,...
This class implements a map that also provides access to all stored values in a deterministic order.
VectorType takeVector()
Clear the MapVector and return the underlying vector.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
virtual void releaseMemory()
releaseMemory() - This member can be implemented by a pass if it wants to be able to release its memo...
PointerIntPair - This class implements a pair of a pointer and small integer.
An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
Analysis providing profile information.
Special value supplied for machine level alias analysis.
Track the current register pressure at some position in the instruction stream, and remember the high...
unsigned getRegPressureSetLimit(unsigned Idx) const
Get the register unit limit for the given pressure set index.
void runOnMachineFunction(const MachineFunction &MF)
runOnFunction - Prepare to answer questions about MF.
List of registers defined and used by a machine instruction.
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.
void clear()
Completely clear the SetVector.
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.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
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...
TargetSubtargetInfo - Generic base class for all target subtargets.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
virtual const TargetInstrInfo * getInstrInfo() const
std::pair< iterator, bool > insert(const ValueT &V)
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
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.
bool isCycleInvariant(const MachineCycle *Cycle, MachineInstr &I)
char & MachineSinkingID
MachineSinking - This pass performs sinking on machine instructions.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
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...
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)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
char & PostRAMachineSinkingID
This pass perform post-ra machine sink for COPY instructions.
void initializeMachineSinkingPass(PassRegistry &)
iterator_range< df_iterator< T > > depth_first(const T &G)
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
TODO: Might pack better if we changed this to a Struct of Arrays, since MachineOperand is width 32,...
Used to describe addressing mode similar to ExtAddrMode in CodeGenPrepare.
RegisterPressure computed within a region of instructions delimited by TopPos and BottomPos.
Represents a predicate at the MachineFunction level.