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);
929void MachineLICMImpl::InitRegPressure(MachineBasicBlock *BB) {
937 MachineBasicBlock *
TBB =
nullptr, *FBB =
nullptr;
938 SmallVector<MachineOperand, 4>
Cond;
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!");
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 =
1715 Pred->SplitCriticalEdge(CurLoop->
getHeader(), LegacyPass, MFAM, 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);