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 *>>>
188 unsigned SpeculationState = SpeculateUnknown;
191 MachineLICMImpl(
bool PreRegAlloc,
Pass *LegacyPass,
193 : PreRegAlloc(PreRegAlloc), LegacyPass(LegacyPass), MFAM(MFAM) {
194 assert((LegacyPass || MFAM) &&
"LegacyPass or MFAM must be provided");
195 assert(!(LegacyPass && MFAM) &&
196 "LegacyPass and MFAM cannot be provided at the same time");
201 void releaseMemory() {
207 ExitBlockMap.clear();
212 struct CandidateInfo {
217 CandidateInfo(MachineInstr *mi,
Register def,
int fi)
218 : MI(mi), Def(def), FI(fi) {}
221 void HoistRegionPostRA(MachineLoop *CurLoop);
223 void HoistPostRA(MachineInstr *
MI,
Register Def, MachineLoop *CurLoop);
225 void ProcessMI(MachineInstr *
MI, BitVector &RUDefs, BitVector &RUClobbers,
226 SmallDenseSet<int> &StoredFIs,
227 SmallVectorImpl<CandidateInfo> &Candidates,
228 MachineLoop *CurLoop);
230 void AddToLiveIns(MCRegister
Reg, MachineLoop *CurLoop);
232 bool IsLICMCandidate(MachineInstr &
I, MachineLoop *CurLoop);
234 bool IsLoopInvariantInst(MachineInstr &
I, MachineLoop *CurLoop);
236 bool HasLoopPHIUse(
const MachineInstr *
MI, MachineLoop *CurLoop);
238 bool HasHighOperandLatency(MachineInstr &
MI,
unsigned DefIdx,
Register Reg,
239 MachineLoop *CurLoop)
const;
241 bool IsCheapInstruction(MachineInstr &
MI)
const;
243 bool CanCauseHighRegPressure(
const SmallDenseMap<unsigned, int> &
Cost,
246 void UpdateBackTraceRegPressure(
const MachineInstr *
MI);
248 bool IsProfitableToHoist(MachineInstr &
MI, MachineLoop *CurLoop);
250 bool IsGuaranteedToExecute(MachineBasicBlock *BB, MachineLoop *CurLoop);
252 void EnterScope(MachineBasicBlock *
MBB);
254 void ExitScope(MachineBasicBlock *
MBB);
256 void ExitScopeIfDone(
258 DenseMap<MachineDomTreeNode *, unsigned> &OpenChildren,
259 const DenseMap<MachineDomTreeNode *, MachineDomTreeNode *> &ParentMap);
263 void InitRegPressure(MachineBasicBlock *BB);
265 SmallDenseMap<unsigned, int> calcRegisterCost(
const MachineInstr *
MI,
267 bool ConsiderUnseenAsDef);
269 void UpdateRegPressure(
const MachineInstr *
MI,
270 bool ConsiderUnseenAsDef =
false);
272 MachineInstr *ExtractHoistableLoad(MachineInstr *
MI, MachineLoop *CurLoop);
274 MachineInstr *LookForDuplicate(
const MachineInstr *
MI,
275 std::vector<MachineInstr *> &PrevMIs);
278 EliminateCSE(MachineInstr *
MI,
279 DenseMap<
unsigned, std::vector<MachineInstr *>>::iterator &CI);
281 bool MayCSE(MachineInstr *
MI);
283 unsigned Hoist(MachineInstr *
MI, MachineBasicBlock *Preheader,
284 MachineLoop *CurLoop);
286 void InitCSEMap(MachineBasicBlock *BB);
288 void InitializeLoadsHoistableLoops();
290 bool isTgtHotterThanSrc(MachineBasicBlock *SrcBlock,
291 MachineBasicBlock *TgtBlock);
292 MachineBasicBlock *getOrCreatePreheader(MachineLoop *CurLoop);
299 MachineLICMBase(
char &ID,
bool PreRegAlloc)
300 : MachineFunctionPass(
ID), PreRegAlloc(PreRegAlloc) {}
304 void getAnalysisUsage(AnalysisUsage &AU)
const override {
307 AU.
addRequired<LazyMachineBlockFrequencyInfoPass>();
309 AU.
addRequired<MachineRegisterClassInfoWrapperPass>();
317 class MachineLICM :
public MachineLICMBase {
320 MachineLICM() : MachineLICMBase(ID,
false) {}
323 class EarlyMachineLICM :
public MachineLICMBase {
326 EarlyMachineLICM() : MachineLICMBase(ID,
true) {}
332char EarlyMachineLICM::ID;
338 "Machine Loop Invariant Code Motion",
false,
false)
348 "Early Machine Loop Invariant Code Motion",
false,
false)
355 "Early Machine Loop Invariant Code Motion",
false,
false)
358 if (skipFunction(MF.getFunction()))
361 MachineLICMImpl Impl(PreRegAlloc,
this,
nullptr);
365#define GET_RESULT(RESULT, GETTER, INFIX) \
367 ? &LegacyPass->getAnalysis<RESULT##INFIX##WrapperPass>().GETTER() \
368 : &MFAM->getResult<RESULT##Analysis>(MF))
384 MachineDomTreeUpdater::UpdateStrategy::Lazy);
390 TII = ST.getInstrInfo();
391 TLI = ST.getTargetLowering();
392 TRI = ST.getRegisterInfo();
395 SchedModel.
init(&ST);
414 unsigned NumRPS =
TRI->getNumRegPressureSets();
415 RegPressure.resize(NumRPS);
418 for (
unsigned i = 0, e = NumRPS; i != e; ++i)
423 InitializeLoadsHoistableLoops();
426 while (!Worklist.
empty()) {
430 HoistRegionPostRA(CurLoop);
436 HoistOutOfLoop(
N, CurLoop);
452 if (
MI->memoperands_empty())
455 if (!
MemOp->isStore() || !
MemOp->getPseudoValue())
459 if (
Value->getFrameIndex() == FI)
500 const unsigned NumRegs =
TRI.getNumRegs();
501 const unsigned MaskWords = (NumRegs + 31) / 32;
502 for (
unsigned K = 0;
K < MaskWords; ++
K) {
504 for (
unsigned Bit = 0; Bit < 32; ++Bit) {
505 const unsigned PhysReg = (
K * 32) + Bit;
506 if (PhysReg == NumRegs)
509 if (PhysReg && !((Word >> Bit) & 1)) {
510 for (MCRegUnit Unit :
TRI.regunits(PhysReg))
511 RUsFromRegsNotInMask.
set(
static_cast<unsigned>(Unit));
516 RUs |= RUsFromRegsNotInMask;
521void MachineLICMImpl::ProcessMI(MachineInstr *
MI, BitVector &RUDefs,
522 BitVector &RUClobbers,
523 SmallDenseSet<int> &StoredFIs,
524 SmallVectorImpl<CandidateInfo> &Candidates,
525 MachineLoop *CurLoop) {
526 bool RuledOut =
false;
527 bool HasNonInvariantUse =
false;
529 for (
const MachineOperand &MO :
MI->operands()) {
532 int FI = MO.getIndex();
533 if (!StoredFIs.
count(FI) &&
537 HasNonInvariantUse =
true;
543 if (MO.isRegMask()) {
556 if (!HasNonInvariantUse) {
557 for (MCRegUnit Unit :
TRI->regunits(
Reg)) {
560 if (RUDefs.
test(
static_cast<unsigned>(Unit)) ||
561 RUClobbers.
test(
static_cast<unsigned>(Unit))) {
562 HasNonInvariantUse =
true;
581 for (MCRegUnit Unit :
TRI->regunits(
Reg)) {
582 if (RUDefs.
test(
static_cast<unsigned>(Unit))) {
583 RUClobbers.
set(
static_cast<unsigned>(Unit));
585 }
else if (RUClobbers.
test(
static_cast<unsigned>(Unit))) {
591 RUDefs.
set(
static_cast<unsigned>(Unit));
597 if (Def && !RuledOut) {
598 int FI = std::numeric_limits<int>::min();
599 if ((!HasNonInvariantUse && IsLICMCandidate(*
MI, CurLoop)) ||
607void MachineLICMImpl::HoistRegionPostRA(MachineLoop *CurLoop) {
608 MachineBasicBlock *Preheader = getOrCreatePreheader(CurLoop);
612 unsigned NumRegUnits =
TRI->getNumRegUnits();
613 BitVector RUDefs(NumRegUnits);
614 BitVector RUClobbers(NumRegUnits);
617 SmallDenseSet<int> StoredFIs;
621 for (MachineBasicBlock *BB : CurLoop->
getBlocks()) {
625 if (
ML &&
ML->getHeader()->isEHPad())
continue;
630 for (
const auto &LI : BB->liveins()) {
631 for (MCRegUnit Unit :
TRI->regunits(LI.PhysReg))
632 RUDefs.
set(
static_cast<unsigned>(Unit));
636 if (
const uint32_t *Mask = BB->getBeginClobberMask(
TRI))
646 for (MCRegUnit Unit :
TRI->regunits(
Reg))
647 RUClobbers.
set(
static_cast<unsigned>(Unit));
649 for (MCRegUnit Unit :
TRI->regunits(
Reg))
650 RUClobbers.
set(
static_cast<unsigned>(Unit));
653 SpeculationState = SpeculateUnknown;
654 for (MachineInstr &
MI : *BB)
655 ProcessMI(&
MI, RUDefs, RUClobbers, StoredFIs, Candidates, CurLoop);
659 BitVector TermRUs(NumRegUnits);
661 if (TI != Preheader->
end()) {
662 for (
const MachineOperand &MO : TI->operands()) {
668 for (MCRegUnit Unit :
TRI->regunits(
Reg))
669 TermRUs.set(
static_cast<unsigned>(Unit));
681 for (CandidateInfo &Candidate : Candidates) {
682 if (Candidate.FI != std::numeric_limits<int>::min() &&
683 StoredFIs.
count(Candidate.FI))
688 for (MCRegUnit Unit :
TRI->regunits(Def)) {
689 if (RUClobbers.
test(
static_cast<unsigned>(Unit)) ||
690 TermRUs.test(
static_cast<unsigned>(Unit))) {
699 MachineInstr *
MI = Candidate.MI;
700 for (
const MachineOperand &MO :
MI->all_uses()) {
703 for (MCRegUnit Unit :
TRI->regunits(MO.getReg())) {
704 if (RUDefs.
test(
static_cast<unsigned>(Unit)) ||
705 RUClobbers.
test(
static_cast<unsigned>(Unit))) {
718 HoistPostRA(
MI, Candidate.Def, CurLoop);
724void MachineLICMImpl::AddToLiveIns(MCRegister
Reg, MachineLoop *CurLoop) {
725 for (MachineBasicBlock *BB : CurLoop->
getBlocks()) {
726 if (!BB->isLiveIn(
Reg))
728 for (MachineInstr &
MI : *BB) {
729 for (MachineOperand &MO :
MI.all_uses()) {
732 if (
TRI->regsOverlap(
Reg, MO.getReg()))
741void MachineLICMImpl::HoistPostRA(MachineInstr *
MI,
Register Def,
742 MachineLoop *CurLoop) {
758 assert(!
MI->isDebugInstr() &&
"Should not hoist debug inst");
764 AddToLiveIns(Def, CurLoop);
772bool MachineLICMImpl::IsGuaranteedToExecute(MachineBasicBlock *BB,
773 MachineLoop *CurLoop) {
774 if (SpeculationState != SpeculateUnknown)
775 return SpeculationState == SpeculateFalse;
781 for (MachineBasicBlock *CurrentLoopExitingBlock : CurrentLoopExitingBlocks)
783 SpeculationState = SpeculateTrue;
788 SpeculationState = SpeculateFalse;
792void MachineLICMImpl::EnterScope(MachineBasicBlock *
MBB) {
799void MachineLICMImpl::ExitScope(MachineBasicBlock *
MBB) {
807void MachineLICMImpl::ExitScopeIfDone(
809 DenseMap<MachineDomTreeNode *, unsigned> &OpenChildren,
810 const DenseMap<MachineDomTreeNode *, MachineDomTreeNode *> &ParentMap) {
811 if (OpenChildren[Node])
815 ExitScope(
Node->getBlock());
818 if (!Parent || --OpenChildren[Parent] != 0)
829 MachineLoop *CurLoop) {
830 MachineBasicBlock *Preheader = getOrCreatePreheader(CurLoop);
836 DenseMap<MachineDomTreeNode*, MachineDomTreeNode*> ParentMap;
837 DenseMap<MachineDomTreeNode*, unsigned> OpenChildren;
841 while (!WorkList.
empty()) {
843 assert(Node &&
"Null dominator tree node?");
844 MachineBasicBlock *BB =
Node->getBlock();
849 if (
ML &&
ML->getHeader()->isEHPad())
862 OpenChildren[
Node] = 0;
869 size_t WorkListStart = WorkList.
size();
871 ParentMap[Child] =
Node;
874 std::reverse(WorkList.
begin() + WorkListStart, WorkList.
end());
875 OpenChildren[
Node] = WorkList.
size() - WorkListStart;
884 InitRegPressure(Preheader);
888 MachineBasicBlock *
MBB =
Node->getBlock();
893 SpeculationState = SpeculateUnknown;
895 unsigned HoistRes = HoistResult::NotHoisted;
896 HoistRes = Hoist(&
MI, Preheader, CurLoop);
897 if (HoistRes & HoistResult::NotHoisted) {
900 SmallVector<MachineLoop *> InnerLoopWorkList;
901 for (MachineLoop *L = MLI->
getLoopFor(
MI.getParent()); L != CurLoop;
902 L =
L->getParentLoop())
905 while (!InnerLoopWorkList.
empty()) {
906 MachineLoop *InnerLoop = InnerLoopWorkList.
pop_back_val();
908 if (InnerLoopPreheader) {
909 HoistRes = Hoist(&
MI, InnerLoopPreheader, InnerLoop);
910 if (HoistRes & HoistResult::Hoisted)
916 if (HoistRes & HoistResult::ErasedMI)
919 UpdateRegPressure(&
MI);
923 ExitScopeIfDone(Node, OpenChildren, ParentMap);
930void MachineLICMImpl::InitRegPressure(MachineBasicBlock *BB) {
938 MachineBasicBlock *
TBB =
nullptr, *FBB =
nullptr;
939 SmallVector<MachineOperand, 4>
Cond;
944 for (
const MachineInstr &
MI : *BB)
945 UpdateRegPressure(&
MI,
true);
949void MachineLICMImpl::UpdateRegPressure(
const MachineInstr *
MI,
950 bool ConsiderUnseenAsDef) {
951 auto Cost = calcRegisterCost(
MI,
true, ConsiderUnseenAsDef);
952 for (
const auto &[Class, Weight] :
Cost) {
953 if (
static_cast<int>(RegPressure[Class]) < -Weight)
966SmallDenseMap<unsigned, int>
967MachineLICMImpl::calcRegisterCost(
const MachineInstr *
MI,
bool ConsiderSeen,
968 bool ConsiderUnseenAsDef) {
969 SmallDenseMap<unsigned, int>
Cost;
970 if (
MI->isImplicitDef())
972 for (
unsigned i = 0, e =
MI->getDesc().getNumOperands(); i != e; ++i) {
973 const MachineOperand &MO =
MI->getOperand(i);
981 bool isNew = ConsiderSeen ? RegSeen.
insert(
Reg).second :
false;
984 RegClassWeight
W =
TRI->getRegClassWeight(RC);
987 RCCost =
W.RegWeight;
990 if (isNew && !isKill && ConsiderUnseenAsDef)
992 RCCost =
W.RegWeight;
993 else if (!isNew && isKill)
994 RCCost = -
W.RegWeight;
998 const int *PS =
TRI->getRegClassPressureSets(RC);
999 for (; *PS != -1; ++PS)
1000 Cost[*PS] += RCCost;
1008 assert(
MI.mayLoad() &&
"Expected MI that loads!");
1012 if (
MI.memoperands_empty())
1017 if (PSV->isGOT() || PSV->isConstantPool())
1034 bool FoundCallerPresReg =
false;
1035 if (!
MI.mayStore() ||
MI.hasUnmodeledSideEffects() ||
1036 (
MI.getNumOperands() == 0))
1045 if (
Reg.isVirtual())
1047 if (
Reg.isVirtual())
1049 if (!
TRI->isCallerPreservedPhysReg(
Reg.asMCReg(), *
MI.getMF()))
1052 FoundCallerPresReg =
true;
1053 }
else if (!MO.
isImm()) {
1057 return FoundCallerPresReg;
1075 Register CopySrcReg =
MI.getOperand(1).getReg();
1079 if (!
TRI->isCallerPreservedPhysReg(CopySrcReg.
asMCReg(), *MF))
1082 Register CopyDstReg =
MI.getOperand(0).getReg();
1095bool MachineLICMImpl::IsLICMCandidate(MachineInstr &
I, MachineLoop *CurLoop) {
1097 bool DontMoveAcrossStore = !
HoistConstLoads || !AllowedToHoistLoads[CurLoop];
1098 if ((!
I.isSafeToMove(DontMoveAcrossStore)) &&
1111 !IsGuaranteedToExecute(
I.getParent(), CurLoop)) {
1120 if (
I.isConvergent())
1123 if (!
TII->shouldHoist(
I, CurLoop))
1130bool MachineLICMImpl::IsLoopInvariantInst(MachineInstr &
I,
1131 MachineLoop *CurLoop) {
1132 if (!IsLICMCandidate(
I, CurLoop)) {
1133 LLVM_DEBUG(
dbgs() <<
"LICM: Instruction not a LICM candidate\n");
1141bool MachineLICMImpl::HasLoopPHIUse(
const MachineInstr *
MI,
1142 MachineLoop *CurLoop) {
1145 MI = Work.pop_back_val();
1146 for (
const MachineOperand &MO :
MI->all_defs()) {
1152 if (
UseMI.isPHI()) {
1166 Work.push_back(&
UseMI);
1169 }
while (!Work.empty());
1175bool MachineLICMImpl::HasHighOperandLatency(MachineInstr &
MI,
unsigned DefIdx,
1177 MachineLoop *CurLoop)
const {
1182 if (
UseMI.isCopyLike())
1186 for (
unsigned i = 0, e =
UseMI.getNumOperands(); i != e; ++i) {
1187 const MachineOperand &MO =
UseMI.getOperand(i);
1194 if (
TII->hasHighOperandLatency(SchedModel,
MRI,
MI, DefIdx,
UseMI, i))
1207bool MachineLICMImpl::IsCheapInstruction(MachineInstr &
MI)
const {
1211 bool isCheap =
false;
1212 unsigned NumDefs =
MI.getDesc().getNumDefs();
1213 for (
unsigned i = 0, e =
MI.getNumOperands(); NumDefs && i != e; ++i) {
1214 MachineOperand &DefMO =
MI.getOperand(i);
1222 if (!
TII->hasLowDefLatency(SchedModel,
MI, i))
1232bool MachineLICMImpl::CanCauseHighRegPressure(
1233 const SmallDenseMap<unsigned, int> &
Cost,
bool CheapInstr) {
1234 for (
const auto &[Class, Weight] :
Cost) {
1238 int Limit = RegLimit[
Class];
1245 for (
const auto &RP : BackTrace)
1246 if (
static_cast<int>(RP[Class]) + Weight >= Limit)
1256void MachineLICMImpl::UpdateBackTraceRegPressure(
const MachineInstr *
MI) {
1259 auto Cost = calcRegisterCost(
MI,
false,
1263 for (
auto &RP : BackTrace)
1264 for (
const auto &[Class, Weight] :
Cost)
1270bool MachineLICMImpl::IsProfitableToHoist(MachineInstr &
MI,
1271 MachineLoop *CurLoop) {
1272 if (
MI.isImplicitDef())
1290 bool CheapInstr = IsCheapInstruction(
MI);
1291 bool CreatesCopy = HasLoopPHIUse(&
MI, CurLoop);
1294 if (CheapInstr && CreatesCopy) {
1301 if (
TII->isTriviallyReMaterializable(
MI))
1306 for (
unsigned i = 0, e =
MI.getDesc().getNumOperands(); i != e; ++i) {
1307 const MachineOperand &MO =
MI.getOperand(i);
1313 if (MO.
isDef() && HasHighOperandLatency(
MI, i,
Reg, CurLoop)) {
1326 auto Cost = calcRegisterCost(&
MI,
false,
1331 if (!CanCauseHighRegPressure(
Cost, CheapInstr)) {
1347 (!IsGuaranteedToExecute(
MI.getParent(), CurLoop) && !MayCSE(&
MI))) {
1355 if (
MI.isCopy() ||
MI.isRegSequence()) {
1359 [
this](
const MachineOperand &UseOp) {
1360 return !UseOp.isReg() || UseOp.getReg().isVirtual() ||
1361 MRI->isConstantPhysReg(UseOp.getReg());
1363 IsLoopInvariantInst(
MI, CurLoop) &&
1365 [&CurLoop,
this, DefReg,
1367 if (!CurLoop->contains(&UseMI))
1374 if (CanCauseHighRegPressure(Cost, false) &&
1375 !CurLoop->isLoopInvariant(UseMI, DefReg))
1385 if (!
TII->isTriviallyReMaterializable(
MI) &&
1386 !
MI.isDereferenceableInvariantLoad()) {
1397MachineInstr *MachineLICMImpl::ExtractHoistableLoad(MachineInstr *
MI,
1398 MachineLoop *CurLoop) {
1400 if (
MI->canFoldAsLoad())
1406 if (!
MI->isDereferenceableInvariantLoad())
1410 unsigned LoadRegIndex;
1412 TII->getOpcodeAfterMemoryUnfold(
MI->getOpcode(),
1416 if (NewOpc == 0)
return nullptr;
1417 const MCInstrDesc &MID =
TII->get(NewOpc);
1423 SmallVector<MachineInstr *, 2> NewMIs;
1429 "unfoldMemoryOperand failed when getOpcodeAfterMemoryUnfold "
1432 "Unfolded a load into multiple instructions!");
1439 if (!IsLoopInvariantInst(*NewMIs[0], CurLoop) ||
1440 !IsProfitableToHoist(*NewMIs[0], CurLoop)) {
1441 NewMIs[0]->eraseFromParent();
1442 NewMIs[1]->eraseFromParent();
1447 UpdateRegPressure(NewMIs[1]);
1452 if (
MI->shouldUpdateAdditionalCallInfo())
1455 MI->eraseFromParent();
1462void MachineLICMImpl::InitCSEMap(MachineBasicBlock *BB) {
1463 for (MachineInstr &
MI : *BB)
1469void MachineLICMImpl::InitializeLoadsHoistableLoops() {
1475 while (!Worklist.empty()) {
1476 auto *
L = Worklist.pop_back_val();
1477 AllowedToHoistLoads[
L] =
true;
1490 for (
auto *
MBB :
Loop->blocks()) {
1492 if (!AllowedToHoistLoads[
Loop])
1494 for (
auto &
MI : *
MBB) {
1495 if (!
MI.isLoadFoldBarrier() && !
MI.mayStore() && !
MI.isCall() &&
1496 !(
MI.mayLoad() &&
MI.hasOrderedMemoryRef()))
1498 for (MachineLoop *L =
Loop;
L !=
nullptr;
L =
L->getParentLoop())
1499 AllowedToHoistLoads[
L] =
false;
1509MachineLICMImpl::LookForDuplicate(
const MachineInstr *
MI,
1510 std::vector<MachineInstr *> &PrevMIs) {
1511 for (MachineInstr *PrevMI : PrevMIs)
1512 if (
TII->produceSameValue(*
MI, *PrevMI, (PreRegAlloc ?
MRI :
nullptr)))
1522bool MachineLICMImpl::EliminateCSE(
1524 DenseMap<
unsigned, std::vector<MachineInstr *>>::iterator &CI) {
1527 if (
MI->isImplicitDef())
1532 if (
MI->mayLoad() && !
MI->isDereferenceableInvariantLoad())
1535 if (MachineInstr *Dup = LookForDuplicate(
MI, CI->second)) {
1540 SmallVector<unsigned, 2> Defs;
1541 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
1542 const MachineOperand &MO =
MI->getOperand(i);
1546 MO.
getReg() == Dup->getOperand(i).getReg()) &&
1547 "Instructions with different phys regs are not identical!");
1554 for (
unsigned i = 0, e = Defs.
size(); i != e; ++i) {
1555 unsigned Idx = Defs[i];
1557 Register DupReg = Dup->getOperand(Idx).getReg();
1562 for (
unsigned j = 0;
j != i; ++
j)
1568 for (
unsigned Idx : Defs) {
1570 Register DupReg = Dup->getOperand(Idx).getReg();
1575 Dup->getOperand(Idx).setIsDead(
false);
1578 MI->eraseFromParent();
1587bool MachineLICMImpl::MayCSE(MachineInstr *
MI) {
1588 if (
MI->mayLoad() && !
MI->isDereferenceableInvariantLoad())
1591 unsigned Opcode =
MI->getOpcode();
1592 for (
auto &Map : CSEMap) {
1595 DenseMap<unsigned, std::vector<MachineInstr *>>::iterator CI =
1596 Map.second.find(Opcode);
1599 if (CI ==
Map.second.end() ||
MI->isImplicitDef())
1601 if (LookForDuplicate(
MI, CI->second) !=
nullptr)
1612unsigned MachineLICMImpl::Hoist(MachineInstr *
MI, MachineBasicBlock *Preheader,
1613 MachineLoop *CurLoop) {
1614 MachineBasicBlock *SrcBlock =
MI->getParent();
1619 isTgtHotterThanSrc(SrcBlock, Preheader)) {
1620 ++NumNotHoistedDueToHotness;
1621 return HoistResult::NotHoisted;
1624 bool HasExtractHoistableLoad =
false;
1625 if (!IsLoopInvariantInst(*
MI, CurLoop) ||
1626 !IsProfitableToHoist(*
MI, CurLoop)) {
1628 MI = ExtractHoistableLoad(
MI, CurLoop);
1630 return HoistResult::NotHoisted;
1631 HasExtractHoistableLoad =
true;
1642 dbgs() <<
"Hoisting " << *
MI;
1643 if (
MI->getParent()->getBasicBlock())
1653 InitCSEMap(Preheader);
1654 FirstInLoop =
false;
1658 unsigned Opcode =
MI->getOpcode();
1659 bool HasCSEDone =
false;
1660 for (
auto &Map : CSEMap) {
1663 DenseMap<unsigned, std::vector<MachineInstr *>>::iterator CI =
1664 Map.second.find(Opcode);
1665 if (CI !=
Map.second.end()) {
1666 if (EliminateCSE(
MI, CI)) {
1681 assert(!
MI->isDebugInstr() &&
"Should not hoist debug inst");
1685 UpdateBackTraceRegPressure(
MI);
1690 for (MachineOperand &MO :
MI->all_defs())
1694 CSEMap[Preheader][Opcode].push_back(
MI);
1700 if (HasCSEDone || HasExtractHoistableLoad)
1701 return HoistResult::Hoisted | HoistResult::ErasedMI;
1702 return HoistResult::Hoisted;
1706MachineBasicBlock *MachineLICMImpl::getOrCreatePreheader(MachineLoop *CurLoop) {
1715 MachineBasicBlock *NewPreheader =
1716 Pred->SplitCriticalEdge(CurLoop->
getHeader(), LegacyPass, MFAM, MDTU);
1719 return NewPreheader;
1727bool MachineLICMImpl::isTgtHotterThanSrc(MachineBasicBlock *SrcBlock,
1728 MachineBasicBlock *TgtBlock) {
1737 double Ratio = (double)DstBF / SrcBF;
1743template <
typename DerivedT,
bool PreRegAlloc>
1746 bool Changed = MachineLICMImpl(PreRegAlloc,
nullptr, &MFAM).run(MF);