61#define DEBUG_TYPE "machinelicm"
65 cl::desc(
"MachineLICM should avoid speculation"),
70 cl::desc(
"MachineLICM should hoist even cheap instructions"),
86 cl::desc(
"Do not hoist instructions if target"
87 "block is N times hotter than the source."),
94 cl::desc(
"Disable hoisting instructions to"
98 "disable the feature"),
100 "enable the feature when using profile data"),
102 "enable the feature with/wo profile data")));
105 "Number of machine instructions hoisted out of loops");
107 "Number of instructions hoisted in low reg pressure situation");
109 "Number of high latency instructions hoisted");
111 "Number of hoisted machine instructions CSEed");
113 "Number of machine instructions hoisted out of loops post regalloc");
115 "Number of stores of const phys reg hoisted out of loops");
117 "Number of instructions not hoisted due to block frequency");
120 enum HoistResult { NotHoisted = 1, Hoisted = 2, ErasedMI = 4 };
122 class MachineLICMImpl {
123 const TargetInstrInfo *TII =
nullptr;
124 const TargetLoweringBase *TLI =
nullptr;
125 const TargetRegisterInfo *TRI =
nullptr;
126 const MachineFrameInfo *MFI =
nullptr;
127 MachineRegisterInfo *MRI =
nullptr;
128 const RegisterClassInfo *RegClassInfo =
nullptr;
129 TargetSchedModel SchedModel;
130 bool PreRegAlloc =
false;
131 bool HasProfileData =
false;
137 MachineBlockFrequencyInfo *MBFI =
nullptr;
138 MachineLoopInfo *MLI =
nullptr;
139 MachineDomTreeUpdater *MDTU =
nullptr;
142 bool Changed =
false;
143 bool FirstInLoop =
false;
147 SmallDenseMap<MachineLoop *, bool> AllowedToHoistLoads;
150 DenseMap<MachineLoop *, SmallVector<MachineBasicBlock *, 8>> ExitBlockMap;
152 bool isExitBlock(MachineLoop *CurLoop,
const MachineBasicBlock *
MBB) {
153 auto [It,
Inserted] = ExitBlockMap.try_emplace(CurLoop);
157 It->second = std::move(ExitBlocks);
163 SmallDenseSet<Register> RegSeen;
164 SmallVector<unsigned, 8> RegPressure;
168 SmallVector<unsigned, 8> RegLimit;
174 DenseMap<MachineBasicBlock *,
175 DenseMap<unsigned, std::vector<MachineInstr *>>>
187 unsigned SpeculationState = SpeculateUnknown;
190 MachineLICMImpl(
bool PreRegAlloc,
Pass *LegacyPass,
192 : PreRegAlloc(PreRegAlloc), LegacyPass(LegacyPass), MFAM(MFAM) {
193 assert((LegacyPass || MFAM) &&
"LegacyPass or MFAM must be provided");
194 assert(!(LegacyPass && MFAM) &&
195 "LegacyPass and MFAM cannot be provided at the same time");
200 void releaseMemory() {
206 ExitBlockMap.clear();
211 struct CandidateInfo {
216 CandidateInfo(MachineInstr *mi,
Register def,
int fi)
217 : MI(mi), Def(def), FI(fi) {}
220 void HoistRegionPostRA(MachineLoop *CurLoop);
222 void HoistPostRA(MachineInstr *
MI,
Register Def, MachineLoop *CurLoop);
224 void ProcessMI(MachineInstr *
MI, BitVector &RUDefs, BitVector &RUClobbers,
225 SmallDenseSet<int> &StoredFIs,
226 SmallVectorImpl<CandidateInfo> &Candidates,
227 MachineLoop *CurLoop);
229 void AddToLiveIns(MCRegister
Reg, MachineLoop *CurLoop);
231 bool IsLICMCandidate(MachineInstr &
I, MachineLoop *CurLoop);
233 bool IsLoopInvariantInst(MachineInstr &
I, MachineLoop *CurLoop);
235 bool HasLoopPHIUse(
const MachineInstr *
MI, MachineLoop *CurLoop);
237 bool HasHighOperandLatency(MachineInstr &
MI,
unsigned DefIdx,
Register Reg,
238 MachineLoop *CurLoop)
const;
240 bool IsCheapInstruction(MachineInstr &
MI)
const;
242 bool CanCauseHighRegPressure(
const SmallDenseMap<unsigned, int> &
Cost,
245 void UpdateBackTraceRegPressure(
const MachineInstr *
MI);
247 bool IsProfitableToHoist(MachineInstr &
MI, MachineLoop *CurLoop);
249 bool IsGuaranteedToExecute(MachineBasicBlock *BB, MachineLoop *CurLoop);
251 void EnterScope(MachineBasicBlock *
MBB);
253 void ExitScope(MachineBasicBlock *
MBB);
255 void ExitScopeIfDone(
257 DenseMap<MachineDomTreeNode *, unsigned> &OpenChildren,
258 const DenseMap<MachineDomTreeNode *, MachineDomTreeNode *> &ParentMap);
262 void InitRegPressure(MachineBasicBlock *BB);
264 SmallDenseMap<unsigned, int> calcRegisterCost(
const MachineInstr *
MI,
266 bool ConsiderUnseenAsDef);
268 void UpdateRegPressure(
const MachineInstr *
MI,
269 bool ConsiderUnseenAsDef =
false);
271 MachineInstr *ExtractHoistableLoad(MachineInstr *
MI, MachineLoop *CurLoop);
273 MachineInstr *LookForDuplicate(
const MachineInstr *
MI,
274 std::vector<MachineInstr *> &PrevMIs);
277 EliminateCSE(MachineInstr *
MI,
278 DenseMap<
unsigned, std::vector<MachineInstr *>>::iterator &CI);
280 bool MayCSE(MachineInstr *
MI);
282 unsigned Hoist(MachineInstr *
MI, MachineBasicBlock *Preheader,
283 MachineLoop *CurLoop);
285 void InitCSEMap(MachineBasicBlock *BB);
287 void InitializeLoadsHoistableLoops();
289 bool isTgtHotterThanSrc(MachineBasicBlock *SrcBlock,
290 MachineBasicBlock *TgtBlock);
291 MachineBasicBlock *getOrCreatePreheader(MachineLoop *CurLoop);
298 MachineLICMBase(
char &ID,
bool PreRegAlloc)
299 : MachineFunctionPass(
ID), PreRegAlloc(PreRegAlloc) {}
303 void getAnalysisUsage(AnalysisUsage &AU)
const override {
306 AU.
addRequired<MachineBlockFrequencyInfoWrapperPass>();
308 AU.
addRequired<MachineRegisterClassInfoWrapperPass>();
316 class MachineLICM :
public MachineLICMBase {
319 MachineLICM() : MachineLICMBase(ID,
false) {}
322 class EarlyMachineLICM :
public MachineLICMBase {
325 EarlyMachineLICM() : MachineLICMBase(ID,
true) {}
331char EarlyMachineLICM::ID;
337 "Machine Loop Invariant Code Motion",
false,
false)
347 "Early Machine Loop Invariant Code Motion",
false,
false)
354 "Early Machine Loop Invariant Code Motion",
false,
false)
357 if (skipFunction(MF.getFunction()))
360 MachineLICMImpl Impl(PreRegAlloc,
this,
nullptr);
364#define GET_RESULT(RESULT, GETTER, INFIX) \
366 ? &LegacyPass->getAnalysis<RESULT##INFIX##WrapperPass>().GETTER() \
367 : &MFAM->getResult<RESULT##Analysis>(MF))
383 MachineDomTreeUpdater::UpdateStrategy::Lazy);
387 ?
GET_RESULT(MachineBlockFrequency, getMBFI, Info)
392 TII = ST.getInstrInfo();
393 TLI = ST.getTargetLowering();
394 TRI = ST.getRegisterInfo();
397 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))
642 if (EH == ExceptionHandling::Default)
645 for (MCRegUnit Unit :
TRI->regunits(
Reg))
646 RUClobbers.
set(
static_cast<unsigned>(Unit));
648 for (MCRegUnit Unit :
TRI->regunits(
Reg))
649 RUClobbers.
set(
static_cast<unsigned>(Unit));
652 SpeculationState = SpeculateUnknown;
653 for (MachineInstr &
MI : *BB)
654 ProcessMI(&
MI, RUDefs, RUClobbers, StoredFIs, Candidates, CurLoop);
658 BitVector TermRUs(NumRegUnits);
660 if (TI != Preheader->
end()) {
661 for (
const MachineOperand &MO : TI->operands()) {
667 for (MCRegUnit Unit :
TRI->regunits(
Reg))
668 TermRUs.set(
static_cast<unsigned>(Unit));
680 for (CandidateInfo &Candidate : Candidates) {
681 if (Candidate.FI != std::numeric_limits<int>::min() &&
682 StoredFIs.
count(Candidate.FI))
687 for (MCRegUnit Unit :
TRI->regunits(Def)) {
688 if (RUClobbers.
test(
static_cast<unsigned>(Unit)) ||
689 TermRUs.test(
static_cast<unsigned>(Unit))) {
698 MachineInstr *
MI = Candidate.MI;
699 for (
const MachineOperand &MO :
MI->all_uses()) {
702 for (MCRegUnit Unit :
TRI->regunits(MO.getReg())) {
703 if (RUDefs.
test(
static_cast<unsigned>(Unit)) ||
704 RUClobbers.
test(
static_cast<unsigned>(Unit))) {
717 HoistPostRA(
MI, Candidate.Def, CurLoop);
723void MachineLICMImpl::AddToLiveIns(MCRegister
Reg, MachineLoop *CurLoop) {
724 for (MachineBasicBlock *BB : CurLoop->
getBlocks()) {
725 if (!BB->isLiveIn(
Reg))
727 for (MachineInstr &
MI : *BB) {
728 for (MachineOperand &MO :
MI.all_uses()) {
731 if (
TRI->regsOverlap(
Reg, MO.getReg()))
740void MachineLICMImpl::HoistPostRA(MachineInstr *
MI,
Register Def,
741 MachineLoop *CurLoop) {
757 assert(!
MI->isDebugInstr() &&
"Should not hoist debug inst");
763 AddToLiveIns(Def, CurLoop);
771bool MachineLICMImpl::IsGuaranteedToExecute(MachineBasicBlock *BB,
772 MachineLoop *CurLoop) {
773 if (SpeculationState != SpeculateUnknown)
774 return SpeculationState == SpeculateFalse;
780 for (MachineBasicBlock *CurrentLoopExitingBlock : CurrentLoopExitingBlocks)
782 SpeculationState = SpeculateTrue;
787 SpeculationState = SpeculateFalse;
791void MachineLICMImpl::EnterScope(MachineBasicBlock *
MBB) {
798void MachineLICMImpl::ExitScope(MachineBasicBlock *
MBB) {
806void MachineLICMImpl::ExitScopeIfDone(
808 DenseMap<MachineDomTreeNode *, unsigned> &OpenChildren,
809 const DenseMap<MachineDomTreeNode *, MachineDomTreeNode *> &ParentMap) {
810 if (OpenChildren[Node])
814 ExitScope(
Node->getBlock());
817 if (!Parent || --OpenChildren[Parent] != 0)
828 MachineLoop *CurLoop) {
829 MachineBasicBlock *Preheader = getOrCreatePreheader(CurLoop);
835 DenseMap<MachineDomTreeNode*, MachineDomTreeNode*> ParentMap;
836 DenseMap<MachineDomTreeNode*, unsigned> OpenChildren;
840 while (!WorkList.
empty()) {
842 assert(Node &&
"Null dominator tree node?");
843 MachineBasicBlock *BB =
Node->getBlock();
848 if (
ML &&
ML->getHeader()->isEHPad())
861 OpenChildren[
Node] = 0;
868 size_t WorkListStart = WorkList.
size();
870 ParentMap[Child] =
Node;
873 std::reverse(WorkList.
begin() + WorkListStart, WorkList.
end());
874 OpenChildren[
Node] = WorkList.
size() - WorkListStart;
883 InitRegPressure(Preheader);
887 MachineBasicBlock *
MBB =
Node->getBlock();
892 SpeculationState = SpeculateUnknown;
894 unsigned HoistRes = HoistResult::NotHoisted;
895 HoistRes = Hoist(&
MI, Preheader, CurLoop);
896 if (HoistRes & HoistResult::NotHoisted) {
899 SmallVector<MachineLoop *> InnerLoopWorkList;
900 for (MachineLoop *L = MLI->
getLoopFor(
MI.getParent()); L != CurLoop;
901 L =
L->getParentLoop())
904 while (!InnerLoopWorkList.
empty()) {
905 MachineLoop *InnerLoop = InnerLoopWorkList.
pop_back_val();
907 if (InnerLoopPreheader) {
908 HoistRes = Hoist(&
MI, InnerLoopPreheader, InnerLoop);
909 if (HoistRes & HoistResult::Hoisted)
915 if (HoistRes & HoistResult::ErasedMI)
918 UpdateRegPressure(&
MI);
922 ExitScopeIfDone(Node, OpenChildren, ParentMap);
933void MachineLICMImpl::InitRegPressure(MachineBasicBlock *BB) {
941 MachineBasicBlock *
TBB =
nullptr, *FBB =
nullptr;
942 SmallVector<MachineOperand, 4>
Cond;
947 for (
const MachineInstr &
MI : *BB)
948 UpdateRegPressure(&
MI,
true);
952void MachineLICMImpl::UpdateRegPressure(
const MachineInstr *
MI,
953 bool ConsiderUnseenAsDef) {
954 auto Cost = calcRegisterCost(
MI,
true, ConsiderUnseenAsDef);
955 for (
const auto &[Class, Weight] :
Cost) {
956 if (
static_cast<int>(RegPressure[Class]) < -Weight)
969SmallDenseMap<unsigned, int>
970MachineLICMImpl::calcRegisterCost(
const MachineInstr *
MI,
bool ConsiderSeen,
971 bool ConsiderUnseenAsDef) {
972 SmallDenseMap<unsigned, int>
Cost;
973 if (
MI->isImplicitDef())
975 for (
unsigned i = 0, e =
MI->getDesc().getNumOperands(); i != e; ++i) {
976 const MachineOperand &MO =
MI->getOperand(i);
984 bool isNew = ConsiderSeen ? RegSeen.
insert(
Reg).second :
false;
987 RegClassWeight
W =
TRI->getRegClassWeight(RC);
990 RCCost =
W.RegWeight;
993 if (isNew && !isKill && ConsiderUnseenAsDef)
995 RCCost =
W.RegWeight;
996 else if (!isNew && isKill)
997 RCCost = -
W.RegWeight;
1001 const int *PS =
TRI->getRegClassPressureSets(RC);
1002 for (; *PS != -1; ++PS)
1003 Cost[*PS] += RCCost;
1011 assert(
MI.mayLoad() &&
"Expected MI that loads!");
1015 if (
MI.memoperands_empty())
1020 if (PSV->isGOT() || PSV->isConstantPool())
1037 bool FoundCallerPresReg =
false;
1038 if (!
MI.mayStore() ||
MI.hasUnmodeledSideEffects() ||
1039 (
MI.getNumOperands() == 0))
1048 if (
Reg.isVirtual())
1050 if (
Reg.isVirtual())
1052 if (!
TRI->isCallerPreservedPhysReg(
Reg.asMCReg(), *
MI.getMF()))
1055 FoundCallerPresReg =
true;
1056 }
else if (!MO.
isImm()) {
1060 return FoundCallerPresReg;
1078 Register CopySrcReg =
MI.getOperand(1).getReg();
1082 if (!
TRI->isCallerPreservedPhysReg(CopySrcReg.
asMCReg(), *MF))
1085 Register CopyDstReg =
MI.getOperand(0).getReg();
1098bool MachineLICMImpl::IsLICMCandidate(MachineInstr &
I, MachineLoop *CurLoop) {
1100 bool DontMoveAcrossStore = !
HoistConstLoads || !AllowedToHoistLoads[CurLoop];
1101 if ((!
I.isSafeToMove(DontMoveAcrossStore)) &&
1114 !IsGuaranteedToExecute(
I.getParent(), CurLoop)) {
1123 if (
I.isConvergent())
1126 if (!
TII->shouldHoist(
I, CurLoop))
1133bool MachineLICMImpl::IsLoopInvariantInst(MachineInstr &
I,
1134 MachineLoop *CurLoop) {
1135 if (!IsLICMCandidate(
I, CurLoop)) {
1136 LLVM_DEBUG(
dbgs() <<
"LICM: Instruction not a LICM candidate\n");
1144bool MachineLICMImpl::HasLoopPHIUse(
const MachineInstr *
MI,
1145 MachineLoop *CurLoop) {
1148 MI = Work.pop_back_val();
1149 for (
const MachineOperand &MO :
MI->all_defs()) {
1155 if (
UseMI.isPHI()) {
1169 Work.push_back(&
UseMI);
1172 }
while (!Work.empty());
1178bool MachineLICMImpl::HasHighOperandLatency(MachineInstr &
MI,
unsigned DefIdx,
1180 MachineLoop *CurLoop)
const {
1185 if (
UseMI.isCopyLike())
1189 for (
unsigned i = 0, e =
UseMI.getNumOperands(); i != e; ++i) {
1190 const MachineOperand &MO =
UseMI.getOperand(i);
1197 if (
TII->hasHighOperandLatency(SchedModel, MRI,
MI, DefIdx,
UseMI, i))
1210bool MachineLICMImpl::IsCheapInstruction(MachineInstr &
MI)
const {
1214 bool isCheap =
false;
1215 unsigned NumDefs =
MI.getDesc().getNumDefs();
1216 for (
unsigned i = 0, e =
MI.getNumOperands(); NumDefs && i != e; ++i) {
1217 MachineOperand &DefMO =
MI.getOperand(i);
1225 if (!
TII->hasLowDefLatency(SchedModel,
MI, i))
1235bool MachineLICMImpl::CanCauseHighRegPressure(
1236 const SmallDenseMap<unsigned, int> &
Cost,
bool CheapInstr) {
1237 for (
const auto &[Class, Weight] :
Cost) {
1241 int Limit = RegLimit[
Class];
1248 for (
const auto &RP : BackTrace)
1249 if (
static_cast<int>(RP[Class]) + Weight >= Limit)
1259void MachineLICMImpl::UpdateBackTraceRegPressure(
const MachineInstr *
MI) {
1262 auto Cost = calcRegisterCost(
MI,
false,
1266 for (
auto &RP : BackTrace)
1267 for (
const auto &[Class, Weight] :
Cost)
1273bool MachineLICMImpl::IsProfitableToHoist(MachineInstr &
MI,
1274 MachineLoop *CurLoop) {
1275 if (
MI.isImplicitDef())
1293 bool CheapInstr = IsCheapInstruction(
MI);
1294 bool CreatesCopy = HasLoopPHIUse(&
MI, CurLoop);
1297 if (CheapInstr && CreatesCopy) {
1304 if (
TII->isTriviallyReMaterializable(
MI))
1309 for (
unsigned i = 0, e =
MI.getDesc().getNumOperands(); i != e; ++i) {
1310 const MachineOperand &MO =
MI.getOperand(i);
1316 if (MO.
isDef() && HasHighOperandLatency(
MI, i,
Reg, CurLoop)) {
1329 auto Cost = calcRegisterCost(&
MI,
false,
1334 if (!CanCauseHighRegPressure(
Cost, CheapInstr)) {
1350 (!IsGuaranteedToExecute(
MI.getParent(), CurLoop) && !MayCSE(&
MI))) {
1358 if (
MI.isCopy() ||
MI.isRegSequence()) {
1362 [
this](
const MachineOperand &UseOp) {
1363 return !UseOp.isReg() || UseOp.getReg().isVirtual() ||
1364 MRI->isConstantPhysReg(UseOp.getReg());
1366 IsLoopInvariantInst(
MI, CurLoop) &&
1368 [&CurLoop,
this, DefReg,
1370 if (!CurLoop->contains(&UseMI))
1377 if (CanCauseHighRegPressure(Cost, false) &&
1378 !CurLoop->isLoopInvariant(UseMI, DefReg))
1388 if (!
TII->isTriviallyReMaterializable(
MI) &&
1389 !
MI.isDereferenceableInvariantLoad()) {
1400MachineInstr *MachineLICMImpl::ExtractHoistableLoad(MachineInstr *
MI,
1401 MachineLoop *CurLoop) {
1403 if (
MI->canFoldAsLoad())
1409 if (!
MI->isDereferenceableInvariantLoad())
1413 unsigned LoadRegIndex;
1415 TII->getOpcodeAfterMemoryUnfold(
MI->getOpcode(),
1419 if (NewOpc == 0)
return nullptr;
1420 const MCInstrDesc &MID =
TII->get(NewOpc);
1426 SmallVector<MachineInstr *, 2> NewMIs;
1432 "unfoldMemoryOperand failed when getOpcodeAfterMemoryUnfold "
1435 "Unfolded a load into multiple instructions!");
1442 if (!IsLoopInvariantInst(*NewMIs[0], CurLoop) ||
1443 !IsProfitableToHoist(*NewMIs[0], CurLoop)) {
1444 NewMIs[0]->eraseFromParent();
1445 NewMIs[1]->eraseFromParent();
1450 UpdateRegPressure(NewMIs[1]);
1455 if (
MI->shouldUpdateAdditionalCallInfo())
1458 MI->eraseFromParent();
1465void MachineLICMImpl::InitCSEMap(MachineBasicBlock *BB) {
1466 for (MachineInstr &
MI : *BB)
1472void MachineLICMImpl::InitializeLoadsHoistableLoops() {
1478 while (!Worklist.empty()) {
1479 auto *
L = Worklist.pop_back_val();
1480 AllowedToHoistLoads[
L] =
true;
1493 for (
auto *
MBB :
Loop->blocks()) {
1495 if (!AllowedToHoistLoads[
Loop])
1497 for (
auto &
MI : *
MBB) {
1498 if (!
MI.isLoadFoldBarrier() && !
MI.mayStore() && !
MI.isCall() &&
1499 !(
MI.mayLoad() &&
MI.hasOrderedMemoryRef()))
1501 for (MachineLoop *L =
Loop;
L !=
nullptr;
L =
L->getParentLoop())
1502 AllowedToHoistLoads[
L] =
false;
1512MachineLICMImpl::LookForDuplicate(
const MachineInstr *
MI,
1513 std::vector<MachineInstr *> &PrevMIs) {
1514 for (MachineInstr *PrevMI : PrevMIs)
1515 if (
TII->produceSameValue(*
MI, *PrevMI, (PreRegAlloc ? MRI :
nullptr)))
1525bool MachineLICMImpl::EliminateCSE(
1527 DenseMap<
unsigned, std::vector<MachineInstr *>>::iterator &CI) {
1530 if (
MI->isImplicitDef())
1535 if (
MI->mayLoad() && !
MI->isDereferenceableInvariantLoad())
1538 if (MachineInstr *Dup = LookForDuplicate(
MI, CI->second)) {
1543 SmallVector<unsigned, 2> Defs;
1544 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
1545 const MachineOperand &MO =
MI->getOperand(i);
1549 MO.
getReg() == Dup->getOperand(i).getReg()) &&
1550 "Instructions with different phys regs are not identical!");
1557 for (
unsigned i = 0, e = Defs.
size(); i != e; ++i) {
1558 unsigned Idx = Defs[i];
1560 Register DupReg = Dup->getOperand(Idx).getReg();
1565 for (
unsigned j = 0;
j != i; ++
j)
1566 MRI->
setRegClass(Dup->getOperand(Defs[j]).getReg(), OrigRCs[j]);
1571 for (
unsigned Idx : Defs) {
1573 Register DupReg = Dup->getOperand(Idx).getReg();
1578 Dup->getOperand(Idx).setIsDead(
false);
1581 MI->eraseFromParent();
1590bool MachineLICMImpl::MayCSE(MachineInstr *
MI) {
1591 if (
MI->mayLoad() && !
MI->isDereferenceableInvariantLoad())
1594 unsigned Opcode =
MI->getOpcode();
1595 for (
auto &Map : CSEMap) {
1598 DenseMap<unsigned, std::vector<MachineInstr *>>::iterator CI =
1599 Map.second.find(Opcode);
1602 if (CI ==
Map.second.end() ||
MI->isImplicitDef())
1604 if (LookForDuplicate(
MI, CI->second) !=
nullptr)
1615unsigned MachineLICMImpl::Hoist(MachineInstr *
MI, MachineBasicBlock *Preheader,
1616 MachineLoop *CurLoop) {
1617 MachineBasicBlock *SrcBlock =
MI->getParent();
1622 isTgtHotterThanSrc(SrcBlock, Preheader)) {
1623 ++NumNotHoistedDueToHotness;
1624 return HoistResult::NotHoisted;
1627 bool HasExtractHoistableLoad =
false;
1628 if (!IsLoopInvariantInst(*
MI, CurLoop) ||
1629 !IsProfitableToHoist(*
MI, CurLoop)) {
1631 MI = ExtractHoistableLoad(
MI, CurLoop);
1633 return HoistResult::NotHoisted;
1634 HasExtractHoistableLoad =
true;
1645 dbgs() <<
"Hoisting " << *
MI;
1646 if (
MI->getParent()->getBasicBlock())
1656 InitCSEMap(Preheader);
1657 FirstInLoop =
false;
1661 unsigned Opcode =
MI->getOpcode();
1662 bool HasCSEDone =
false;
1663 for (
auto &Map : CSEMap) {
1666 DenseMap<unsigned, std::vector<MachineInstr *>>::iterator CI =
1667 Map.second.find(Opcode);
1668 if (CI !=
Map.second.end()) {
1669 if (EliminateCSE(
MI, CI)) {
1684 assert(!
MI->isDebugInstr() &&
"Should not hoist debug inst");
1688 UpdateBackTraceRegPressure(
MI);
1693 for (MachineOperand &MO :
MI->all_defs())
1697 CSEMap[Preheader][Opcode].push_back(
MI);
1703 if (HasCSEDone || HasExtractHoistableLoad)
1704 return HoistResult::Hoisted | HoistResult::ErasedMI;
1705 return HoistResult::Hoisted;
1709MachineBasicBlock *MachineLICMImpl::getOrCreatePreheader(MachineLoop *CurLoop) {
1718 MachineBasicBlock *NewPreheader = Pred->SplitCriticalEdge(
1719 CurLoop->
getHeader(), LegacyPass, MFAM,
nullptr, MDTU);
1722 return NewPreheader;
1730bool MachineLICMImpl::isTgtHotterThanSrc(MachineBasicBlock *SrcBlock,
1731 MachineBasicBlock *TgtBlock) {
1740 double Ratio = (double)DstBF / SrcBF;
1746template <
typename DerivedT,
bool PreRegAlloc>
1749 bool Changed = MachineLICMImpl(PreRegAlloc,
nullptr, &MFAM).run(MF);