60#define DEBUG_TYPE "machinelicm"
64 cl::desc(
"MachineLICM should avoid speculation"),
69 cl::desc(
"MachineLICM should hoist even cheap instructions"),
85 cl::desc(
"Do not hoist instructions if target"
86 "block is N times hotter than the source."),
93 cl::desc(
"Disable hoisting instructions to"
97 "disable the feature"),
99 "enable the feature when using profile data"),
101 "enable the feature with/wo profile data")));
104 "Number of machine instructions hoisted out of loops");
106 "Number of instructions hoisted in low reg pressure situation");
108 "Number of high latency instructions hoisted");
110 "Number of hoisted machine instructions CSEed");
112 "Number of machine instructions hoisted out of loops post regalloc");
114 "Number of stores of const phys reg hoisted out of loops");
116 "Number of instructions not hoisted due to block frequency");
119 enum HoistResult { NotHoisted = 1, Hoisted = 2, ErasedMI = 4 };
121 class MachineLICMImpl {
122 const TargetInstrInfo *TII =
nullptr;
123 const TargetLoweringBase *TLI =
nullptr;
124 const TargetRegisterInfo *TRI =
nullptr;
125 const MachineFrameInfo *MFI =
nullptr;
126 MachineRegisterInfo *MRI =
nullptr;
127 const RegisterClassInfo *RegClassInfo =
nullptr;
128 TargetSchedModel SchedModel;
129 bool PreRegAlloc =
false;
130 bool HasProfileData =
false;
136 MachineBlockFrequencyInfo *MBFI =
nullptr;
137 MachineLoopInfo *MLI =
nullptr;
138 MachineDomTreeUpdater *MDTU =
nullptr;
141 bool Changed =
false;
142 bool FirstInLoop =
false;
146 SmallDenseMap<MachineLoop *, bool> AllowedToHoistLoads;
149 DenseMap<MachineLoop *, SmallVector<MachineBasicBlock *, 8>> ExitBlockMap;
151 bool isExitBlock(MachineLoop *CurLoop,
const MachineBasicBlock *
MBB) {
152 auto [It,
Inserted] = ExitBlockMap.try_emplace(CurLoop);
156 It->second = std::move(ExitBlocks);
162 SmallDenseSet<Register> RegSeen;
163 SmallVector<unsigned, 8> RegPressure;
167 SmallVector<unsigned, 8> RegLimit;
173 DenseMap<MachineBasicBlock *,
174 DenseMap<unsigned, std::vector<MachineInstr *>>>
186 unsigned SpeculationState = SpeculateUnknown;
189 MachineLICMImpl(
bool PreRegAlloc,
Pass *LegacyPass,
191 : PreRegAlloc(PreRegAlloc), LegacyPass(LegacyPass), MFAM(MFAM) {
192 assert((LegacyPass || MFAM) &&
"LegacyPass or MFAM must be provided");
193 assert(!(LegacyPass && MFAM) &&
194 "LegacyPass and MFAM cannot be provided at the same time");
199 void releaseMemory() {
205 ExitBlockMap.clear();
210 struct CandidateInfo {
215 CandidateInfo(MachineInstr *mi,
Register def,
int fi)
216 : MI(mi), Def(def), FI(fi) {}
219 void HoistRegionPostRA(MachineLoop *CurLoop);
221 void HoistPostRA(MachineInstr *
MI,
Register Def, MachineLoop *CurLoop);
223 void ProcessMI(MachineInstr *
MI, BitVector &RUDefs, BitVector &RUClobbers,
224 SmallDenseSet<int> &StoredFIs,
225 SmallVectorImpl<CandidateInfo> &Candidates,
226 MachineLoop *CurLoop);
228 void AddToLiveIns(MCRegister
Reg, MachineLoop *CurLoop);
230 bool IsLICMCandidate(MachineInstr &
I, MachineLoop *CurLoop);
232 bool IsLoopInvariantInst(MachineInstr &
I, MachineLoop *CurLoop);
234 bool HasLoopPHIUse(
const MachineInstr *
MI, MachineLoop *CurLoop);
236 bool HasHighOperandLatency(MachineInstr &
MI,
unsigned DefIdx,
Register Reg,
237 MachineLoop *CurLoop)
const;
239 bool IsCheapInstruction(MachineInstr &
MI)
const;
241 bool CanCauseHighRegPressure(
const SmallDenseMap<unsigned, int> &
Cost,
244 void UpdateBackTraceRegPressure(
const MachineInstr *
MI);
246 bool IsProfitableToHoist(MachineInstr &
MI, MachineLoop *CurLoop);
248 bool IsGuaranteedToExecute(MachineBasicBlock *BB, MachineLoop *CurLoop);
250 void EnterScope(MachineBasicBlock *
MBB);
252 void ExitScope(MachineBasicBlock *
MBB);
254 void ExitScopeIfDone(
256 DenseMap<MachineDomTreeNode *, unsigned> &OpenChildren,
257 const DenseMap<MachineDomTreeNode *, MachineDomTreeNode *> &ParentMap);
261 void InitRegPressure(MachineBasicBlock *BB);
263 SmallDenseMap<unsigned, int> calcRegisterCost(
const MachineInstr *
MI,
265 bool ConsiderUnseenAsDef);
267 void UpdateRegPressure(
const MachineInstr *
MI,
268 bool ConsiderUnseenAsDef =
false);
270 MachineInstr *ExtractHoistableLoad(MachineInstr *
MI, MachineLoop *CurLoop);
272 MachineInstr *LookForDuplicate(
const MachineInstr *
MI,
273 std::vector<MachineInstr *> &PrevMIs);
276 EliminateCSE(MachineInstr *
MI,
277 DenseMap<
unsigned, std::vector<MachineInstr *>>::iterator &CI);
279 bool MayCSE(MachineInstr *
MI);
281 unsigned Hoist(MachineInstr *
MI, MachineBasicBlock *Preheader,
282 MachineLoop *CurLoop);
284 void InitCSEMap(MachineBasicBlock *BB);
286 void InitializeLoadsHoistableLoops();
288 bool isTgtHotterThanSrc(MachineBasicBlock *SrcBlock,
289 MachineBasicBlock *TgtBlock);
290 MachineBasicBlock *getOrCreatePreheader(MachineLoop *CurLoop);
297 MachineLICMBase(
char &ID,
bool PreRegAlloc)
298 : MachineFunctionPass(
ID), PreRegAlloc(PreRegAlloc) {}
302 void getAnalysisUsage(AnalysisUsage &AU)
const override {
305 AU.
addRequired<MachineBlockFrequencyInfoWrapperPass>();
307 AU.
addRequired<MachineRegisterClassInfoWrapperPass>();
315 class MachineLICM :
public MachineLICMBase {
318 MachineLICM() : MachineLICMBase(ID,
false) {}
321 class EarlyMachineLICM :
public MachineLICMBase {
324 EarlyMachineLICM() : MachineLICMBase(ID,
true) {}
330char EarlyMachineLICM::ID;
336 "Machine Loop Invariant Code Motion",
false,
false)
346 "Early Machine Loop Invariant Code Motion",
false,
false)
353 "Early Machine Loop Invariant Code Motion",
false,
false)
356 if (skipFunction(MF.getFunction()))
359 MachineLICMImpl Impl(PreRegAlloc,
this,
nullptr);
363#define GET_RESULT(RESULT, GETTER, INFIX) \
365 ? &LegacyPass->getAnalysis<RESULT##INFIX##WrapperPass>().GETTER() \
366 : &MFAM->getResult<RESULT##Analysis>(MF))
382 MachineDomTreeUpdater::UpdateStrategy::Lazy);
386 ?
GET_RESULT(MachineBlockFrequency, getMBFI, Info)
391 TII = ST.getInstrInfo();
392 TLI = ST.getTargetLowering();
393 TRI = ST.getRegisterInfo();
396 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));
644 for (MCRegUnit Unit :
TRI->regunits(
Reg))
645 RUClobbers.
set(
static_cast<unsigned>(Unit));
648 SpeculationState = SpeculateUnknown;
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) {
747 MachineBasicBlock *
MBB =
MI->getParent();
753 assert(!
MI->isDebugInstr() &&
"Should not hoist debug inst");
759 AddToLiveIns(Def, CurLoop);
767bool MachineLICMImpl::IsGuaranteedToExecute(MachineBasicBlock *BB,
768 MachineLoop *CurLoop) {
769 if (SpeculationState != SpeculateUnknown)
770 return SpeculationState == SpeculateFalse;
776 for (MachineBasicBlock *CurrentLoopExitingBlock : CurrentLoopExitingBlocks)
778 SpeculationState = SpeculateTrue;
783 SpeculationState = SpeculateFalse;
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 SpeculationState = SpeculateUnknown;
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);
929void MachineLICMImpl::InitRegPressure(MachineBasicBlock *BB) {
937 MachineBasicBlock *
TBB =
nullptr, *FBB =
nullptr;
943 for (
const MachineInstr &
MI : *BB)
944 UpdateRegPressure(&
MI,
true);
948void MachineLICMImpl::UpdateRegPressure(
const MachineInstr *
MI,
949 bool ConsiderUnseenAsDef) {
950 auto Cost = calcRegisterCost(
MI,
true, ConsiderUnseenAsDef);
951 for (
const auto &[Class, Weight] :
Cost) {
952 if (
static_cast<int>(RegPressure[Class]) < -Weight)
965SmallDenseMap<unsigned, int>
966MachineLICMImpl::calcRegisterCost(
const MachineInstr *
MI,
bool ConsiderSeen,
967 bool ConsiderUnseenAsDef) {
968 SmallDenseMap<unsigned, int>
Cost;
969 if (
MI->isImplicitDef())
971 for (
unsigned i = 0, e =
MI->getDesc().getNumOperands(); i != e; ++i) {
972 const MachineOperand &MO =
MI->getOperand(i);
980 bool isNew = ConsiderSeen ? RegSeen.
insert(
Reg).second :
false;
983 RegClassWeight
W =
TRI->getRegClassWeight(RC);
986 RCCost =
W.RegWeight;
989 if (isNew && !isKill && ConsiderUnseenAsDef)
991 RCCost =
W.RegWeight;
992 else if (!isNew && isKill)
993 RCCost = -
W.RegWeight;
997 const int *PS =
TRI->getRegClassPressureSets(RC);
998 for (; *PS != -1; ++PS)
1007 assert(
MI.mayLoad() &&
"Expected MI that loads!");
1011 if (
MI.memoperands_empty())
1016 if (PSV->isGOT() || PSV->isConstantPool())
1033 bool FoundCallerPresReg =
false;
1034 if (!
MI.mayStore() ||
MI.hasUnmodeledSideEffects() ||
1035 (
MI.getNumOperands() == 0))
1044 if (
Reg.isVirtual())
1046 if (
Reg.isVirtual())
1048 if (!
TRI->isCallerPreservedPhysReg(
Reg.asMCReg(), *
MI.getMF()))
1051 FoundCallerPresReg =
true;
1052 }
else if (!MO.
isImm()) {
1056 return FoundCallerPresReg;
1074 Register CopySrcReg =
MI.getOperand(1).getReg();
1078 if (!
TRI->isCallerPreservedPhysReg(CopySrcReg.
asMCReg(), *MF))
1081 Register CopyDstReg =
MI.getOperand(0).getReg();
1094bool MachineLICMImpl::IsLICMCandidate(MachineInstr &
I, MachineLoop *CurLoop) {
1096 bool DontMoveAcrossStore = !
HoistConstLoads || !AllowedToHoistLoads[CurLoop];
1097 if ((!
I.isSafeToMove(DontMoveAcrossStore)) &&
1110 !IsGuaranteedToExecute(
I.getParent(), CurLoop)) {
1119 if (
I.isConvergent())
1122 if (!
TII->shouldHoist(
I, CurLoop))
1129bool MachineLICMImpl::IsLoopInvariantInst(MachineInstr &
I,
1130 MachineLoop *CurLoop) {
1131 if (!IsLICMCandidate(
I, CurLoop)) {
1132 LLVM_DEBUG(
dbgs() <<
"LICM: Instruction not a LICM candidate\n");
1140bool MachineLICMImpl::HasLoopPHIUse(
const MachineInstr *
MI,
1141 MachineLoop *CurLoop) {
1144 MI = Work.pop_back_val();
1145 for (
const MachineOperand &MO :
MI->all_defs()) {
1151 if (
UseMI.isPHI()) {
1165 Work.push_back(&
UseMI);
1168 }
while (!Work.empty());
1174bool MachineLICMImpl::HasHighOperandLatency(MachineInstr &
MI,
unsigned DefIdx,
1176 MachineLoop *CurLoop)
const {
1181 if (
UseMI.isCopyLike())
1185 for (
unsigned i = 0, e =
UseMI.getNumOperands(); i != e; ++i) {
1186 const MachineOperand &MO =
UseMI.getOperand(i);
1193 if (
TII->hasHighOperandLatency(SchedModel, MRI,
MI, DefIdx,
UseMI, i))
1206bool MachineLICMImpl::IsCheapInstruction(MachineInstr &
MI)
const {
1210 bool isCheap =
false;
1211 unsigned NumDefs =
MI.getDesc().getNumDefs();
1212 for (
unsigned i = 0, e =
MI.getNumOperands(); NumDefs && i != e; ++i) {
1213 MachineOperand &DefMO =
MI.getOperand(i);
1221 if (!
TII->hasLowDefLatency(SchedModel,
MI, i))
1231bool MachineLICMImpl::CanCauseHighRegPressure(
1232 const SmallDenseMap<unsigned, int> &
Cost,
bool CheapInstr) {
1233 for (
const auto &[Class, Weight] :
Cost) {
1237 int Limit = RegLimit[
Class];
1244 for (
const auto &RP : BackTrace)
1245 if (
static_cast<int>(RP[Class]) + Weight >= Limit)
1255void MachineLICMImpl::UpdateBackTraceRegPressure(
const MachineInstr *
MI) {
1258 auto Cost = calcRegisterCost(
MI,
false,
1262 for (
auto &RP : BackTrace)
1263 for (
const auto &[Class, Weight] :
Cost)
1269bool MachineLICMImpl::IsProfitableToHoist(MachineInstr &
MI,
1270 MachineLoop *CurLoop) {
1271 if (
MI.isImplicitDef())
1289 bool CheapInstr = IsCheapInstruction(
MI);
1290 bool CreatesCopy = HasLoopPHIUse(&
MI, CurLoop);
1293 if (CheapInstr && CreatesCopy) {
1300 if (
TII->isTriviallyReMaterializable(
MI))
1305 for (
unsigned i = 0, e =
MI.getDesc().getNumOperands(); i != e; ++i) {
1306 const MachineOperand &MO =
MI.getOperand(i);
1312 if (MO.
isDef() && HasHighOperandLatency(
MI, i,
Reg, CurLoop)) {
1325 auto Cost = calcRegisterCost(&
MI,
false,
1330 if (!CanCauseHighRegPressure(
Cost, CheapInstr)) {
1346 (!IsGuaranteedToExecute(
MI.getParent(), CurLoop) && !MayCSE(&
MI))) {
1354 if (
MI.isCopy() ||
MI.isRegSequence()) {
1358 [
this](
const MachineOperand &UseOp) {
1359 return !UseOp.isReg() || UseOp.getReg().isVirtual() ||
1360 MRI->isConstantPhysReg(UseOp.getReg());
1362 IsLoopInvariantInst(
MI, CurLoop) &&
1364 [&CurLoop,
this, DefReg,
1366 if (!CurLoop->contains(&UseMI))
1373 if (CanCauseHighRegPressure(Cost, false) &&
1374 !CurLoop->isLoopInvariant(UseMI, DefReg))
1384 if (!
TII->isTriviallyReMaterializable(
MI) &&
1385 !
MI.isDereferenceableInvariantLoad()) {
1396MachineInstr *MachineLICMImpl::ExtractHoistableLoad(MachineInstr *
MI,
1397 MachineLoop *CurLoop) {
1399 if (
MI->canFoldAsLoad())
1405 if (!
MI->isDereferenceableInvariantLoad())
1409 unsigned LoadRegIndex;
1411 TII->getOpcodeAfterMemoryUnfold(
MI->getOpcode(),
1415 if (NewOpc == 0)
return nullptr;
1416 const MCInstrDesc &MID =
TII->get(NewOpc);
1422 SmallVector<MachineInstr *, 2> NewMIs;
1428 "unfoldMemoryOperand failed when getOpcodeAfterMemoryUnfold "
1431 "Unfolded a load into multiple instructions!");
1432 MachineBasicBlock *
MBB =
MI->getParent();
1438 if (!IsLoopInvariantInst(*NewMIs[0], CurLoop) ||
1439 !IsProfitableToHoist(*NewMIs[0], CurLoop)) {
1440 NewMIs[0]->eraseFromParent();
1441 NewMIs[1]->eraseFromParent();
1446 UpdateRegPressure(NewMIs[1]);
1451 if (
MI->shouldUpdateAdditionalCallInfo())
1454 MI->eraseFromParent();
1461void MachineLICMImpl::InitCSEMap(MachineBasicBlock *BB) {
1462 for (MachineInstr &
MI : *BB)
1468void MachineLICMImpl::InitializeLoadsHoistableLoops() {
1474 while (!Worklist.empty()) {
1475 auto *
L = Worklist.pop_back_val();
1476 AllowedToHoistLoads[
L] =
true;
1489 for (
auto *
MBB :
Loop->blocks()) {
1491 if (!AllowedToHoistLoads[
Loop])
1493 for (
auto &
MI : *
MBB) {
1494 if (!
MI.isLoadFoldBarrier() && !
MI.mayStore() && !
MI.isCall() &&
1495 !(
MI.mayLoad() &&
MI.hasOrderedMemoryRef()))
1497 for (MachineLoop *L =
Loop;
L !=
nullptr;
L =
L->getParentLoop())
1498 AllowedToHoistLoads[
L] =
false;
1508MachineLICMImpl::LookForDuplicate(
const MachineInstr *
MI,
1509 std::vector<MachineInstr *> &PrevMIs) {
1510 for (MachineInstr *PrevMI : PrevMIs)
1511 if (
TII->produceSameValue(*
MI, *PrevMI, (PreRegAlloc ? MRI :
nullptr)))
1521bool MachineLICMImpl::EliminateCSE(
1523 DenseMap<
unsigned, std::vector<MachineInstr *>>::iterator &CI) {
1526 if (
MI->isImplicitDef())
1531 if (
MI->mayLoad() && !
MI->isDereferenceableInvariantLoad())
1534 if (MachineInstr *Dup = LookForDuplicate(
MI, CI->second)) {
1539 SmallVector<unsigned, 2> Defs;
1540 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
1541 const MachineOperand &MO =
MI->getOperand(i);
1545 MO.
getReg() == Dup->getOperand(i).getReg()) &&
1546 "Instructions with different phys regs are not identical!");
1553 for (
unsigned i = 0, e = Defs.
size(); i != e; ++i) {
1554 unsigned Idx = Defs[i];
1556 Register DupReg = Dup->getOperand(Idx).getReg();
1561 for (
unsigned j = 0;
j != i; ++
j)
1562 MRI->
setRegClass(Dup->getOperand(Defs[j]).getReg(), OrigRCs[j]);
1567 for (
unsigned Idx : Defs) {
1569 Register DupReg = Dup->getOperand(Idx).getReg();
1574 Dup->getOperand(Idx).setIsDead(
false);
1577 MI->eraseFromParent();
1586bool MachineLICMImpl::MayCSE(MachineInstr *
MI) {
1587 if (
MI->mayLoad() && !
MI->isDereferenceableInvariantLoad())
1590 unsigned Opcode =
MI->getOpcode();
1591 for (
auto &Map : CSEMap) {
1594 DenseMap<unsigned, std::vector<MachineInstr *>>::iterator CI =
1595 Map.second.find(Opcode);
1598 if (CI ==
Map.second.end() ||
MI->isImplicitDef())
1600 if (LookForDuplicate(
MI, CI->second) !=
nullptr)
1611unsigned MachineLICMImpl::Hoist(MachineInstr *
MI, MachineBasicBlock *Preheader,
1612 MachineLoop *CurLoop) {
1613 MachineBasicBlock *SrcBlock =
MI->getParent();
1618 isTgtHotterThanSrc(SrcBlock, Preheader)) {
1619 ++NumNotHoistedDueToHotness;
1620 return HoistResult::NotHoisted;
1623 bool HasExtractHoistableLoad =
false;
1624 if (!IsLoopInvariantInst(*
MI, CurLoop) ||
1625 !IsProfitableToHoist(*
MI, CurLoop)) {
1627 MI = ExtractHoistableLoad(
MI, CurLoop);
1629 return HoistResult::NotHoisted;
1630 HasExtractHoistableLoad =
true;
1641 dbgs() <<
"Hoisting " << *
MI;
1642 if (
MI->getParent()->getBasicBlock())
1652 InitCSEMap(Preheader);
1653 FirstInLoop =
false;
1657 unsigned Opcode =
MI->getOpcode();
1658 bool HasCSEDone =
false;
1659 for (
auto &Map : CSEMap) {
1662 DenseMap<unsigned, std::vector<MachineInstr *>>::iterator CI =
1663 Map.second.find(Opcode);
1664 if (CI !=
Map.second.end()) {
1665 if (EliminateCSE(
MI, CI)) {
1680 assert(!
MI->isDebugInstr() &&
"Should not hoist debug inst");
1684 UpdateBackTraceRegPressure(
MI);
1689 for (MachineOperand &MO :
MI->all_defs())
1693 CSEMap[Preheader][Opcode].push_back(
MI);
1699 if (HasCSEDone || HasExtractHoistableLoad)
1700 return HoistResult::Hoisted | HoistResult::ErasedMI;
1701 return HoistResult::Hoisted;
1705MachineBasicBlock *MachineLICMImpl::getOrCreatePreheader(MachineLoop *CurLoop) {
1714 MachineBasicBlock *NewPreheader = Pred->SplitCriticalEdge(
1715 CurLoop->
getHeader(), LegacyPass, MFAM,
nullptr, MDTU);
1718 return NewPreheader;
1726bool MachineLICMImpl::isTgtHotterThanSrc(MachineBasicBlock *SrcBlock,
1727 MachineBasicBlock *TgtBlock) {
1736 double Ratio = (double)DstBF / SrcBF;
1742template <
typename DerivedT,
bool PreRegAlloc>
1745 bool Changed = MachineLICMImpl(PreRegAlloc,
nullptr, &MFAM).run(MF);