59#define DEBUG_TYPE "machinelicm"
63 cl::desc(
"MachineLICM should avoid speculation"),
68 cl::desc(
"MachineLICM should hoist even cheap instructions"),
84 cl::desc(
"Do not hoist instructions if target"
85 "block is N times hotter than the source."),
92 cl::desc(
"Disable hoisting instructions to"
96 "disable the feature"),
98 "enable the feature when using profile data"),
100 "enable the feature with/wo profile data")));
103 "Number of machine instructions hoisted out of loops");
105 "Number of instructions hoisted in low reg pressure situation");
107 "Number of high latency instructions hoisted");
109 "Number of hoisted machine instructions CSEed");
111 "Number of machine instructions hoisted out of loops post regalloc");
113 "Number of stores of const phys reg hoisted out of loops");
115 "Number of instructions not hoisted due to block frequency");
118 enum HoistResult { NotHoisted = 1, Hoisted = 2, ErasedMI = 4 };
120 class MachineLICMImpl {
121 const TargetInstrInfo *TII =
nullptr;
122 const TargetLoweringBase *TLI =
nullptr;
123 const TargetRegisterInfo *TRI =
nullptr;
124 const MachineFrameInfo *MFI =
nullptr;
125 MachineRegisterInfo *MRI =
nullptr;
126 TargetSchedModel SchedModel;
127 bool PreRegAlloc =
false;
128 bool HasProfileData =
false;
134 MachineBlockFrequencyInfo *MBFI =
nullptr;
135 MachineLoopInfo *MLI =
nullptr;
136 MachineDomTreeUpdater *MDTU =
nullptr;
139 bool Changed =
false;
140 bool FirstInLoop =
false;
144 SmallDenseMap<MachineLoop *, bool> AllowedToHoistLoads;
147 DenseMap<MachineLoop *, SmallVector<MachineBasicBlock *, 8>> ExitBlockMap;
149 bool isExitBlock(MachineLoop *CurLoop,
const MachineBasicBlock *
MBB) {
150 auto [It,
Inserted] = ExitBlockMap.try_emplace(CurLoop);
154 It->second = std::move(ExitBlocks);
160 SmallDenseSet<Register> RegSeen;
161 SmallVector<unsigned, 8> RegPressure;
165 SmallVector<unsigned, 8> RegLimit;
171 DenseMap<MachineBasicBlock *,
172 DenseMap<unsigned, std::vector<MachineInstr *>>>
184 unsigned SpeculationState = SpeculateUnknown;
187 MachineLICMImpl(
bool PreRegAlloc,
Pass *LegacyPass,
189 : PreRegAlloc(PreRegAlloc), LegacyPass(LegacyPass), MFAM(MFAM) {
190 assert((LegacyPass || MFAM) &&
"LegacyPass or MFAM must be provided");
191 assert(!(LegacyPass && MFAM) &&
192 "LegacyPass and MFAM cannot be provided at the same time");
195 bool run(MachineFunction &MF);
197 void releaseMemory() {
203 ExitBlockMap.clear();
208 struct CandidateInfo {
213 CandidateInfo(MachineInstr *mi,
Register def,
int fi)
214 : MI(mi), Def(def), FI(fi) {}
217 void HoistRegionPostRA(MachineLoop *CurLoop);
219 void HoistPostRA(MachineInstr *
MI,
Register Def, MachineLoop *CurLoop);
221 void ProcessMI(MachineInstr *
MI, BitVector &RUDefs, BitVector &RUClobbers,
222 SmallDenseSet<int> &StoredFIs,
223 SmallVectorImpl<CandidateInfo> &Candidates,
224 MachineLoop *CurLoop);
226 void AddToLiveIns(MCRegister
Reg, MachineLoop *CurLoop);
228 bool IsLICMCandidate(MachineInstr &
I, MachineLoop *CurLoop);
230 bool IsLoopInvariantInst(MachineInstr &
I, MachineLoop *CurLoop);
232 bool HasLoopPHIUse(
const MachineInstr *
MI, MachineLoop *CurLoop);
234 bool HasHighOperandLatency(MachineInstr &
MI,
unsigned DefIdx,
Register Reg,
235 MachineLoop *CurLoop)
const;
237 bool IsCheapInstruction(MachineInstr &
MI)
const;
239 bool CanCauseHighRegPressure(
const SmallDenseMap<unsigned, int> &
Cost,
242 void UpdateBackTraceRegPressure(
const MachineInstr *
MI);
244 bool IsProfitableToHoist(MachineInstr &
MI, MachineLoop *CurLoop);
246 bool IsGuaranteedToExecute(MachineBasicBlock *BB, MachineLoop *CurLoop);
248 void EnterScope(MachineBasicBlock *
MBB);
250 void ExitScope(MachineBasicBlock *
MBB);
252 void ExitScopeIfDone(
254 DenseMap<MachineDomTreeNode *, unsigned> &OpenChildren,
255 const DenseMap<MachineDomTreeNode *, MachineDomTreeNode *> &ParentMap);
259 void InitRegPressure(MachineBasicBlock *BB);
261 SmallDenseMap<unsigned, int> calcRegisterCost(
const MachineInstr *
MI,
263 bool ConsiderUnseenAsDef);
265 void UpdateRegPressure(
const MachineInstr *
MI,
266 bool ConsiderUnseenAsDef =
false);
268 MachineInstr *ExtractHoistableLoad(MachineInstr *
MI, MachineLoop *CurLoop);
270 MachineInstr *LookForDuplicate(
const MachineInstr *
MI,
271 std::vector<MachineInstr *> &PrevMIs);
274 EliminateCSE(MachineInstr *
MI,
275 DenseMap<
unsigned, std::vector<MachineInstr *>>::iterator &CI);
277 bool MayCSE(MachineInstr *
MI);
279 unsigned Hoist(MachineInstr *
MI, MachineBasicBlock *Preheader,
280 MachineLoop *CurLoop);
282 void InitCSEMap(MachineBasicBlock *BB);
284 void InitializeLoadsHoistableLoops();
286 bool isTgtHotterThanSrc(MachineBasicBlock *SrcBlock,
287 MachineBasicBlock *TgtBlock);
288 MachineBasicBlock *getOrCreatePreheader(MachineLoop *CurLoop);
295 MachineLICMBase(
char &
ID,
bool PreRegAlloc)
296 : MachineFunctionPass(
ID), PreRegAlloc(PreRegAlloc) {}
298 bool runOnMachineFunction(MachineFunction &MF)
override;
300 void getAnalysisUsage(AnalysisUsage &AU)
const override {
303 AU.
addRequired<MachineBlockFrequencyInfoWrapperPass>();
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)
342 "Early Machine Loop Invariant Code Motion",
false,
false)
348 "Early Machine Loop Invariant Code Motion",
false,
false)
351 if (skipFunction(MF.getFunction()))
354 MachineLICMImpl Impl(PreRegAlloc,
this,
nullptr);
358#define GET_RESULT(RESULT, GETTER, INFIX) \
360 ? &LegacyPass->getAnalysis<RESULT##INFIX##WrapperPass>().GETTER() \
361 : &MFAM->getResult<RESULT##Analysis>(MF))
370 MachineDomTreeUpdater::UpdateStrategy::Lazy);
374 ?
GET_RESULT(MachineBlockFrequency, getMBFI, Info)
379 TII = ST.getInstrInfo();
380 TLI = ST.getTargetLowering();
381 TRI = ST.getRegisterInfo();
384 SchedModel.
init(&ST);
396 unsigned NumRPS =
TRI->getNumRegPressureSets();
397 RegPressure.resize(NumRPS);
400 for (
unsigned i = 0, e = NumRPS; i != e; ++i)
401 RegLimit[i] =
TRI->getRegPressureSetLimit(MF, i);
405 InitializeLoadsHoistableLoops();
408 while (!Worklist.
empty()) {
412 HoistRegionPostRA(CurLoop);
418 HoistOutOfLoop(
N, CurLoop);
434 if (
MI->memoperands_empty())
437 if (!
MemOp->isStore() || !
MemOp->getPseudoValue())
441 if (
Value->getFrameIndex() == FI)
482 const unsigned NumRegs =
TRI.getNumRegs();
483 const unsigned MaskWords = (NumRegs + 31) / 32;
484 for (
unsigned K = 0; K < MaskWords; ++K) {
486 for (
unsigned Bit = 0; Bit < 32; ++Bit) {
487 const unsigned PhysReg = (K * 32) + Bit;
488 if (PhysReg == NumRegs)
491 if (PhysReg && !((Word >> Bit) & 1)) {
492 for (MCRegUnit Unit :
TRI.regunits(PhysReg))
493 RUsFromRegsNotInMask.
set(
static_cast<unsigned>(Unit));
498 RUs |= RUsFromRegsNotInMask;
503void MachineLICMImpl::ProcessMI(MachineInstr *
MI, BitVector &RUDefs,
504 BitVector &RUClobbers,
505 SmallDenseSet<int> &StoredFIs,
506 SmallVectorImpl<CandidateInfo> &Candidates,
507 MachineLoop *CurLoop) {
508 bool RuledOut =
false;
509 bool HasNonInvariantUse =
false;
511 for (
const MachineOperand &MO :
MI->operands()) {
514 int FI = MO.getIndex();
515 if (!StoredFIs.
count(FI) &&
519 HasNonInvariantUse =
true;
525 if (MO.isRegMask()) {
538 if (!HasNonInvariantUse) {
539 for (MCRegUnit Unit :
TRI->regunits(
Reg)) {
542 if (RUDefs.
test(
static_cast<unsigned>(Unit)) ||
543 RUClobbers.
test(
static_cast<unsigned>(Unit))) {
544 HasNonInvariantUse =
true;
563 for (MCRegUnit Unit :
TRI->regunits(
Reg)) {
564 if (RUDefs.
test(
static_cast<unsigned>(Unit))) {
565 RUClobbers.
set(
static_cast<unsigned>(Unit));
567 }
else if (RUClobbers.
test(
static_cast<unsigned>(Unit))) {
573 RUDefs.
set(
static_cast<unsigned>(Unit));
579 if (Def && !RuledOut) {
580 int FI = std::numeric_limits<int>::min();
581 if ((!HasNonInvariantUse && IsLICMCandidate(*
MI, CurLoop)) ||
589void MachineLICMImpl::HoistRegionPostRA(MachineLoop *CurLoop) {
590 MachineBasicBlock *Preheader = getOrCreatePreheader(CurLoop);
594 unsigned NumRegUnits =
TRI->getNumRegUnits();
595 BitVector RUDefs(NumRegUnits);
596 BitVector RUClobbers(NumRegUnits);
599 SmallDenseSet<int> StoredFIs;
603 for (MachineBasicBlock *BB : CurLoop->
getBlocks()) {
607 if (
ML &&
ML->getHeader()->isEHPad())
continue;
612 for (
const auto &LI : BB->liveins()) {
613 for (MCRegUnit Unit :
TRI->regunits(LI.PhysReg))
614 RUDefs.
set(
static_cast<unsigned>(Unit));
618 if (
const uint32_t *Mask = BB->getBeginClobberMask(
TRI))
623 const MachineFunction &MF = *BB->getParent();
627 for (MCRegUnit Unit :
TRI->regunits(
Reg))
628 RUClobbers.
set(
static_cast<unsigned>(Unit));
630 for (MCRegUnit Unit :
TRI->regunits(
Reg))
631 RUClobbers.
set(
static_cast<unsigned>(Unit));
634 SpeculationState = SpeculateUnknown;
635 for (MachineInstr &
MI : *BB)
636 ProcessMI(&
MI, RUDefs, RUClobbers, StoredFIs, Candidates, CurLoop);
640 BitVector TermRUs(NumRegUnits);
642 if (TI != Preheader->
end()) {
643 for (
const MachineOperand &MO : TI->operands()) {
649 for (MCRegUnit Unit :
TRI->regunits(
Reg))
650 TermRUs.set(
static_cast<unsigned>(Unit));
662 for (CandidateInfo &Candidate : Candidates) {
663 if (Candidate.FI != std::numeric_limits<int>::min() &&
664 StoredFIs.
count(Candidate.FI))
669 for (MCRegUnit Unit :
TRI->regunits(Def)) {
670 if (RUClobbers.
test(
static_cast<unsigned>(Unit)) ||
671 TermRUs.test(
static_cast<unsigned>(Unit))) {
680 MachineInstr *
MI = Candidate.MI;
681 for (
const MachineOperand &MO :
MI->all_uses()) {
684 for (MCRegUnit Unit :
TRI->regunits(MO.getReg())) {
685 if (RUDefs.
test(
static_cast<unsigned>(Unit)) ||
686 RUClobbers.
test(
static_cast<unsigned>(Unit))) {
699 HoistPostRA(
MI, Candidate.Def, CurLoop);
705void MachineLICMImpl::AddToLiveIns(MCRegister
Reg, MachineLoop *CurLoop) {
706 for (MachineBasicBlock *BB : CurLoop->
getBlocks()) {
707 if (!BB->isLiveIn(
Reg))
709 for (MachineInstr &
MI : *BB) {
710 for (MachineOperand &MO :
MI.all_uses()) {
713 if (
TRI->regsOverlap(
Reg, MO.getReg()))
722void MachineLICMImpl::HoistPostRA(MachineInstr *
MI,
Register Def,
723 MachineLoop *CurLoop) {
733 MachineBasicBlock *
MBB =
MI->getParent();
739 assert(!
MI->isDebugInstr() &&
"Should not hoist debug inst");
745 AddToLiveIns(Def, CurLoop);
753bool MachineLICMImpl::IsGuaranteedToExecute(MachineBasicBlock *BB,
754 MachineLoop *CurLoop) {
755 if (SpeculationState != SpeculateUnknown)
756 return SpeculationState == SpeculateFalse;
762 for (MachineBasicBlock *CurrentLoopExitingBlock : CurrentLoopExitingBlocks)
764 SpeculationState = SpeculateTrue;
769 SpeculationState = SpeculateFalse;
773void MachineLICMImpl::EnterScope(MachineBasicBlock *
MBB) {
780void MachineLICMImpl::ExitScope(MachineBasicBlock *
MBB) {
788void MachineLICMImpl::ExitScopeIfDone(
790 DenseMap<MachineDomTreeNode *, unsigned> &OpenChildren,
791 const DenseMap<MachineDomTreeNode *, MachineDomTreeNode *> &ParentMap) {
792 if (OpenChildren[Node])
796 ExitScope(
Node->getBlock());
799 if (!Parent || --OpenChildren[Parent] != 0)
810 MachineLoop *CurLoop) {
811 MachineBasicBlock *Preheader = getOrCreatePreheader(CurLoop);
817 DenseMap<MachineDomTreeNode*, MachineDomTreeNode*> ParentMap;
818 DenseMap<MachineDomTreeNode*, unsigned> OpenChildren;
822 while (!WorkList.
empty()) {
824 assert(Node &&
"Null dominator tree node?");
825 MachineBasicBlock *BB =
Node->getBlock();
830 if (
ML &&
ML->getHeader()->isEHPad())
843 OpenChildren[
Node] = 0;
850 size_t WorkListStart = WorkList.
size();
852 ParentMap[Child] =
Node;
855 std::reverse(WorkList.
begin() + WorkListStart, WorkList.
end());
856 OpenChildren[
Node] = WorkList.
size() - WorkListStart;
865 InitRegPressure(Preheader);
869 MachineBasicBlock *
MBB =
Node->getBlock();
874 SpeculationState = SpeculateUnknown;
876 unsigned HoistRes = HoistResult::NotHoisted;
877 HoistRes = Hoist(&
MI, Preheader, CurLoop);
878 if (HoistRes & HoistResult::NotHoisted) {
881 SmallVector<MachineLoop *> InnerLoopWorkList;
882 for (MachineLoop *L = MLI->
getLoopFor(
MI.getParent()); L != CurLoop;
883 L =
L->getParentLoop())
886 while (!InnerLoopWorkList.
empty()) {
887 MachineLoop *InnerLoop = InnerLoopWorkList.
pop_back_val();
889 if (InnerLoopPreheader) {
890 HoistRes = Hoist(&
MI, InnerLoopPreheader, InnerLoop);
891 if (HoistRes & HoistResult::Hoisted)
897 if (HoistRes & HoistResult::ErasedMI)
900 UpdateRegPressure(&
MI);
904 ExitScopeIfDone(Node, OpenChildren, ParentMap);
915void MachineLICMImpl::InitRegPressure(MachineBasicBlock *BB) {
923 MachineBasicBlock *
TBB =
nullptr, *FBB =
nullptr;
929 for (
const MachineInstr &
MI : *BB)
930 UpdateRegPressure(&
MI,
true);
934void MachineLICMImpl::UpdateRegPressure(
const MachineInstr *
MI,
935 bool ConsiderUnseenAsDef) {
936 auto Cost = calcRegisterCost(
MI,
true, ConsiderUnseenAsDef);
937 for (
const auto &[Class, Weight] :
Cost) {
938 if (
static_cast<int>(RegPressure[Class]) < -Weight)
951SmallDenseMap<unsigned, int>
952MachineLICMImpl::calcRegisterCost(
const MachineInstr *
MI,
bool ConsiderSeen,
953 bool ConsiderUnseenAsDef) {
954 SmallDenseMap<unsigned, int>
Cost;
955 if (
MI->isImplicitDef())
957 for (
unsigned i = 0, e =
MI->getDesc().getNumOperands(); i != e; ++i) {
958 const MachineOperand &MO =
MI->getOperand(i);
966 bool isNew = ConsiderSeen ? RegSeen.
insert(
Reg).second :
false;
969 RegClassWeight
W =
TRI->getRegClassWeight(RC);
972 RCCost =
W.RegWeight;
975 if (isNew && !isKill && ConsiderUnseenAsDef)
977 RCCost =
W.RegWeight;
978 else if (!isNew && isKill)
979 RCCost = -
W.RegWeight;
983 const int *PS =
TRI->getRegClassPressureSets(RC);
984 for (; *PS != -1; ++PS)
993 assert(
MI.mayLoad() &&
"Expected MI that loads!");
997 if (
MI.memoperands_empty())
1002 if (PSV->isGOT() || PSV->isConstantPool())
1019 bool FoundCallerPresReg =
false;
1020 if (!
MI.mayStore() ||
MI.hasUnmodeledSideEffects() ||
1021 (
MI.getNumOperands() == 0))
1030 if (
Reg.isVirtual())
1032 if (
Reg.isVirtual())
1034 if (!
TRI->isCallerPreservedPhysReg(
Reg.asMCReg(), *
MI.getMF()))
1037 FoundCallerPresReg =
true;
1038 }
else if (!MO.
isImm()) {
1042 return FoundCallerPresReg;
1060 Register CopySrcReg =
MI.getOperand(1).getReg();
1064 if (!
TRI->isCallerPreservedPhysReg(CopySrcReg.
asMCReg(), *MF))
1067 Register CopyDstReg =
MI.getOperand(0).getReg();
1080bool MachineLICMImpl::IsLICMCandidate(MachineInstr &
I, MachineLoop *CurLoop) {
1082 bool DontMoveAcrossStore = !
HoistConstLoads || !AllowedToHoistLoads[CurLoop];
1083 if ((!
I.isSafeToMove(DontMoveAcrossStore)) &&
1096 !IsGuaranteedToExecute(
I.getParent(), CurLoop)) {
1105 if (
I.isConvergent())
1108 if (!
TII->shouldHoist(
I, CurLoop))
1115bool MachineLICMImpl::IsLoopInvariantInst(MachineInstr &
I,
1116 MachineLoop *CurLoop) {
1117 if (!IsLICMCandidate(
I, CurLoop)) {
1118 LLVM_DEBUG(
dbgs() <<
"LICM: Instruction not a LICM candidate\n");
1126bool MachineLICMImpl::HasLoopPHIUse(
const MachineInstr *
MI,
1127 MachineLoop *CurLoop) {
1130 MI = Work.pop_back_val();
1131 for (
const MachineOperand &MO :
MI->all_defs()) {
1137 if (
UseMI.isPHI()) {
1151 Work.push_back(&
UseMI);
1154 }
while (!Work.empty());
1160bool MachineLICMImpl::HasHighOperandLatency(MachineInstr &
MI,
unsigned DefIdx,
1162 MachineLoop *CurLoop)
const {
1167 if (
UseMI.isCopyLike())
1171 for (
unsigned i = 0, e =
UseMI.getNumOperands(); i != e; ++i) {
1172 const MachineOperand &MO =
UseMI.getOperand(i);
1179 if (
TII->hasHighOperandLatency(SchedModel, MRI,
MI, DefIdx,
UseMI, i))
1192bool MachineLICMImpl::IsCheapInstruction(MachineInstr &
MI)
const {
1196 bool isCheap =
false;
1197 unsigned NumDefs =
MI.getDesc().getNumDefs();
1198 for (
unsigned i = 0, e =
MI.getNumOperands(); NumDefs && i != e; ++i) {
1199 MachineOperand &DefMO =
MI.getOperand(i);
1207 if (!
TII->hasLowDefLatency(SchedModel,
MI, i))
1217bool MachineLICMImpl::CanCauseHighRegPressure(
1218 const SmallDenseMap<unsigned, int> &
Cost,
bool CheapInstr) {
1219 for (
const auto &[Class, Weight] :
Cost) {
1223 int Limit = RegLimit[
Class];
1230 for (
const auto &RP : BackTrace)
1231 if (
static_cast<int>(RP[Class]) + Weight >= Limit)
1241void MachineLICMImpl::UpdateBackTraceRegPressure(
const MachineInstr *
MI) {
1244 auto Cost = calcRegisterCost(
MI,
false,
1248 for (
auto &RP : BackTrace)
1249 for (
const auto &[Class, Weight] :
Cost)
1255bool MachineLICMImpl::IsProfitableToHoist(MachineInstr &
MI,
1256 MachineLoop *CurLoop) {
1257 if (
MI.isImplicitDef())
1275 bool CheapInstr = IsCheapInstruction(
MI);
1276 bool CreatesCopy = HasLoopPHIUse(&
MI, CurLoop);
1279 if (CheapInstr && CreatesCopy) {
1286 if (
TII->isTriviallyReMaterializable(
MI))
1291 for (
unsigned i = 0, e =
MI.getDesc().getNumOperands(); i != e; ++i) {
1292 const MachineOperand &MO =
MI.getOperand(i);
1298 if (MO.
isDef() && HasHighOperandLatency(
MI, i,
Reg, CurLoop)) {
1311 auto Cost = calcRegisterCost(&
MI,
false,
1316 if (!CanCauseHighRegPressure(
Cost, CheapInstr)) {
1332 (!IsGuaranteedToExecute(
MI.getParent(), CurLoop) && !MayCSE(&
MI))) {
1340 if (
MI.isCopy() ||
MI.isRegSequence()) {
1344 [
this](
const MachineOperand &UseOp) {
1345 return !UseOp.isReg() || UseOp.getReg().isVirtual() ||
1346 MRI->isConstantPhysReg(UseOp.getReg());
1348 IsLoopInvariantInst(
MI, CurLoop) &&
1350 [&CurLoop,
this, DefReg,
1352 if (!CurLoop->contains(&UseMI))
1359 if (CanCauseHighRegPressure(Cost, false) &&
1360 !CurLoop->isLoopInvariant(UseMI, DefReg))
1370 if (!
TII->isTriviallyReMaterializable(
MI) &&
1371 !
MI.isDereferenceableInvariantLoad()) {
1382MachineInstr *MachineLICMImpl::ExtractHoistableLoad(MachineInstr *
MI,
1383 MachineLoop *CurLoop) {
1385 if (
MI->canFoldAsLoad())
1391 if (!
MI->isDereferenceableInvariantLoad())
1395 unsigned LoadRegIndex;
1397 TII->getOpcodeAfterMemoryUnfold(
MI->getOpcode(),
1401 if (NewOpc == 0)
return nullptr;
1402 const MCInstrDesc &MID =
TII->get(NewOpc);
1403 MachineFunction &MF = *
MI->getMF();
1408 SmallVector<MachineInstr *, 2> NewMIs;
1414 "unfoldMemoryOperand failed when getOpcodeAfterMemoryUnfold "
1417 "Unfolded a load into multiple instructions!");
1418 MachineBasicBlock *
MBB =
MI->getParent();
1424 if (!IsLoopInvariantInst(*NewMIs[0], CurLoop) ||
1425 !IsProfitableToHoist(*NewMIs[0], CurLoop)) {
1426 NewMIs[0]->eraseFromParent();
1427 NewMIs[1]->eraseFromParent();
1432 UpdateRegPressure(NewMIs[1]);
1437 if (
MI->shouldUpdateAdditionalCallInfo())
1440 MI->eraseFromParent();
1447void MachineLICMImpl::InitCSEMap(MachineBasicBlock *BB) {
1448 for (MachineInstr &
MI : *BB)
1454void MachineLICMImpl::InitializeLoadsHoistableLoops() {
1460 while (!Worklist.empty()) {
1461 auto *
L = Worklist.pop_back_val();
1462 AllowedToHoistLoads[
L] =
true;
1474 for (
auto *Loop :
reverse(LoopsInPreOrder)) {
1475 for (
auto *
MBB : Loop->blocks()) {
1477 if (!AllowedToHoistLoads[Loop])
1479 for (
auto &
MI : *
MBB) {
1480 if (!
MI.isLoadFoldBarrier() && !
MI.mayStore() && !
MI.isCall() &&
1481 !(
MI.mayLoad() &&
MI.hasOrderedMemoryRef()))
1483 for (MachineLoop *L = Loop;
L !=
nullptr;
L =
L->getParentLoop())
1484 AllowedToHoistLoads[
L] =
false;
1494MachineLICMImpl::LookForDuplicate(
const MachineInstr *
MI,
1495 std::vector<MachineInstr *> &PrevMIs) {
1496 for (MachineInstr *PrevMI : PrevMIs)
1497 if (
TII->produceSameValue(*
MI, *PrevMI, (PreRegAlloc ? MRI :
nullptr)))
1507bool MachineLICMImpl::EliminateCSE(
1509 DenseMap<
unsigned, std::vector<MachineInstr *>>::iterator &CI) {
1512 if (
MI->isImplicitDef())
1517 if (
MI->mayLoad() && !
MI->isDereferenceableInvariantLoad())
1520 if (MachineInstr *Dup = LookForDuplicate(
MI, CI->second)) {
1525 SmallVector<unsigned, 2> Defs;
1526 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
1527 const MachineOperand &MO =
MI->getOperand(i);
1531 MO.
getReg() == Dup->getOperand(i).getReg()) &&
1532 "Instructions with different phys regs are not identical!");
1539 for (
unsigned i = 0, e = Defs.
size(); i != e; ++i) {
1540 unsigned Idx = Defs[i];
1542 Register DupReg = Dup->getOperand(Idx).getReg();
1547 for (
unsigned j = 0;
j != i; ++
j)
1548 MRI->
setRegClass(Dup->getOperand(Defs[j]).getReg(), OrigRCs[j]);
1553 for (
unsigned Idx : Defs) {
1555 Register DupReg = Dup->getOperand(Idx).getReg();
1560 Dup->getOperand(Idx).setIsDead(
false);
1563 MI->eraseFromParent();
1572bool MachineLICMImpl::MayCSE(MachineInstr *
MI) {
1573 if (
MI->mayLoad() && !
MI->isDereferenceableInvariantLoad())
1576 unsigned Opcode =
MI->getOpcode();
1577 for (
auto &Map : CSEMap) {
1580 DenseMap<unsigned, std::vector<MachineInstr *>>::iterator CI =
1581 Map.second.find(Opcode);
1584 if (CI ==
Map.second.end() ||
MI->isImplicitDef())
1586 if (LookForDuplicate(
MI, CI->second) !=
nullptr)
1597unsigned MachineLICMImpl::Hoist(MachineInstr *
MI, MachineBasicBlock *Preheader,
1598 MachineLoop *CurLoop) {
1599 MachineBasicBlock *SrcBlock =
MI->getParent();
1604 isTgtHotterThanSrc(SrcBlock, Preheader)) {
1605 ++NumNotHoistedDueToHotness;
1606 return HoistResult::NotHoisted;
1609 bool HasExtractHoistableLoad =
false;
1610 if (!IsLoopInvariantInst(*
MI, CurLoop) ||
1611 !IsProfitableToHoist(*
MI, CurLoop)) {
1613 MI = ExtractHoistableLoad(
MI, CurLoop);
1615 return HoistResult::NotHoisted;
1616 HasExtractHoistableLoad =
true;
1627 dbgs() <<
"Hoisting " << *
MI;
1628 if (
MI->getParent()->getBasicBlock())
1638 InitCSEMap(Preheader);
1639 FirstInLoop =
false;
1643 unsigned Opcode =
MI->getOpcode();
1644 bool HasCSEDone =
false;
1645 for (
auto &Map : CSEMap) {
1648 DenseMap<unsigned, std::vector<MachineInstr *>>::iterator CI =
1649 Map.second.find(Opcode);
1650 if (CI !=
Map.second.end()) {
1651 if (EliminateCSE(
MI, CI)) {
1666 assert(!
MI->isDebugInstr() &&
"Should not hoist debug inst");
1670 UpdateBackTraceRegPressure(
MI);
1675 for (MachineOperand &MO :
MI->all_defs())
1679 CSEMap[Preheader][Opcode].push_back(
MI);
1685 if (HasCSEDone || HasExtractHoistableLoad)
1686 return HoistResult::Hoisted | HoistResult::ErasedMI;
1687 return HoistResult::Hoisted;
1691MachineBasicBlock *MachineLICMImpl::getOrCreatePreheader(MachineLoop *CurLoop) {
1700 MachineBasicBlock *NewPreheader = Pred->SplitCriticalEdge(
1701 CurLoop->
getHeader(), LegacyPass, MFAM,
nullptr, MDTU);
1704 return NewPreheader;
1712bool MachineLICMImpl::isTgtHotterThanSrc(MachineBasicBlock *SrcBlock,
1713 MachineBasicBlock *TgtBlock) {
1722 double Ratio = (double)DstBF / SrcBF;
1728template <
typename DerivedT,
bool PreRegAlloc>
1731 bool Changed = MachineLICMImpl(PreRegAlloc,
nullptr, &MFAM).run(MF);