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>();
311 class MachineLICM :
public MachineLICMBase {
314 MachineLICM() : MachineLICMBase(ID,
false) {}
317 class EarlyMachineLICM :
public MachineLICMBase {
320 EarlyMachineLICM() : MachineLICMBase(ID,
true) {}
326char EarlyMachineLICM::ID;
332 "Machine Loop Invariant Code Motion",
false,
false)
342 "Early Machine Loop Invariant Code Motion",
false,
false)
349 "Early Machine Loop Invariant Code Motion",
false,
false)
352 if (skipFunction(MF.getFunction()))
355 MachineLICMImpl Impl(PreRegAlloc,
this,
nullptr);
359#define GET_RESULT(RESULT, GETTER, INFIX) \
361 ? &LegacyPass->getAnalysis<RESULT##INFIX##WrapperPass>().GETTER() \
362 : &MFAM->getResult<RESULT##Analysis>(MF))
378 MachineDomTreeUpdater::UpdateStrategy::Lazy);
384 TII = ST.getInstrInfo();
385 TLI = ST.getTargetLowering();
386 TRI = ST.getRegisterInfo();
389 SchedModel.
init(&ST);
408 unsigned NumRPS =
TRI->getNumRegPressureSets();
409 RegPressure.resize(NumRPS);
412 for (
unsigned i = 0, e = NumRPS; i != e; ++i)
417 InitializeLoadsHoistableLoops();
420 while (!Worklist.
empty()) {
424 HoistRegionPostRA(CurLoop);
430 HoistOutOfLoop(
N, CurLoop);
446 if (
MI->memoperands_empty())
449 if (!
MemOp->isStore() || !
MemOp->getPseudoValue())
453 if (
Value->getFrameIndex() == FI)
494 const unsigned NumRegs =
TRI.getNumRegs();
495 const unsigned MaskWords = (NumRegs + 31) / 32;
496 for (
unsigned K = 0;
K < MaskWords; ++
K) {
498 for (
unsigned Bit = 0; Bit < 32; ++Bit) {
499 const unsigned PhysReg = (
K * 32) + Bit;
500 if (PhysReg == NumRegs)
503 if (PhysReg && !((Word >> Bit) & 1)) {
504 for (MCRegUnit Unit :
TRI.regunits(PhysReg))
505 RUsFromRegsNotInMask.
set(
static_cast<unsigned>(Unit));
510 RUs |= RUsFromRegsNotInMask;
515void MachineLICMImpl::ProcessMI(MachineInstr *
MI, BitVector &RUDefs,
516 BitVector &RUClobbers,
517 SmallDenseSet<int> &StoredFIs,
518 SmallVectorImpl<CandidateInfo> &Candidates,
519 MachineLoop *CurLoop) {
520 bool RuledOut =
false;
521 bool HasNonInvariantUse =
false;
523 for (
const MachineOperand &MO :
MI->operands()) {
526 int FI = MO.getIndex();
527 if (!StoredFIs.
count(FI) &&
531 HasNonInvariantUse =
true;
537 if (MO.isRegMask()) {
550 if (!HasNonInvariantUse) {
551 for (MCRegUnit Unit :
TRI->regunits(
Reg)) {
554 if (RUDefs.
test(
static_cast<unsigned>(Unit)) ||
555 RUClobbers.
test(
static_cast<unsigned>(Unit))) {
556 HasNonInvariantUse =
true;
575 for (MCRegUnit Unit :
TRI->regunits(
Reg)) {
576 if (RUDefs.
test(
static_cast<unsigned>(Unit))) {
577 RUClobbers.
set(
static_cast<unsigned>(Unit));
579 }
else if (RUClobbers.
test(
static_cast<unsigned>(Unit))) {
585 RUDefs.
set(
static_cast<unsigned>(Unit));
591 if (Def && !RuledOut) {
592 int FI = std::numeric_limits<int>::min();
593 if ((!HasNonInvariantUse && IsLICMCandidate(*
MI, CurLoop)) ||
601void MachineLICMImpl::HoistRegionPostRA(MachineLoop *CurLoop) {
602 MachineBasicBlock *Preheader = getOrCreatePreheader(CurLoop);
606 unsigned NumRegUnits =
TRI->getNumRegUnits();
607 BitVector RUDefs(NumRegUnits);
608 BitVector RUClobbers(NumRegUnits);
611 SmallDenseSet<int> StoredFIs;
615 for (MachineBasicBlock *BB : CurLoop->
getBlocks()) {
619 if (
ML &&
ML->getHeader()->isEHPad())
continue;
624 for (
const auto &LI : BB->liveins()) {
625 for (MCRegUnit Unit :
TRI->regunits(LI.PhysReg))
626 RUDefs.
set(
static_cast<unsigned>(Unit));
630 if (
const uint32_t *Mask = BB->getBeginClobberMask(
TRI))
640 for (MCRegUnit Unit :
TRI->regunits(
Reg))
641 RUClobbers.
set(
static_cast<unsigned>(Unit));
643 for (MCRegUnit Unit :
TRI->regunits(
Reg))
644 RUClobbers.
set(
static_cast<unsigned>(Unit));
647 GuaranteedToExecute.
clear();
648 for (MachineInstr &
MI : *BB)
649 ProcessMI(&
MI, RUDefs, RUClobbers, StoredFIs, Candidates, CurLoop);
653 BitVector TermRUs(NumRegUnits);
655 if (TI != Preheader->
end()) {
656 for (
const MachineOperand &MO : TI->operands()) {
662 for (MCRegUnit Unit :
TRI->regunits(
Reg))
663 TermRUs.set(
static_cast<unsigned>(Unit));
675 for (CandidateInfo &Candidate : Candidates) {
676 if (Candidate.FI != std::numeric_limits<int>::min() &&
677 StoredFIs.
count(Candidate.FI))
682 for (MCRegUnit Unit :
TRI->regunits(Def)) {
683 if (RUClobbers.
test(
static_cast<unsigned>(Unit)) ||
684 TermRUs.test(
static_cast<unsigned>(Unit))) {
693 MachineInstr *
MI = Candidate.MI;
694 for (
const MachineOperand &MO :
MI->all_uses()) {
697 for (MCRegUnit Unit :
TRI->regunits(MO.getReg())) {
698 if (RUDefs.
test(
static_cast<unsigned>(Unit)) ||
699 RUClobbers.
test(
static_cast<unsigned>(Unit))) {
712 HoistPostRA(
MI, Candidate.Def, CurLoop);
718void MachineLICMImpl::AddToLiveIns(MCRegister
Reg, MachineLoop *CurLoop) {
719 for (MachineBasicBlock *BB : CurLoop->
getBlocks()) {
720 if (!BB->isLiveIn(
Reg))
722 for (MachineInstr &
MI : *BB) {
723 for (MachineOperand &MO :
MI.all_uses()) {
726 if (
TRI->regsOverlap(
Reg, MO.getReg()))
735void MachineLICMImpl::HoistPostRA(MachineInstr *
MI,
Register Def,
736 MachineLoop *CurLoop) {
752 assert(!
MI->isDebugInstr() &&
"Should not hoist debug inst");
758 AddToLiveIns(Def, CurLoop);
766bool MachineLICMImpl::IsGuaranteedToExecute(MachineBasicBlock *BB,
767 MachineLoop *CurLoop) {
776 for (MachineBasicBlock *CurrentLoopExitingBlock : CurrentLoopExitingBlocks)
786void MachineLICMImpl::EnterScope(MachineBasicBlock *
MBB) {
793void MachineLICMImpl::ExitScope(MachineBasicBlock *
MBB) {
801void MachineLICMImpl::ExitScopeIfDone(
803 DenseMap<MachineDomTreeNode *, unsigned> &OpenChildren,
804 const DenseMap<MachineDomTreeNode *, MachineDomTreeNode *> &ParentMap) {
805 if (OpenChildren[Node])
809 ExitScope(
Node->getBlock());
812 if (!Parent || --OpenChildren[Parent] != 0)
823 MachineLoop *CurLoop) {
824 MachineBasicBlock *Preheader = getOrCreatePreheader(CurLoop);
830 DenseMap<MachineDomTreeNode*, MachineDomTreeNode*> ParentMap;
831 DenseMap<MachineDomTreeNode*, unsigned> OpenChildren;
835 while (!WorkList.
empty()) {
837 assert(Node &&
"Null dominator tree node?");
838 MachineBasicBlock *BB =
Node->getBlock();
843 if (
ML &&
ML->getHeader()->isEHPad())
856 OpenChildren[
Node] = 0;
863 size_t WorkListStart = WorkList.
size();
865 ParentMap[Child] =
Node;
868 std::reverse(WorkList.
begin() + WorkListStart, WorkList.
end());
869 OpenChildren[
Node] = WorkList.
size() - WorkListStart;
878 InitRegPressure(Preheader);
882 MachineBasicBlock *
MBB =
Node->getBlock();
887 GuaranteedToExecute.
clear();
889 unsigned HoistRes = HoistResult::NotHoisted;
890 HoistRes = Hoist(&
MI, Preheader, CurLoop);
891 if (HoistRes & HoistResult::NotHoisted) {
894 SmallVector<MachineLoop *> InnerLoopWorkList;
895 for (MachineLoop *L = MLI->
getLoopFor(
MI.getParent()); L != CurLoop;
896 L =
L->getParentLoop())
899 while (!InnerLoopWorkList.
empty()) {
900 MachineLoop *InnerLoop = InnerLoopWorkList.
pop_back_val();
902 if (InnerLoopPreheader) {
903 HoistRes = Hoist(&
MI, InnerLoopPreheader, InnerLoop);
904 if (HoistRes & HoistResult::Hoisted)
910 if (HoistRes & HoistResult::ErasedMI)
913 UpdateRegPressure(&
MI);
917 ExitScopeIfDone(Node, OpenChildren, ParentMap);
924void MachineLICMImpl::InitRegPressure(MachineBasicBlock *BB) {
932 MachineBasicBlock *
TBB =
nullptr, *FBB =
nullptr;
933 SmallVector<MachineOperand, 4>
Cond;
938 for (
const MachineInstr &
MI : *BB)
939 UpdateRegPressure(&
MI,
true);
943void MachineLICMImpl::UpdateRegPressure(
const MachineInstr *
MI,
944 bool ConsiderUnseenAsDef) {
945 auto Cost = calcRegisterCost(
MI,
true, ConsiderUnseenAsDef);
946 for (
const auto &[Class, Weight] :
Cost) {
947 if (
static_cast<int>(RegPressure[Class]) < -Weight)
960SmallDenseMap<unsigned, int>
961MachineLICMImpl::calcRegisterCost(
const MachineInstr *
MI,
bool ConsiderSeen,
962 bool ConsiderUnseenAsDef) {
963 SmallDenseMap<unsigned, int>
Cost;
964 if (
MI->isImplicitDef())
966 for (
unsigned i = 0, e =
MI->getDesc().getNumOperands(); i != e; ++i) {
967 const MachineOperand &MO =
MI->getOperand(i);
975 bool isNew = ConsiderSeen ? RegSeen.
insert(
Reg).second :
false;
978 RegClassWeight
W =
TRI->getRegClassWeight(RC);
981 RCCost =
W.RegWeight;
984 if (isNew && !isKill && ConsiderUnseenAsDef)
986 RCCost =
W.RegWeight;
987 else if (!isNew && isKill)
988 RCCost = -
W.RegWeight;
992 const int *PS =
TRI->getRegClassPressureSets(RC);
993 for (; *PS != -1; ++PS)
1002 assert(
MI.mayLoad() &&
"Expected MI that loads!");
1006 if (
MI.memoperands_empty())
1011 if (PSV->isGOT() || PSV->isConstantPool())
1028 bool FoundCallerPresReg =
false;
1029 if (!
MI.mayStore() ||
MI.hasUnmodeledSideEffects() ||
1030 (
MI.getNumOperands() == 0))
1039 if (
Reg.isVirtual())
1041 if (
Reg.isVirtual())
1043 if (!
TRI->isCallerPreservedPhysReg(
Reg.asMCReg(), *
MI.getMF()))
1046 FoundCallerPresReg =
true;
1047 }
else if (!MO.
isImm()) {
1051 return FoundCallerPresReg;
1069 Register CopySrcReg =
MI.getOperand(1).getReg();
1073 if (!
TRI->isCallerPreservedPhysReg(CopySrcReg.
asMCReg(), *MF))
1076 Register CopyDstReg =
MI.getOperand(0).getReg();
1089bool MachineLICMImpl::IsLICMCandidate(MachineInstr &
I, MachineLoop *CurLoop) {
1091 bool DontMoveAcrossStore = !
HoistConstLoads || !AllowedToHoistLoads[CurLoop];
1092 if ((!
I.isSafeToMove(DontMoveAcrossStore)) &&
1105 !IsGuaranteedToExecute(
I.getParent(), CurLoop)) {
1114 if (
I.isConvergent())
1117 if (!
TII->shouldHoist(
I, CurLoop))
1124bool MachineLICMImpl::IsLoopInvariantInst(MachineInstr &
I,
1125 MachineLoop *CurLoop) {
1126 if (!IsLICMCandidate(
I, CurLoop)) {
1127 LLVM_DEBUG(
dbgs() <<
"LICM: Instruction not a LICM candidate\n");
1135bool MachineLICMImpl::HasLoopPHIUse(
const MachineInstr *
MI,
1136 MachineLoop *CurLoop) {
1139 MI = Work.pop_back_val();
1140 for (
const MachineOperand &MO :
MI->all_defs()) {
1146 if (
UseMI.isPHI()) {
1160 Work.push_back(&
UseMI);
1163 }
while (!Work.empty());
1169bool MachineLICMImpl::HasHighOperandLatency(MachineInstr &
MI,
unsigned DefIdx,
1171 MachineLoop *CurLoop)
const {
1176 if (
UseMI.isCopyLike())
1180 for (
unsigned i = 0, e =
UseMI.getNumOperands(); i != e; ++i) {
1181 const MachineOperand &MO =
UseMI.getOperand(i);
1188 if (
TII->hasHighOperandLatency(SchedModel,
MRI,
MI, DefIdx,
UseMI, i))
1201bool MachineLICMImpl::IsCheapInstruction(MachineInstr &
MI)
const {
1205 bool isCheap =
false;
1206 unsigned NumDefs =
MI.getDesc().getNumDefs();
1207 for (
unsigned i = 0, e =
MI.getNumOperands(); NumDefs && i != e; ++i) {
1208 MachineOperand &DefMO =
MI.getOperand(i);
1216 if (!
TII->hasLowDefLatency(SchedModel,
MI, i))
1226bool MachineLICMImpl::CanCauseHighRegPressure(
1227 const SmallDenseMap<unsigned, int> &
Cost,
bool CheapInstr) {
1228 for (
const auto &[Class, Weight] :
Cost) {
1232 int Limit = RegLimit[
Class];
1239 for (
const auto &RP : BackTrace)
1240 if (
static_cast<int>(RP[Class]) + Weight >= Limit)
1250void MachineLICMImpl::UpdateBackTraceRegPressure(
const MachineInstr *
MI) {
1253 auto Cost = calcRegisterCost(
MI,
false,
1257 for (
auto &RP : BackTrace)
1258 for (
const auto &[Class, Weight] :
Cost)
1264bool MachineLICMImpl::IsProfitableToHoist(MachineInstr &
MI,
1265 MachineLoop *CurLoop) {
1266 if (
MI.isImplicitDef())
1284 bool CheapInstr = IsCheapInstruction(
MI);
1285 bool CreatesCopy = HasLoopPHIUse(&
MI, CurLoop);
1288 if (CheapInstr && CreatesCopy) {
1295 if (
TII->isTriviallyReMaterializable(
MI))
1300 for (
unsigned i = 0, e =
MI.getDesc().getNumOperands(); i != e; ++i) {
1301 const MachineOperand &MO =
MI.getOperand(i);
1307 if (MO.
isDef() && HasHighOperandLatency(
MI, i,
Reg, CurLoop)) {
1320 auto Cost = calcRegisterCost(&
MI,
false,
1325 if (!CanCauseHighRegPressure(
Cost, CheapInstr)) {
1341 (!IsGuaranteedToExecute(
MI.getParent(), CurLoop) && !MayCSE(&
MI))) {
1349 if (
MI.isCopy() ||
MI.isRegSequence()) {
1353 [
this](
const MachineOperand &UseOp) {
1354 return !UseOp.isReg() || UseOp.getReg().isVirtual() ||
1355 MRI->isConstantPhysReg(UseOp.getReg());
1357 IsLoopInvariantInst(
MI, CurLoop) &&
1359 [&CurLoop,
this, DefReg,
1361 if (!CurLoop->contains(&UseMI))
1368 if (CanCauseHighRegPressure(Cost, false) &&
1369 !CurLoop->isLoopInvariant(UseMI, DefReg))
1379 if (!
TII->isTriviallyReMaterializable(
MI) &&
1380 !
MI.isDereferenceableInvariantLoad()) {
1391MachineInstr *MachineLICMImpl::ExtractHoistableLoad(MachineInstr *
MI,
1392 MachineLoop *CurLoop) {
1394 if (
MI->canFoldAsLoad())
1400 if (!
MI->isDereferenceableInvariantLoad())
1404 unsigned LoadRegIndex;
1406 TII->getOpcodeAfterMemoryUnfold(
MI->getOpcode(),
1410 if (NewOpc == 0)
return nullptr;
1411 const MCInstrDesc &MID =
TII->get(NewOpc);
1417 SmallVector<MachineInstr *, 2> NewMIs;
1423 "unfoldMemoryOperand failed when getOpcodeAfterMemoryUnfold "
1426 "Unfolded a load into multiple instructions!");
1433 if (!IsLoopInvariantInst(*NewMIs[0], CurLoop) ||
1434 !IsProfitableToHoist(*NewMIs[0], CurLoop)) {
1435 NewMIs[0]->eraseFromParent();
1436 NewMIs[1]->eraseFromParent();
1441 UpdateRegPressure(NewMIs[1]);
1446 if (
MI->shouldUpdateAdditionalCallInfo())
1449 MI->eraseFromParent();
1456void MachineLICMImpl::InitCSEMap(MachineBasicBlock *BB) {
1457 for (MachineInstr &
MI : *BB)
1463void MachineLICMImpl::InitializeLoadsHoistableLoops() {
1469 while (!Worklist.empty()) {
1470 auto *
L = Worklist.pop_back_val();
1471 AllowedToHoistLoads[
L] =
true;
1484 for (
auto *
MBB :
Loop->blocks()) {
1486 if (!AllowedToHoistLoads[
Loop])
1488 for (
auto &
MI : *
MBB) {
1489 if (!
MI.isLoadFoldBarrier() && !
MI.mayStore() && !
MI.isCall() &&
1490 !(
MI.mayLoad() &&
MI.hasOrderedMemoryRef()))
1492 for (MachineLoop *L =
Loop;
L !=
nullptr;
L =
L->getParentLoop())
1493 AllowedToHoistLoads[
L] =
false;
1503MachineLICMImpl::LookForDuplicate(
const MachineInstr *
MI,
1504 std::vector<MachineInstr *> &PrevMIs) {
1505 for (MachineInstr *PrevMI : PrevMIs)
1506 if (
TII->produceSameValue(*
MI, *PrevMI, (PreRegAlloc ?
MRI :
nullptr)))
1516bool MachineLICMImpl::EliminateCSE(
1518 DenseMap<
unsigned, std::vector<MachineInstr *>>::iterator &CI) {
1521 if (
MI->isImplicitDef())
1526 if (
MI->mayLoad() && !
MI->isDereferenceableInvariantLoad())
1529 if (MachineInstr *Dup = LookForDuplicate(
MI, CI->second)) {
1534 SmallVector<unsigned, 2> Defs;
1535 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
1536 const MachineOperand &MO =
MI->getOperand(i);
1540 MO.
getReg() == Dup->getOperand(i).getReg()) &&
1541 "Instructions with different phys regs are not identical!");
1548 for (
unsigned i = 0, e = Defs.
size(); i != e; ++i) {
1549 unsigned Idx = Defs[i];
1551 Register DupReg = Dup->getOperand(Idx).getReg();
1556 for (
unsigned j = 0;
j != i; ++
j)
1562 for (
unsigned Idx : Defs) {
1564 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);
1684 for (MachineOperand &MO :
MI->all_defs())
1688 CSEMap[Preheader][Opcode].push_back(
MI);
1694 if (HasCSEDone || HasExtractHoistableLoad)
1695 return HoistResult::Hoisted | HoistResult::ErasedMI;
1696 return HoistResult::Hoisted;
1700MachineBasicBlock *MachineLICMImpl::getOrCreatePreheader(MachineLoop *CurLoop) {
1709 MachineBasicBlock *NewPreheader =
1710 Pred->SplitCriticalEdge(CurLoop->
getHeader(), LegacyPass, MFAM, MDTU);
1713 return NewPreheader;
1721bool MachineLICMImpl::isTgtHotterThanSrc(MachineBasicBlock *SrcBlock,
1722 MachineBasicBlock *TgtBlock) {
1731 double Ratio = (double)DstBF / SrcBF;
1737template <
typename DerivedT,
bool PreRegAlloc>
1740 bool Changed = MachineLICMImpl(PreRegAlloc,
nullptr, &MFAM).run(MF);