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",
106 cl::desc(
"The maximum number of instructions considered for cycle sinking."),
109STATISTIC(NumSunk,
"Number of machine instructions sunk");
110STATISTIC(NumCycleSunk,
"Number of machine instructions sunk into a cycle");
113STATISTIC(NumPostRACopySink,
"Number of copies sunk after RA");
148 using AllSuccsCache =
179 CachedRegisterPressure;
181 bool EnableSinkAndFold;
207 CEBCandidates.
clear();
208 CEMergeCandidates.
clear();
240 AllSuccsCache &AllSuccessors);
250 bool &LocalUse)
const;
252 bool &BreakPHIEdge, AllSuccsCache &AllSuccessors);
261 AllSuccsCache &AllSuccessors);
270 AllSuccsCache &AllSuccessors)
const;
274 bool registerPressureSetExceedsLimit(
unsigned NRegs,
281char MachineSinking::ID = 0;
286 "Machine code sinking",
false,
false)
305 if (!
TII->isBasicBlockPrologue(*PI))
307 for (
auto &MO :
MI.operands()) {
314 if (
Reg.isPhysical() &&
315 (
TII->isIgnorableUse(MO) || (
MRI &&
MRI->isConstantPhysReg(
Reg))))
317 if (PI->modifiesRegister(
Reg,
TRI))
320 if (PI->readsRegister(
Reg,
TRI))
323 auto *DefOp = PI->findRegisterDefOperand(
Reg,
TRI,
false,
true);
324 if (DefOp && !DefOp->isDead())
333bool MachineSinking::PerformTrivialForwardCoalescing(
MachineInstr &
MI,
341 !
MRI->hasOneNonDBGUse(SrcReg))
354 MRI->replaceRegWith(DstReg, SrcReg);
355 MI.eraseFromParent();
359 MRI->clearKillFlags(SrcReg);
367 if (
MI.isCopy() ||
MI.mayLoadOrStore() ||
368 MI.getOpcode() == TargetOpcode::REG_SEQUENCE)
376 bool SawStore =
true;
377 if (!
MI.isSafeToMove(SawStore))
382 if (
MI.isConvergent())
392 if (MO.isImm() || MO.isRegMask() || MO.isRegLiveOut() || MO.isMetadata() ||
393 MO.isMCSymbol() || MO.isDbgInstrRef() || MO.isCFIIndex() ||
394 MO.isIntrinsicID() || MO.isPredicate() || MO.isShuffleMask())
403 if (
Reg.isVirtual()) {
413 else if (UsedRegB == 0)
420 if (
Reg.isPhysical() && MO.isUse() &&
421 (
MRI->isConstantPhysReg(
Reg) ||
TII->isIgnorableUse(MO)))
431 using SinkInfo = std::pair<MachineInstr *, ExtAddrMode>;
437 UsedRegA == 0 ? nullptr :
MRI->getRegClass(UsedRegA);
439 UsedRegB == 0 ? nullptr :
MRI->getRegClass(UsedRegB);
442 while (!Worklist.
empty()) {
468 if (!
TII->canFoldIntoAddrMode(UseInst,
Reg,
MI, AM))
485 if (RCA ==
nullptr) {
490 unsigned NRegs = !!RCA + !!RCB;
496 if (RCB ==
nullptr) {
497 if (registerPressureSetExceedsLimit(NRegs, RCA,
MBB))
499 }
else if (registerPressureSetExceedsLimit(1, RCA,
MBB) ||
500 registerPressureSetExceedsLimit(1, RCB,
MBB)) {
510 if (SinkInto.
empty())
514 for (
auto &[SinkDst, MaybeAM] : SinkInto) {
518 if (SinkDst->isCopy()) {
531 Register DstReg = SinkDst->getOperand(0).getReg();
532 TII->reMaterialize(*SinkDst->getParent(), InsertPt, DstReg, 0,
MI, *
TRI);
533 New = &*std::prev(InsertPt);
534 if (!
New->getDebugLoc())
535 New->setDebugLoc(SinkDst->getDebugLoc());
541 MRI->clearKillFlags(UsedRegA);
543 MRI->clearKillFlags(UsedRegB);
546 New =
TII->emitLdStWithAddr(*SinkDst, MaybeAM);
552 MRI->clearKillFlags(R);
554 MRI->clearKillFlags(R);
558 if (SinkDst->mayStore() && !SinkDst->hasOrderedMemoryRef())
559 StoreInstrCache.
clear();
560 SinkDst->eraseFromParent();
568 while (!Worklist.
empty()) {
572 assert((
U->isCopy() ||
U->isDebugInstr()) &&
573 "Only debug uses and copies must remain");
575 Worklist.
push_back(
U->getOperand(0).getReg());
584 I->eraseFromParent();
591 MI.eraseFromParent();
599bool MachineSinking::AllUsesDominatedByBlock(
Register Reg,
603 bool &LocalUse)
const {
604 assert(
Reg.isVirtual() &&
"Only makes sense for vregs");
607 if (
MRI->use_nodbg_empty(
Reg))
625 MachineInstr *UseInst = MO.getParent();
626 unsigned OpNo = MO.getOperandNo();
627 MachineBasicBlock *UseBlock = UseInst->getParent();
628 return UseBlock == MBB && UseInst->isPHI() &&
629 UseInst->getOperand(OpNo + 1).getMBB() == DefMBB;
638 unsigned OpNo = &MO - &UseInst->
getOperand(0);
640 if (UseInst->
isPHI()) {
644 }
else if (UseBlock == DefMBB) {
660 assert(
MI.mayLoad() &&
"Expected MI that loads!");
664 if (
MI.memoperands_empty())
669 if (PSV->isGOT() || PSV->isConstantPool())
675void MachineSinking::FindCycleSinkCandidates(
678 for (
auto &
MI : *BB) {
681 LLVM_DEBUG(
dbgs() <<
"CycleSink: Instruction not a candidate for this "
686 LLVM_DEBUG(
dbgs() <<
"CycleSink: Instruction is not cycle invariant\n");
689 bool DontMoveAcrossStore =
true;
690 if (!
MI.isSafeToMove(DontMoveAcrossStore)) {
691 LLVM_DEBUG(
dbgs() <<
"CycleSink: Instruction not safe to move.\n");
695 LLVM_DEBUG(
dbgs() <<
"CycleSink: Dont sink GOT or constant pool loads\n");
698 if (
MI.isConvergent())
707 LLVM_DEBUG(
dbgs() <<
"CycleSink: Instruction added as candidate.\n");
722 DT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
723 PDT = &getAnalysis<MachinePostDominatorTreeWrapperPass>().getPostDomTree();
724 CI = &getAnalysis<MachineCycleInfoWrapperPass>().getCycleInfo();
726 ? &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI()
728 MBPI = &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
729 AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
734 bool EverMadeChange =
false;
737 bool MadeChange =
false;
740 CEBCandidates.
clear();
741 CEMergeCandidates.
clear();
747 for (
const auto &Pair : ToSplit) {
748 auto NewSucc = Pair.first->SplitCriticalEdge(Pair.second, *
this);
749 if (NewSucc !=
nullptr) {
764 if (!MadeChange)
break;
765 EverMadeChange =
true;
771 for (
auto *
Cycle : Cycles) {
778 FindCycleSinkCandidates(
Cycle, Preheader, Candidates);
786 LLVM_DEBUG(
dbgs() <<
"CycleSink: Limit reached of instructions to "
791 if (!SinkIntoCycle(
Cycle, *
I))
793 EverMadeChange =
true;
799 HasStoreCache.
clear();
800 StoreInstrCache.
clear();
803 for (
auto I : RegsToClearKillFlags)
804 MRI->clearKillFlags(
I);
805 RegsToClearKillFlags.clear();
807 return EverMadeChange;
819 bool MadeChange =
false;
822 AllSuccsCache AllSuccessors;
827 bool ProcessedBegin, SawStore =
false;
837 if (
MI.isDebugOrPseudoInstr()) {
838 if (
MI.isDebugValue())
843 if (EnableSinkAndFold && PerformSinkAndFold(
MI, &
MBB)) {
852 if (PerformTrivialForwardCoalescing(
MI, &
MBB)) {
863 }
while (!ProcessedBegin);
865 SeenDbgUsers.
clear();
868 CachedRegisterPressure.
clear();
875 assert(
MI.isDebugValue() &&
"Expected DBG_VALUE for processing");
878 MI.getDebugLoc()->getInlinedAt());
879 bool SeenBefore = SeenDbgVars.
contains(Var);
883 SeenDbgUsers[MO.
getReg()].push_back(SeenDbgUser(&
MI, SeenBefore));
890bool MachineSinking::isWorthBreakingCriticalEdge(
898 if (!CEBCandidates.
insert(std::make_pair(
From, To)).second)
909 for (
const auto &MO :
MI.all_defs()) {
914 auto Key = std::make_pair(SrcReg, To);
920 DeferredFromBlock = Res.first->second;
939 if (
Reg.isPhysical())
945 if (
MRI->hasOneNonDBGUse(
Reg)) {
971 if (FromCycle == ToCycle && FromCycle &&
1014 if (!BreakPHIEdge) {
1016 if (Pred != FromBB && !DT->
dominates(ToBB, Pred))
1026 bool BreakPHIEdge) {
1029 if (isWorthBreakingCriticalEdge(
MI, FromBB, ToBB, DeferredFromBB)) {
1032 if ((!DeferredFromBB ||
1033 ToSplit.count(std::make_pair(DeferredFromBB, ToBB)) ||
1034 isLegalToBreakCriticalEdge(
MI, DeferredFromBB, ToBB, BreakPHIEdge)) &&
1035 isLegalToBreakCriticalEdge(
MI, FromBB, ToBB, BreakPHIEdge)) {
1036 ToSplit.
insert(std::make_pair(FromBB, ToBB));
1038 ToSplit.insert(std::make_pair(DeferredFromBB, ToBB));
1046std::vector<unsigned> &
1052 auto RP = CachedRegisterPressure.
find(&
MBB);
1053 if (RP != CachedRegisterPressure.
end())
1065 MII != MIE; --MII) {
1067 if (
MI.isDebugInstr() ||
MI.isPseudoProbe())
1071 RPTracker.recedeSkipDebugValues();
1072 assert(&*RPTracker.getPos() == &
MI &&
"RPTracker sync error!");
1073 RPTracker.recede(RegOpers);
1076 RPTracker.closeRegion();
1077 auto It = CachedRegisterPressure.
insert(
1078 std::make_pair(&
MBB, RPTracker.getPressure().MaxSetPressure));
1079 return It.first->second;
1082bool MachineSinking::registerPressureSetExceedsLimit(
1085 unsigned Weight = NRegs *
TRI->getRegClassWeight(RC).RegWeight;
1086 const int *PS =
TRI->getRegClassPressureSets(RC);
1087 std::vector<unsigned> BBRegisterPressure = getBBRegisterPressure(
MBB);
1088 for (; *PS != -1; PS++)
1089 if (Weight + BBRegisterPressure[*PS] >=
1099 AllSuccsCache &AllSuccessors) {
1100 assert (SuccToSinkTo &&
"Invalid SinkTo Candidate BB");
1102 if (
MBB == SuccToSinkTo)
1115 bool NonPHIUse =
false;
1118 if (UseBlock == SuccToSinkTo && !UseInst.
isPHI())
1126 bool BreakPHIEdge =
false;
1129 FindSuccToSinkTo(
MI, SuccToSinkTo, BreakPHIEdge, AllSuccessors))
1130 return isProfitableToSinkTo(
Reg,
MI, SuccToSinkTo, MBB2, AllSuccessors);
1149 if (
Reg.isPhysical()) {
1151 if (MO.
isUse() && !
MRI->isConstantPhysReg(
Reg) && !
TII->isIgnorableUse(MO))
1159 bool LocalUse =
false;
1160 if (!AllUsesDominatedByBlock(
Reg, SuccToSinkTo,
MBB, BreakPHIEdge,
1178 if (registerPressureSetExceedsLimit(1,
MRI->getRegClass(
Reg),
1180 LLVM_DEBUG(
dbgs() <<
"register pressure exceed limit, not profitable.");
1196 AllSuccsCache &AllSuccessors)
const {
1198 auto Succs = AllSuccessors.find(
MBB);
1199 if (Succs != AllSuccessors.end())
1200 return Succs->second;
1213 if (DTChild->getIDom()->getBlock() ==
MI.getParent() &&
1216 AllSuccs.push_back(DTChild->getBlock());
1224 bool HasBlockFreq = LHSFreq != 0 || RHSFreq != 0;
1225 return HasBlockFreq ? LHSFreq < RHSFreq
1229 auto it = AllSuccessors.insert(std::make_pair(
MBB, AllSuccs));
1231 return it.first->second;
1238 AllSuccsCache &AllSuccessors) {
1239 assert (
MBB &&
"Invalid MachineBasicBlock!");
1248 if (!MO.
isReg())
continue;
1251 if (
Reg == 0)
continue;
1253 if (
Reg.isPhysical()) {
1258 if (!
MRI->isConstantPhysReg(
Reg) && !
TII->isIgnorableUse(MO))
1260 }
else if (!MO.
isDead()) {
1266 if (MO.
isUse())
continue;
1269 if (!
TII->isSafeToMoveRegClassDefs(
MRI->getRegClass(
Reg)))
1277 bool LocalUse =
false;
1278 if (!AllUsesDominatedByBlock(
Reg, SuccToSinkTo,
MBB,
1279 BreakPHIEdge, LocalUse))
1290 GetAllSortedSuccessors(
MI,
MBB, AllSuccessors)) {
1291 bool LocalUse =
false;
1292 if (AllUsesDominatedByBlock(
Reg, SuccBlock,
MBB,
1293 BreakPHIEdge, LocalUse)) {
1294 SuccToSinkTo = SuccBlock;
1305 if (!isProfitableToSinkTo(
Reg,
MI,
MBB, SuccToSinkTo, AllSuccessors))
1312 if (
MBB == SuccToSinkTo)
1317 if (SuccToSinkTo && SuccToSinkTo->
isEHPad())
1327 if (SuccToSinkTo && !
TII->isSafeToSink(
MI, SuccToSinkTo, CI))
1330 return SuccToSinkTo;
1345 auto *
MBB =
MI.getParent();
1350 auto *PredBB = PredMBB->getBasicBlock();
1356 !PredBB->getTerminator()->getMetadata(LLVMContext::MD_make_implicit))
1361 bool OffsetIsScalable;
1362 if (!
TII->getMemOperandWithOffset(
MI, BaseOp,
Offset, OffsetIsScalable,
TRI))
1365 if (!BaseOp->
isReg())
1368 if (!(
MI.mayLoad() && !
MI.isPredicable()))
1371 MachineBranchPredicate MBP;
1372 if (
TII->analyzeBranchPredicate(*PredMBB, MBP,
false))
1375 return MBP.LHS.isReg() && MBP.RHS.isImm() && MBP.RHS.getImm() == 0 &&
1376 (MBP.Predicate == MachineBranchPredicate::PRED_NE ||
1377 MBP.Predicate == MachineBranchPredicate::PRED_EQ) &&
1378 MBP.LHS.getReg() == BaseOp->
getReg();
1395 auto CopyOperands =
TII.isCopyInstr(SinkInst);
1398 SrcMO = CopyOperands->Source;
1399 DstMO = CopyOperands->Destination;
1402 bool PostRA =
MRI.getNumVirtRegs() == 0;
1410 bool arePhysRegs = !
Reg.isVirtual();
1411 if (arePhysRegs != PostRA)
1418 if (DbgMO.getSubReg() != SrcMO->
getSubReg() ||
1419 DbgMO.getSubReg() != DstMO->getSubReg())
1425 if (PostRA &&
Reg != DstMO->getReg())
1429 DbgMO.setReg(SrcMO->
getReg());
1435using MIRegs = std::pair<MachineInstr *, SmallVector<unsigned, 2>>;
1443 if (!SuccToSinkTo.
empty() && InsertPos != SuccToSinkTo.
end())
1445 InsertPos->getDebugLoc()));
1451 SuccToSinkTo.
splice(InsertPos, ParentBlock,
MI,
1458 for (
const auto &DbgValueToSink : DbgValuesToSink) {
1461 SuccToSinkTo.
insert(InsertPos, NewDbgMI);
1463 bool PropagatedAllSunkOps =
true;
1464 for (
unsigned Reg : DbgValueToSink.second) {
1467 PropagatedAllSunkOps =
false;
1472 if (!PropagatedAllSunkOps)
1486 auto BlockPair = std::make_pair(
From, To);
1490 if (
auto It = HasStoreCache.
find(BlockPair); It != HasStoreCache.
end())
1493 if (
auto It = StoreInstrCache.
find(BlockPair); It != StoreInstrCache.
end())
1495 return I->mayAlias(AA, MI, false);
1498 bool SawStore =
false;
1499 bool HasAliasedStore =
false;
1508 if (BB == To || BB ==
From)
1512 if (HandledBlocks.
count(BB))
1515 HandledBlocks.
insert(BB);
1518 if (!HandledDomBlocks.
count(BB))
1519 HandledDomBlocks.
insert(BB);
1525 for (
auto *DomBB : HandledDomBlocks) {
1526 if (DomBB != BB && DT->
dominates(DomBB, BB))
1527 HasStoreCache[std::make_pair(DomBB, To)] =
true;
1528 else if(DomBB != BB && DT->
dominates(BB, DomBB))
1529 HasStoreCache[std::make_pair(
From, DomBB)] =
true;
1531 HasStoreCache[BlockPair] =
true;
1538 if (
I.isCall() ||
I.hasOrderedMemoryRef()) {
1539 for (
auto *DomBB : HandledDomBlocks) {
1540 if (DomBB != BB && DT->
dominates(DomBB, BB))
1541 HasStoreCache[std::make_pair(DomBB, To)] =
true;
1542 else if(DomBB != BB && DT->
dominates(BB, DomBB))
1543 HasStoreCache[std::make_pair(
From, DomBB)] =
true;
1545 HasStoreCache[BlockPair] =
true;
1555 if (
I.mayAlias(AA,
MI,
false))
1556 HasAliasedStore =
true;
1557 StoreInstrCache[BlockPair].push_back(&
I);
1564 HasStoreCache[BlockPair] =
false;
1565 return HasAliasedStore;
1574 assert(Preheader &&
"Cycle sink needs a preheader block");
1576 bool CanSink =
true;
1582 LLVM_DEBUG(
dbgs() <<
"CycleSink: Use not in cycle, can't sink.\n");
1597 SinkBlock =
MI.getParent();
1604 LLVM_DEBUG(
dbgs() <<
"CycleSink: Can't find nearest dominator\n");
1608 LLVM_DEBUG(
dbgs() <<
"CycleSink: Setting nearest common dom block: " <<
1617 LLVM_DEBUG(
dbgs() <<
"CycleSink: Not sinking, can't find sink block.\n");
1620 if (SinkBlock == Preheader) {
1622 dbgs() <<
"CycleSink: Not sinking, sink block is the preheader\n");
1627 dbgs() <<
"CycleSink: Not Sinking, block too large to analyse.\n");
1638 RegsToClearKillFlags.insert(MO.
getReg());
1643 assert(!
I.isDebugInstr() &&
"Should not sink debug inst");
1650bool MachineSinking::SinkInstruction(
MachineInstr &
MI,
bool &SawStore,
1651 AllSuccsCache &AllSuccessors) {
1657 if (!
MI.isSafeToMove(SawStore))
1662 if (
MI.isConvergent())
1678 bool BreakPHIEdge =
false;
1681 FindSuccToSinkTo(
MI, ParentBlock, BreakPHIEdge, AllSuccessors);
1692 if (
Reg == 0 || !
Reg.isPhysical())
1698 LLVM_DEBUG(
dbgs() <<
"Sink instr " <<
MI <<
"\tinto block " << *SuccToSinkTo);
1705 bool TryBreak =
false;
1707 MI.mayLoad() ? hasStoreBetween(ParentBlock, SuccToSinkTo,
MI) :
true;
1708 if (!
MI.isSafeToMove(Store)) {
1709 LLVM_DEBUG(
dbgs() <<
" *** NOTE: Won't sink load along critical edge.\n");
1715 if (!TryBreak && !DT->
dominates(ParentBlock, SuccToSinkTo)) {
1721 if (!TryBreak && CI->
getCycle(SuccToSinkTo) &&
1736 PostponeSplitCriticalEdge(
MI, ParentBlock, SuccToSinkTo, BreakPHIEdge);
1739 "break critical edge\n");
1749 bool Status = PostponeSplitCriticalEdge(
MI, ParentBlock,
1750 SuccToSinkTo, BreakPHIEdge);
1753 "break critical edge\n");
1762 LLVM_DEBUG(
dbgs() <<
" *** Not sinking: prologue interference\n");
1768 for (
auto &MO :
MI.all_defs()) {
1778 if (
User.getInt()) {
1793 if (
MI.getMF()->getFunction().getSubprogram() &&
MI.isCopy())
1794 SalvageUnsunkDebugUsersOfCopy(
MI, SuccToSinkTo);
1804 RegsToClearKillFlags.insert(MO.
getReg());
1809void MachineSinking::SalvageUnsunkDebugUsersOfCopy(
1820 for (
auto &MO :
MI.all_defs()) {
1829 if (
User.getParent() ==
MI.getParent())
1833 "DBG_VALUE user of vreg, but has no operand for it?");
1840 for (
auto *
User : DbgDefUsers) {
1841 for (
auto &
Reg : DbgUseRegs) {
1842 for (
auto &
DbgOp :
User->getDebugOperandsForReg(
Reg)) {
1843 DbgOp.setReg(
MI.getOperand(1).getReg());
1844 DbgOp.setSubReg(
MI.getOperand(1).getSubReg());
1901 MachineFunctionProperties::Property::NoVRegs);
1921char PostRAMachineSinking::ID = 0;
1925 "PostRA Machine Sink",
false,
false)
1940 for (
auto *SI : SinkableBBs) {
1941 if (aliasWithRegsInLiveIn(*SI,
Reg,
TRI)) {
1955 if (!SinkableBBs.
count(SI) && aliasWithRegsInLiveIn(*SI,
Reg,
TRI))
1967 for (
auto DefReg : DefedRegsInCopy) {
1970 if (!BB || (SingleBB && SingleBB != BB))
1981 for (
auto U : UsedOpsInCopy) {
1987 if (UI.killsRegister(SrcReg,
TRI)) {
1988 UI.clearRegisterKills(SrcReg,
TRI);
2002 for (
unsigned DefReg : DefedRegsInCopy)
2005 for (
auto U : UsedOpsInCopy)
2015 bool HasRegDependency =
false;
2016 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
2025 HasRegDependency =
true;
2034 }
else if (MO.
isUse()) {
2036 HasRegDependency =
true;
2042 return HasRegDependency;
2054 if (!
SI->livein_empty() &&
SI->pred_size() == 1)
2057 if (SinkableBBs.
empty())
2060 bool Changed =
false;
2064 ModifiedRegUnits.clear();
2065 UsedRegUnits.clear();
2066 SeenDbgInstrs.clear();
2076 if (
MI.isDebugValue() && !
MI.isDebugRef()) {
2078 bool IsValid =
true;
2084 ModifiedRegUnits, UsedRegUnits)) {
2091 MIUnits[Unit].push_back(MO.
getReg());
2095 for (
auto &RegOps : MIUnits)
2096 SeenDbgInstrs[RegOps.first].emplace_back(&
MI,
2097 std::move(RegOps.second));
2102 if (
MI.isDebugOrPseudoInstr())
2109 if (!
MI.isCopy() || !
MI.getOperand(0).isRenamable()) {
2117 ModifiedRegUnits, UsedRegUnits)) {
2123 "Unexpect SrcReg or DefReg");
2134 "Unexpected predecessor");
2140 for (
auto &MO :
MI.all_defs()) {
2142 for (
const auto &
MIRegs : SeenDbgInstrs.lookup(Unit)) {
2143 auto &Regs = DbgValsToSinkMap[
MIRegs.first];
2145 Regs.push_back(
Reg);
2149 auto DbgValsToSink = DbgValsToSinkMap.
takeVector();
2157 dbgs() <<
" *** Not sinking: prologue interference\n");
2168 ++NumPostRACopySink;
2177 bool Changed =
false;
2181 ModifiedRegUnits.init(*
TRI);
2182 UsedRegUnits.init(*
TRI);
2184 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)
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< unsigned > SinkIntoCycleLimit("machine-sink-cycle-limit", cl::desc("The maximum number of instructions considered for cycle sinking."), cl::init(50), cl::Hidden)
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.
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
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.
const_toplevel_iterator toplevel_end() 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.
const_toplevel_iterator toplevel_begin() const
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.
bool isLiveIn(MCPhysReg Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in 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 '...
void removeLiveIn(MCPhysReg Reg, LaneBitmask LaneMask=LaneBitmask::getAll())
Remove the specified register from the live in set.
bool sizeWithoutDebugLargerThan(unsigned Limit) const
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...
MachineBasicBlock * findNearestCommonDominator(MachineBasicBlock *A, MachineBasicBlock *B)
findNearestCommonDominator - Find nearest common dominator basic block for basic block A and B.
bool isReachableFromEntry(const MachineBasicBlock *A)
isReachableFromEntry - Return true if A is dominated by the entry block of the function containing it...
MachineDomTreeNode * getNode(MachineBasicBlock *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
bool dominates(const MachineDomTreeNode *A, const MachineDomTreeNode *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.
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.
Special value supplied for machine level alias analysis.
Track the current register pressure at some position in the instruction stream, and remember the high...
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.
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.