62#define DEBUG_TYPE "machinelicm"
66 cl::desc(
"MachineLICM should avoid speculation"),
71 cl::desc(
"MachineLICM should hoist even cheap instructions"),
87 cl::desc(
"Do not hoist instructions if target"
88 "block is N times hotter than the source."),
95 cl::desc(
"Disable hoisting instructions to"
99 "disable the feature"),
101 "enable the feature when using profile data"),
103 "enable the feature with/wo profile data")));
106 "Number of machine instructions hoisted out of loops");
108 "Number of instructions hoisted in low reg pressure situation");
110 "Number of high latency instructions hoisted");
112 "Number of hoisted machine instructions CSEed");
114 "Number of machine instructions hoisted out of loops post regalloc");
116 "Number of stores of const phys reg hoisted out of loops");
118 "Number of instructions not hoisted due to block frequency");
121 enum HoistResult { NotHoisted = 1, Hoisted = 2, ErasedMI = 4 };
123 class MachineLICMImpl {
124 const TargetInstrInfo *TII =
nullptr;
125 const TargetLoweringBase *TLI =
nullptr;
126 const TargetRegisterInfo *TRI =
nullptr;
127 const MachineFrameInfo *MFI =
nullptr;
128 MachineRegisterInfo *MRI =
nullptr;
129 const RegisterClassInfo *RegClassInfo =
nullptr;
130 TargetSchedModel SchedModel;
131 bool PreRegAlloc =
false;
132 bool HasProfileData =
false;
138 MachineBlockFrequencyInfo *MBFI =
nullptr;
139 MachineLoopInfo *MLI =
nullptr;
140 MachineDomTreeUpdater *MDTU =
nullptr;
143 bool Changed =
false;
144 bool FirstInLoop =
false;
148 SmallDenseMap<MachineLoop *, bool> AllowedToHoistLoads;
151 DenseMap<MachineLoop *, SmallVector<MachineBasicBlock *, 8>> ExitBlockMap;
153 bool isExitBlock(MachineLoop *CurLoop,
const MachineBasicBlock *
MBB) {
154 auto [It,
Inserted] = ExitBlockMap.try_emplace(CurLoop);
158 It->second = std::move(ExitBlocks);
164 SmallDenseSet<Register> RegSeen;
165 SmallVector<unsigned, 8> RegPressure;
169 SmallVector<unsigned, 8> RegLimit;
175 DenseMap<MachineBasicBlock *,
176 DenseMap<unsigned, std::vector<MachineInstr *>>>
182 SmallDenseMap<MachineLoop *, bool> GuaranteedToExecute;
185 MachineLICMImpl(
bool PreRegAlloc,
Pass *LegacyPass,
187 : PreRegAlloc(PreRegAlloc), LegacyPass(LegacyPass), MFAM(MFAM) {
188 assert((LegacyPass || MFAM) &&
"LegacyPass or MFAM must be provided");
189 assert(!(LegacyPass && MFAM) &&
190 "LegacyPass and MFAM cannot be provided at the same time");
195 void releaseMemory() {
201 ExitBlockMap.clear();
206 struct CandidateInfo {
211 CandidateInfo(MachineInstr *mi,
Register def,
int fi)
212 : MI(mi), Def(def), FI(fi) {}
215 void HoistRegionPostRA(MachineLoop *CurLoop);
217 void HoistPostRA(MachineInstr *
MI,
Register Def, MachineLoop *CurLoop);
219 void ProcessMI(MachineInstr *
MI, BitVector &RUDefs, BitVector &RUClobbers,
220 SmallDenseSet<int> &StoredFIs,
221 SmallVectorImpl<CandidateInfo> &Candidates,
222 MachineLoop *CurLoop);
224 void AddToLiveIns(MCRegister
Reg, MachineLoop *CurLoop);
226 bool IsLICMCandidate(MachineInstr &
I, MachineLoop *CurLoop);
228 bool IsLoopInvariantInst(MachineInstr &
I, MachineLoop *CurLoop);
230 bool HasLoopPHIUse(
const MachineInstr *
MI, MachineLoop *CurLoop);
232 bool HasHighOperandLatency(MachineInstr &
MI,
unsigned DefIdx,
Register Reg,
233 MachineLoop *CurLoop)
const;
235 bool IsCheapInstruction(MachineInstr &
MI)
const;
237 bool CanCauseHighRegPressure(
const SmallDenseMap<unsigned, int> &
Cost,
240 void UpdateBackTraceRegPressure(
const MachineInstr *
MI);
242 bool IsProfitableToHoist(MachineInstr &
MI, MachineLoop *CurLoop);
244 bool IsGuaranteedToExecute(MachineBasicBlock *BB, MachineLoop *CurLoop);
246 void EnterScope(MachineBasicBlock *
MBB);
248 void ExitScope(MachineBasicBlock *
MBB);
250 void ExitScopeIfDone(
252 DenseMap<MachineDomTreeNode *, unsigned> &OpenChildren,
253 const DenseMap<MachineDomTreeNode *, MachineDomTreeNode *> &ParentMap);
257 void InitRegPressure(MachineBasicBlock *BB);
259 SmallDenseMap<unsigned, int> calcRegisterCost(
const MachineInstr *
MI,
261 bool ConsiderUnseenAsDef);
263 void UpdateRegPressure(
const MachineInstr *
MI,
264 bool ConsiderUnseenAsDef =
false);
266 MachineInstr *ExtractHoistableLoad(MachineInstr *
MI, MachineLoop *CurLoop);
268 MachineInstr *LookForDuplicate(
const MachineInstr *
MI,
269 std::vector<MachineInstr *> &PrevMIs);
272 EliminateCSE(MachineInstr *
MI,
273 DenseMap<
unsigned, std::vector<MachineInstr *>>::iterator &CI);
275 bool MayCSE(MachineInstr *
MI);
277 unsigned Hoist(MachineInstr *
MI, MachineBasicBlock *Preheader,
278 MachineLoop *CurLoop);
280 void InitCSEMap(MachineBasicBlock *BB);
282 void InitializeLoadsHoistableLoops();
284 bool isTgtHotterThanSrc(MachineBasicBlock *SrcBlock,
285 MachineBasicBlock *TgtBlock);
286 MachineBasicBlock *getOrCreatePreheader(MachineLoop *CurLoop);
293 MachineLICMBase(
char &ID,
bool PreRegAlloc)
294 : MachineFunctionPass(
ID), PreRegAlloc(PreRegAlloc) {}
298 void getAnalysisUsage(AnalysisUsage &AU)
const override {
301 AU.
addRequired<LazyMachineBlockFrequencyInfoPass>();
303 AU.
addRequired<MachineRegisterClassInfoWrapperPass>();
312 class MachineLICM :
public MachineLICMBase {
315 MachineLICM() : MachineLICMBase(ID,
false) {}
318 class EarlyMachineLICM :
public MachineLICMBase {
321 EarlyMachineLICM() : MachineLICMBase(ID,
true) {}
327char EarlyMachineLICM::ID;
333 "Machine Loop Invariant Code Motion",
false,
false)
343 "Early Machine Loop Invariant Code Motion",
false,
false)
350 "Early Machine Loop Invariant Code Motion",
false,
false)
353 if (skipFunction(MF.getFunction()))
356 MachineLICMImpl Impl(PreRegAlloc,
this,
nullptr);
360#define GET_RESULT(RESULT, GETTER, INFIX) \
362 ? &LegacyPass->getAnalysis<RESULT##INFIX##WrapperPass>().GETTER() \
363 : &MFAM->getResult<RESULT##Analysis>(MF))
379 MachineDomTreeUpdater::UpdateStrategy::Lazy);
385 TII = ST.getInstrInfo();
386 TLI = ST.getTargetLowering();
387 TRI = ST.getRegisterInfo();
390 SchedModel.
init(&ST);
409 unsigned NumRPS =
TRI->getNumRegPressureSets();
410 RegPressure.resize(NumRPS);
413 for (
unsigned i = 0, e = NumRPS; i != e; ++i)
418 InitializeLoadsHoistableLoops();
421 while (!Worklist.
empty()) {
425 HoistRegionPostRA(CurLoop);
431 HoistOutOfLoop(
N, CurLoop);
447 if (
MI->memoperands_empty())
450 if (!
MemOp->isStore() || !
MemOp->getPseudoValue())
454 if (
Value->getFrameIndex() == FI)
495 const unsigned NumRegs =
TRI.getNumRegs();
496 const unsigned MaskWords = (NumRegs + 31) / 32;
497 for (
unsigned K = 0;
K < MaskWords; ++
K) {
499 for (
unsigned Bit = 0; Bit < 32; ++Bit) {
500 const unsigned PhysReg = (
K * 32) + Bit;
501 if (PhysReg == NumRegs)
504 if (PhysReg && !((Word >> Bit) & 1)) {
505 for (MCRegUnit Unit :
TRI.regunits(PhysReg))
506 RUsFromRegsNotInMask.
set(
static_cast<unsigned>(Unit));
511 RUs |= RUsFromRegsNotInMask;
516void MachineLICMImpl::ProcessMI(MachineInstr *
MI, BitVector &RUDefs,
517 BitVector &RUClobbers,
518 SmallDenseSet<int> &StoredFIs,
519 SmallVectorImpl<CandidateInfo> &Candidates,
520 MachineLoop *CurLoop) {
521 bool RuledOut =
false;
522 bool HasNonInvariantUse =
false;
524 for (
const MachineOperand &MO :
MI->operands()) {
527 int FI = MO.getIndex();
528 if (!StoredFIs.
count(FI) &&
532 HasNonInvariantUse =
true;
538 if (MO.isRegMask()) {
551 if (!HasNonInvariantUse) {
552 for (MCRegUnit Unit :
TRI->regunits(
Reg)) {
555 if (RUDefs.
test(
static_cast<unsigned>(Unit)) ||
556 RUClobbers.
test(
static_cast<unsigned>(Unit))) {
557 HasNonInvariantUse =
true;
576 for (MCRegUnit Unit :
TRI->regunits(
Reg)) {
577 if (RUDefs.
test(
static_cast<unsigned>(Unit))) {
578 RUClobbers.
set(
static_cast<unsigned>(Unit));
580 }
else if (RUClobbers.
test(
static_cast<unsigned>(Unit))) {
586 RUDefs.
set(
static_cast<unsigned>(Unit));
592 if (Def && !RuledOut) {
593 int FI = std::numeric_limits<int>::min();
594 if ((!HasNonInvariantUse && IsLICMCandidate(*
MI, CurLoop)) ||
602void MachineLICMImpl::HoistRegionPostRA(MachineLoop *CurLoop) {
603 MachineBasicBlock *Preheader = getOrCreatePreheader(CurLoop);
607 unsigned NumRegUnits =
TRI->getNumRegUnits();
608 BitVector RUDefs(NumRegUnits);
609 BitVector RUClobbers(NumRegUnits);
612 SmallDenseSet<int> StoredFIs;
616 for (MachineBasicBlock *BB : CurLoop->
getBlocks()) {
620 if (
ML &&
ML->getHeader()->isEHPad())
continue;
625 for (
const auto &LI : BB->liveins()) {
626 for (MCRegUnit Unit :
TRI->regunits(LI.PhysReg))
627 RUDefs.
set(
static_cast<unsigned>(Unit));
631 if (
const uint32_t *Mask = BB->getBeginClobberMask(
TRI))
641 for (MCRegUnit Unit :
TRI->regunits(
Reg))
642 RUClobbers.
set(
static_cast<unsigned>(Unit));
644 for (MCRegUnit Unit :
TRI->regunits(
Reg))
645 RUClobbers.
set(
static_cast<unsigned>(Unit));
648 GuaranteedToExecute.
clear();
649 for (MachineInstr &
MI : *BB)
650 ProcessMI(&
MI, RUDefs, RUClobbers, StoredFIs, Candidates, CurLoop);
654 BitVector TermRUs(NumRegUnits);
656 if (TI != Preheader->
end()) {
657 for (
const MachineOperand &MO : TI->operands()) {
663 for (MCRegUnit Unit :
TRI->regunits(
Reg))
664 TermRUs.set(
static_cast<unsigned>(Unit));
676 for (CandidateInfo &Candidate : Candidates) {
677 if (Candidate.FI != std::numeric_limits<int>::min() &&
678 StoredFIs.
count(Candidate.FI))
683 for (MCRegUnit Unit :
TRI->regunits(Def)) {
684 if (RUClobbers.
test(
static_cast<unsigned>(Unit)) ||
685 TermRUs.test(
static_cast<unsigned>(Unit))) {
694 MachineInstr *
MI = Candidate.MI;
695 for (
const MachineOperand &MO :
MI->all_uses()) {
698 for (MCRegUnit Unit :
TRI->regunits(MO.getReg())) {
699 if (RUDefs.
test(
static_cast<unsigned>(Unit)) ||
700 RUClobbers.
test(
static_cast<unsigned>(Unit))) {
713 HoistPostRA(
MI, Candidate.Def, CurLoop);
719void MachineLICMImpl::AddToLiveIns(MCRegister
Reg, MachineLoop *CurLoop) {
720 for (MachineBasicBlock *BB : CurLoop->
getBlocks()) {
721 if (!BB->isLiveIn(
Reg))
723 for (MachineInstr &
MI : *BB) {
724 for (MachineOperand &MO :
MI.all_uses()) {
727 if (
TRI->regsOverlap(
Reg, MO.getReg()))
736void MachineLICMImpl::HoistPostRA(MachineInstr *
MI,
Register Def,
737 MachineLoop *CurLoop) {
753 assert(!
MI->isDebugInstr() &&
"Should not hoist debug inst");
759 AddToLiveIns(Def, CurLoop);
767bool MachineLICMImpl::IsGuaranteedToExecute(MachineBasicBlock *BB,
768 MachineLoop *CurLoop) {
777 for (MachineBasicBlock *CurrentLoopExitingBlock : CurrentLoopExitingBlocks)
787void MachineLICMImpl::EnterScope(MachineBasicBlock *
MBB) {
794void MachineLICMImpl::ExitScope(MachineBasicBlock *
MBB) {
802void MachineLICMImpl::ExitScopeIfDone(
804 DenseMap<MachineDomTreeNode *, unsigned> &OpenChildren,
805 const DenseMap<MachineDomTreeNode *, MachineDomTreeNode *> &ParentMap) {
806 if (OpenChildren[Node])
810 ExitScope(
Node->getBlock());
813 if (!Parent || --OpenChildren[Parent] != 0)
824 MachineLoop *CurLoop) {
825 MachineBasicBlock *Preheader = getOrCreatePreheader(CurLoop);
831 DenseMap<MachineDomTreeNode*, MachineDomTreeNode*> ParentMap;
832 DenseMap<MachineDomTreeNode*, unsigned> OpenChildren;
836 while (!WorkList.
empty()) {
838 assert(Node &&
"Null dominator tree node?");
839 MachineBasicBlock *BB =
Node->getBlock();
844 if (
ML &&
ML->getHeader()->isEHPad())
857 OpenChildren[
Node] = 0;
864 size_t WorkListStart = WorkList.
size();
866 ParentMap[Child] =
Node;
869 std::reverse(WorkList.
begin() + WorkListStart, WorkList.
end());
870 OpenChildren[
Node] = WorkList.
size() - WorkListStart;
879 InitRegPressure(Preheader);
883 MachineBasicBlock *
MBB =
Node->getBlock();
888 GuaranteedToExecute.
clear();
890 unsigned HoistRes = HoistResult::NotHoisted;
891 HoistRes = Hoist(&
MI, Preheader, CurLoop);
892 if (HoistRes & HoistResult::NotHoisted) {
895 SmallVector<MachineLoop *> InnerLoopWorkList;
896 for (MachineLoop *L = MLI->
getLoopFor(
MI.getParent()); L != CurLoop;
897 L =
L->getParentLoop())
900 while (!InnerLoopWorkList.
empty()) {
901 MachineLoop *InnerLoop = InnerLoopWorkList.
pop_back_val();
903 if (InnerLoopPreheader) {
904 HoistRes = Hoist(&
MI, InnerLoopPreheader, InnerLoop);
905 if (HoistRes & HoistResult::Hoisted)
911 if (HoistRes & HoistResult::ErasedMI)
914 UpdateRegPressure(&
MI);
918 ExitScopeIfDone(Node, OpenChildren, ParentMap);
925void MachineLICMImpl::InitRegPressure(MachineBasicBlock *BB) {
933 MachineBasicBlock *
TBB =
nullptr, *FBB =
nullptr;
934 SmallVector<MachineOperand, 4>
Cond;
939 for (
const MachineInstr &
MI : *BB)
940 UpdateRegPressure(&
MI,
true);
944void MachineLICMImpl::UpdateRegPressure(
const MachineInstr *
MI,
945 bool ConsiderUnseenAsDef) {
946 auto Cost = calcRegisterCost(
MI,
true, ConsiderUnseenAsDef);
947 for (
const auto &[Class, Weight] :
Cost) {
948 if (
static_cast<int>(RegPressure[Class]) < -Weight)
961SmallDenseMap<unsigned, int>
962MachineLICMImpl::calcRegisterCost(
const MachineInstr *
MI,
bool ConsiderSeen,
963 bool ConsiderUnseenAsDef) {
964 SmallDenseMap<unsigned, int>
Cost;
965 if (
MI->isImplicitDef())
967 for (
unsigned i = 0, e =
MI->getDesc().getNumOperands(); i != e; ++i) {
968 const MachineOperand &MO =
MI->getOperand(i);
976 bool isNew = ConsiderSeen ? RegSeen.
insert(
Reg).second :
false;
979 RegClassWeight
W =
TRI->getRegClassWeight(RC);
982 RCCost =
W.RegWeight;
985 if (isNew && !isKill && ConsiderUnseenAsDef)
987 RCCost =
W.RegWeight;
988 else if (!isNew && isKill)
989 RCCost = -
W.RegWeight;
993 const int *PS =
TRI->getRegClassPressureSets(RC);
994 for (; *PS != -1; ++PS)
1003 assert(
MI.mayLoad() &&
"Expected MI that loads!");
1007 if (
MI.memoperands_empty())
1012 if (PSV->isGOT() || PSV->isConstantPool())
1029 bool FoundCallerPresReg =
false;
1030 if (!
MI.mayStore() ||
MI.hasUnmodeledSideEffects() ||
1031 (
MI.getNumOperands() == 0))
1040 if (
Reg.isVirtual())
1042 if (
Reg.isVirtual())
1044 if (!
TRI->isCallerPreservedPhysReg(
Reg.asMCReg(), *
MI.getMF()))
1047 FoundCallerPresReg =
true;
1048 }
else if (!MO.
isImm()) {
1052 return FoundCallerPresReg;
1070 Register CopySrcReg =
MI.getOperand(1).getReg();
1074 if (!
TRI->isCallerPreservedPhysReg(CopySrcReg.
asMCReg(), *MF))
1077 Register CopyDstReg =
MI.getOperand(0).getReg();
1090bool MachineLICMImpl::IsLICMCandidate(MachineInstr &
I, MachineLoop *CurLoop) {
1092 bool DontMoveAcrossStore = !
HoistConstLoads || !AllowedToHoistLoads[CurLoop];
1093 if ((!
I.isSafeToMove(DontMoveAcrossStore)) &&
1106 !IsGuaranteedToExecute(
I.getParent(), CurLoop)) {
1115 if (
I.isConvergent())
1118 if (!
TII->shouldHoist(
I, CurLoop))
1125bool MachineLICMImpl::IsLoopInvariantInst(MachineInstr &
I,
1126 MachineLoop *CurLoop) {
1127 if (!IsLICMCandidate(
I, CurLoop)) {
1128 LLVM_DEBUG(
dbgs() <<
"LICM: Instruction not a LICM candidate\n");
1136bool MachineLICMImpl::HasLoopPHIUse(
const MachineInstr *
MI,
1137 MachineLoop *CurLoop) {
1140 MI = Work.pop_back_val();
1141 for (
const MachineOperand &MO :
MI->all_defs()) {
1147 if (
UseMI.isPHI()) {
1161 Work.push_back(&
UseMI);
1164 }
while (!Work.empty());
1170bool MachineLICMImpl::HasHighOperandLatency(MachineInstr &
MI,
unsigned DefIdx,
1172 MachineLoop *CurLoop)
const {
1177 if (
UseMI.isCopyLike())
1181 for (
unsigned i = 0, e =
UseMI.getNumOperands(); i != e; ++i) {
1182 const MachineOperand &MO =
UseMI.getOperand(i);
1189 if (
TII->hasHighOperandLatency(SchedModel,
MRI,
MI, DefIdx,
UseMI, i))
1202bool MachineLICMImpl::IsCheapInstruction(MachineInstr &
MI)
const {
1206 bool isCheap =
false;
1207 unsigned NumDefs =
MI.getDesc().getNumDefs();
1208 for (
unsigned i = 0, e =
MI.getNumOperands(); NumDefs && i != e; ++i) {
1209 MachineOperand &DefMO =
MI.getOperand(i);
1217 if (!
TII->hasLowDefLatency(SchedModel,
MI, i))
1227bool MachineLICMImpl::CanCauseHighRegPressure(
1228 const SmallDenseMap<unsigned, int> &
Cost,
bool CheapInstr) {
1229 for (
const auto &[Class, Weight] :
Cost) {
1233 int Limit = RegLimit[
Class];
1240 for (
const auto &RP : BackTrace)
1241 if (
static_cast<int>(RP[Class]) + Weight >= Limit)
1251void MachineLICMImpl::UpdateBackTraceRegPressure(
const MachineInstr *
MI) {
1254 auto Cost = calcRegisterCost(
MI,
false,
1258 for (
auto &RP : BackTrace)
1259 for (
const auto &[Class, Weight] :
Cost)
1265bool MachineLICMImpl::IsProfitableToHoist(MachineInstr &
MI,
1266 MachineLoop *CurLoop) {
1267 if (
MI.isImplicitDef())
1285 bool CheapInstr = IsCheapInstruction(
MI);
1286 bool CreatesCopy = HasLoopPHIUse(&
MI, CurLoop);
1289 if (CheapInstr && CreatesCopy) {
1296 if (
TII->isTriviallyReMaterializable(
MI))
1301 for (
unsigned i = 0, e =
MI.getDesc().getNumOperands(); i != e; ++i) {
1302 const MachineOperand &MO =
MI.getOperand(i);
1308 if (MO.
isDef() && HasHighOperandLatency(
MI, i,
Reg, CurLoop)) {
1321 auto Cost = calcRegisterCost(&
MI,
false,
1326 if (!CanCauseHighRegPressure(
Cost, CheapInstr)) {
1342 (!IsGuaranteedToExecute(
MI.getParent(), CurLoop) && !MayCSE(&
MI))) {
1350 if (
MI.isCopy() ||
MI.isRegSequence()) {
1354 [
this](
const MachineOperand &UseOp) {
1355 return !UseOp.isReg() || UseOp.getReg().isVirtual() ||
1356 MRI->isConstantPhysReg(UseOp.getReg());
1358 IsLoopInvariantInst(
MI, CurLoop) &&
1360 [&CurLoop,
this, DefReg,
1362 if (!CurLoop->contains(&UseMI))
1369 if (CanCauseHighRegPressure(Cost, false) &&
1370 !CurLoop->isLoopInvariant(UseMI, DefReg))
1380 if (!
TII->isTriviallyReMaterializable(
MI) &&
1381 !
MI.isDereferenceableInvariantLoad()) {
1392MachineInstr *MachineLICMImpl::ExtractHoistableLoad(MachineInstr *
MI,
1393 MachineLoop *CurLoop) {
1395 if (
MI->canFoldAsLoad())
1401 if (!
MI->isDereferenceableInvariantLoad())
1405 unsigned LoadRegIndex;
1407 TII->getOpcodeAfterMemoryUnfold(
MI->getOpcode(),
1411 if (NewOpc == 0)
return nullptr;
1412 const MCInstrDesc &MID =
TII->get(NewOpc);
1418 SmallVector<MachineInstr *, 2> NewMIs;
1424 "unfoldMemoryOperand failed when getOpcodeAfterMemoryUnfold "
1427 "Unfolded a load into multiple instructions!");
1434 if (!IsLoopInvariantInst(*NewMIs[0], CurLoop) ||
1435 !IsProfitableToHoist(*NewMIs[0], CurLoop)) {
1436 NewMIs[0]->eraseFromParent();
1437 NewMIs[1]->eraseFromParent();
1442 UpdateRegPressure(NewMIs[1]);
1447 if (
MI->shouldUpdateAdditionalCallInfo())
1450 MI->eraseFromParent();
1457void MachineLICMImpl::InitCSEMap(MachineBasicBlock *BB) {
1458 for (MachineInstr &
MI : *BB)
1464void MachineLICMImpl::InitializeLoadsHoistableLoops() {
1470 while (!Worklist.empty()) {
1471 auto *
L = Worklist.pop_back_val();
1472 AllowedToHoistLoads[
L] =
true;
1485 for (
auto *
MBB :
Loop->blocks()) {
1487 if (!AllowedToHoistLoads[
Loop])
1489 for (
auto &
MI : *
MBB) {
1490 if (!
MI.isLoadFoldBarrier() && !
MI.mayStore() && !
MI.isCall() &&
1491 !(
MI.mayLoad() &&
MI.hasOrderedMemoryRef()))
1493 for (MachineLoop *L =
Loop;
L !=
nullptr;
L =
L->getParentLoop())
1494 AllowedToHoistLoads[
L] =
false;
1504MachineLICMImpl::LookForDuplicate(
const MachineInstr *
MI,
1505 std::vector<MachineInstr *> &PrevMIs) {
1506 for (MachineInstr *PrevMI : PrevMIs)
1507 if (
TII->produceSameValue(*
MI, *PrevMI, (PreRegAlloc ?
MRI :
nullptr)))
1517bool MachineLICMImpl::EliminateCSE(
1519 DenseMap<
unsigned, std::vector<MachineInstr *>>::iterator &CI) {
1522 if (
MI->isImplicitDef())
1527 if (
MI->mayLoad() && !
MI->isDereferenceableInvariantLoad())
1530 if (MachineInstr *Dup = LookForDuplicate(
MI, CI->second)) {
1535 SmallVector<unsigned, 2> Defs;
1536 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
1537 const MachineOperand &MO =
MI->getOperand(i);
1541 MO.
getReg() == Dup->getOperand(i).getReg()) &&
1542 "Instructions with different phys regs are not identical!");
1549 for (
unsigned i = 0, e = Defs.
size(); i != e; ++i) {
1550 unsigned Idx = Defs[i];
1552 Register DupReg = Dup->getOperand(Idx).getReg();
1557 for (
unsigned j = 0;
j != i; ++
j)
1563 for (
unsigned Idx : Defs) {
1565 Register DupReg = Dup->getOperand(Idx).getReg();
1569 Dup->getOperand(Idx).setIsDead(
false);
1572 MI->eraseFromParent();
1581bool MachineLICMImpl::MayCSE(MachineInstr *
MI) {
1582 if (
MI->mayLoad() && !
MI->isDereferenceableInvariantLoad())
1585 unsigned Opcode =
MI->getOpcode();
1586 for (
auto &Map : CSEMap) {
1589 DenseMap<unsigned, std::vector<MachineInstr *>>::iterator CI =
1590 Map.second.find(Opcode);
1593 if (CI ==
Map.second.end() ||
MI->isImplicitDef())
1595 if (LookForDuplicate(
MI, CI->second) !=
nullptr)
1606unsigned MachineLICMImpl::Hoist(MachineInstr *
MI, MachineBasicBlock *Preheader,
1607 MachineLoop *CurLoop) {
1608 MachineBasicBlock *SrcBlock =
MI->getParent();
1613 isTgtHotterThanSrc(SrcBlock, Preheader)) {
1614 ++NumNotHoistedDueToHotness;
1615 return HoistResult::NotHoisted;
1618 bool HasExtractHoistableLoad =
false;
1619 if (!IsLoopInvariantInst(*
MI, CurLoop) ||
1620 !IsProfitableToHoist(*
MI, CurLoop)) {
1622 MI = ExtractHoistableLoad(
MI, CurLoop);
1624 return HoistResult::NotHoisted;
1625 HasExtractHoistableLoad =
true;
1636 dbgs() <<
"Hoisting " << *
MI;
1637 if (
MI->getParent()->getBasicBlock())
1647 InitCSEMap(Preheader);
1648 FirstInLoop =
false;
1652 unsigned Opcode =
MI->getOpcode();
1653 bool HasCSEDone =
false;
1654 for (
auto &Map : CSEMap) {
1657 DenseMap<unsigned, std::vector<MachineInstr *>>::iterator CI =
1658 Map.second.find(Opcode);
1659 if (CI !=
Map.second.end()) {
1660 if (EliminateCSE(
MI, CI)) {
1675 assert(!
MI->isDebugInstr() &&
"Should not hoist debug inst");
1679 UpdateBackTraceRegPressure(
MI);
1681 CSEMap[Preheader][Opcode].push_back(
MI);
1687 if (HasCSEDone || HasExtractHoistableLoad)
1688 return HoistResult::Hoisted | HoistResult::ErasedMI;
1689 return HoistResult::Hoisted;
1693MachineBasicBlock *MachineLICMImpl::getOrCreatePreheader(MachineLoop *CurLoop) {
1702 MachineBasicBlock *NewPreheader =
Pred->SplitCriticalEdge(
1703 CurLoop->
getHeader(), {nullptr, nullptr, MLI}, MDTU);
1706 return NewPreheader;
1714bool MachineLICMImpl::isTgtHotterThanSrc(MachineBasicBlock *SrcBlock,
1715 MachineBasicBlock *TgtBlock) {
1724 double Ratio = (double)DstBF / SrcBF;
1730template <
typename DerivedT,
bool PreRegAlloc>
1733 bool Changed = MachineLICMImpl(PreRegAlloc,
nullptr, &MFAM).run(MF);