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 const RegisterClassInfo *RegClassInfo =
nullptr;
127 TargetSchedModel SchedModel;
128 bool PreRegAlloc =
false;
129 bool HasProfileData =
false;
135 MachineBlockFrequencyInfo *MBFI =
nullptr;
136 MachineLoopInfo *MLI =
nullptr;
137 MachineDomTreeUpdater *MDTU =
nullptr;
140 bool Changed =
false;
141 bool FirstInLoop =
false;
145 SmallDenseMap<MachineLoop *, bool> AllowedToHoistLoads;
148 DenseMap<MachineLoop *, SmallVector<MachineBasicBlock *, 8>> ExitBlockMap;
150 bool isExitBlock(MachineLoop *CurLoop,
const MachineBasicBlock *
MBB) {
151 auto [It,
Inserted] = ExitBlockMap.try_emplace(CurLoop);
155 It->second = std::move(ExitBlocks);
161 SmallDenseSet<Register> RegSeen;
162 SmallVector<unsigned, 8> RegPressure;
166 SmallVector<unsigned, 8> RegLimit;
172 DenseMap<MachineBasicBlock *,
173 DenseMap<unsigned, std::vector<MachineInstr *>>>
185 unsigned SpeculationState = SpeculateUnknown;
188 MachineLICMImpl(
bool PreRegAlloc,
Pass *LegacyPass,
190 : PreRegAlloc(PreRegAlloc), LegacyPass(LegacyPass), MFAM(MFAM) {
191 assert((LegacyPass || MFAM) &&
"LegacyPass or MFAM must be provided");
192 assert(!(LegacyPass && MFAM) &&
193 "LegacyPass and MFAM cannot be provided at the same time");
196 bool run(MachineFunction &MF);
198 void releaseMemory() {
204 ExitBlockMap.clear();
209 struct CandidateInfo {
214 CandidateInfo(MachineInstr *mi,
Register def,
int fi)
215 : MI(mi), Def(def), FI(fi) {}
218 void HoistRegionPostRA(MachineLoop *CurLoop);
220 void HoistPostRA(MachineInstr *
MI,
Register Def, MachineLoop *CurLoop);
222 void ProcessMI(MachineInstr *
MI, BitVector &RUDefs, BitVector &RUClobbers,
223 SmallDenseSet<int> &StoredFIs,
224 SmallVectorImpl<CandidateInfo> &Candidates,
225 MachineLoop *CurLoop);
227 void AddToLiveIns(MCRegister
Reg, MachineLoop *CurLoop);
229 bool IsLICMCandidate(MachineInstr &
I, MachineLoop *CurLoop);
231 bool IsLoopInvariantInst(MachineInstr &
I, MachineLoop *CurLoop);
233 bool HasLoopPHIUse(
const MachineInstr *
MI, MachineLoop *CurLoop);
235 bool HasHighOperandLatency(MachineInstr &
MI,
unsigned DefIdx,
Register Reg,
236 MachineLoop *CurLoop)
const;
238 bool IsCheapInstruction(MachineInstr &
MI)
const;
240 bool CanCauseHighRegPressure(
const SmallDenseMap<unsigned, int> &
Cost,
243 void UpdateBackTraceRegPressure(
const MachineInstr *
MI);
245 bool IsProfitableToHoist(MachineInstr &
MI, MachineLoop *CurLoop);
247 bool IsGuaranteedToExecute(MachineBasicBlock *BB, MachineLoop *CurLoop);
249 void EnterScope(MachineBasicBlock *
MBB);
251 void ExitScope(MachineBasicBlock *
MBB);
253 void ExitScopeIfDone(
255 DenseMap<MachineDomTreeNode *, unsigned> &OpenChildren,
256 const DenseMap<MachineDomTreeNode *, MachineDomTreeNode *> &ParentMap);
260 void InitRegPressure(MachineBasicBlock *BB);
262 SmallDenseMap<unsigned, int> calcRegisterCost(
const MachineInstr *
MI,
264 bool ConsiderUnseenAsDef);
266 void UpdateRegPressure(
const MachineInstr *
MI,
267 bool ConsiderUnseenAsDef =
false);
269 MachineInstr *ExtractHoistableLoad(MachineInstr *
MI, MachineLoop *CurLoop);
271 MachineInstr *LookForDuplicate(
const MachineInstr *
MI,
272 std::vector<MachineInstr *> &PrevMIs);
275 EliminateCSE(MachineInstr *
MI,
276 DenseMap<
unsigned, std::vector<MachineInstr *>>::iterator &CI);
278 bool MayCSE(MachineInstr *
MI);
280 unsigned Hoist(MachineInstr *
MI, MachineBasicBlock *Preheader,
281 MachineLoop *CurLoop);
283 void InitCSEMap(MachineBasicBlock *BB);
285 void InitializeLoadsHoistableLoops();
287 bool isTgtHotterThanSrc(MachineBasicBlock *SrcBlock,
288 MachineBasicBlock *TgtBlock);
289 MachineBasicBlock *getOrCreatePreheader(MachineLoop *CurLoop);
296 MachineLICMBase(
char &ID,
bool PreRegAlloc)
297 : MachineFunctionPass(
ID), PreRegAlloc(PreRegAlloc) {}
299 bool runOnMachineFunction(MachineFunction &MF)
override;
301 void getAnalysisUsage(AnalysisUsage &AU)
const override {
304 AU.
addRequired<MachineBlockFrequencyInfoWrapperPass>();
306 AU.
addRequired<MachineRegisterClassInfoWrapperPass>();
314 class MachineLICM :
public MachineLICMBase {
317 MachineLICM() : MachineLICMBase(ID,
false) {}
320 class EarlyMachineLICM :
public MachineLICMBase {
323 EarlyMachineLICM() : MachineLICMBase(ID,
true) {}
329char EarlyMachineLICM::ID;
335 "Machine Loop Invariant Code Motion",
false,
false)
345 "Early Machine Loop Invariant Code Motion",
false,
false)
352 "Early Machine Loop Invariant Code Motion",
false,
false)
355 if (skipFunction(MF.getFunction()))
358 MachineLICMImpl Impl(PreRegAlloc,
this,
nullptr);
362#define GET_RESULT(RESULT, GETTER, INFIX) \
364 ? &LegacyPass->getAnalysis<RESULT##INFIX##WrapperPass>().GETTER() \
365 : &MFAM->getResult<RESULT##Analysis>(MF))
381 MachineDomTreeUpdater::UpdateStrategy::Lazy);
385 ?
GET_RESULT(MachineBlockFrequency, getMBFI, Info)
390 TII = ST.getInstrInfo();
391 TLI = ST.getTargetLowering();
392 TRI = ST.getRegisterInfo();
395 SchedModel.
init(&ST);
407 unsigned NumRPS =
TRI->getNumRegPressureSets();
408 RegPressure.resize(NumRPS);
411 for (
unsigned i = 0, e = NumRPS; i != e; ++i)
416 InitializeLoadsHoistableLoops();
419 while (!Worklist.
empty()) {
423 HoistRegionPostRA(CurLoop);
429 HoistOutOfLoop(
N, CurLoop);
445 if (
MI->memoperands_empty())
448 if (!
MemOp->isStore() || !
MemOp->getPseudoValue())
452 if (
Value->getFrameIndex() == FI)
493 const unsigned NumRegs =
TRI.getNumRegs();
494 const unsigned MaskWords = (NumRegs + 31) / 32;
495 for (
unsigned K = 0; K < MaskWords; ++K) {
497 for (
unsigned Bit = 0; Bit < 32; ++Bit) {
498 const unsigned PhysReg = (K * 32) + Bit;
499 if (PhysReg == NumRegs)
502 if (PhysReg && !((Word >> Bit) & 1)) {
503 for (MCRegUnit Unit :
TRI.regunits(PhysReg))
504 RUsFromRegsNotInMask.
set(
static_cast<unsigned>(Unit));
509 RUs |= RUsFromRegsNotInMask;
514void MachineLICMImpl::ProcessMI(MachineInstr *
MI, BitVector &RUDefs,
515 BitVector &RUClobbers,
516 SmallDenseSet<int> &StoredFIs,
517 SmallVectorImpl<CandidateInfo> &Candidates,
518 MachineLoop *CurLoop) {
519 bool RuledOut =
false;
520 bool HasNonInvariantUse =
false;
522 for (
const MachineOperand &MO :
MI->operands()) {
525 int FI = MO.getIndex();
526 if (!StoredFIs.
count(FI) &&
530 HasNonInvariantUse =
true;
536 if (MO.isRegMask()) {
549 if (!HasNonInvariantUse) {
550 for (MCRegUnit Unit :
TRI->regunits(
Reg)) {
553 if (RUDefs.
test(
static_cast<unsigned>(Unit)) ||
554 RUClobbers.
test(
static_cast<unsigned>(Unit))) {
555 HasNonInvariantUse =
true;
574 for (MCRegUnit Unit :
TRI->regunits(
Reg)) {
575 if (RUDefs.
test(
static_cast<unsigned>(Unit))) {
576 RUClobbers.
set(
static_cast<unsigned>(Unit));
578 }
else if (RUClobbers.
test(
static_cast<unsigned>(Unit))) {
584 RUDefs.
set(
static_cast<unsigned>(Unit));
590 if (Def && !RuledOut) {
591 int FI = std::numeric_limits<int>::min();
592 if ((!HasNonInvariantUse && IsLICMCandidate(*
MI, CurLoop)) ||
600void MachineLICMImpl::HoistRegionPostRA(MachineLoop *CurLoop) {
601 MachineBasicBlock *Preheader = getOrCreatePreheader(CurLoop);
605 unsigned NumRegUnits =
TRI->getNumRegUnits();
606 BitVector RUDefs(NumRegUnits);
607 BitVector RUClobbers(NumRegUnits);
610 SmallDenseSet<int> StoredFIs;
614 for (MachineBasicBlock *BB : CurLoop->
getBlocks()) {
618 if (
ML &&
ML->getHeader()->isEHPad())
continue;
623 for (
const auto &LI : BB->liveins()) {
624 for (MCRegUnit Unit :
TRI->regunits(LI.PhysReg))
625 RUDefs.
set(
static_cast<unsigned>(Unit));
629 if (
const uint32_t *Mask = BB->getBeginClobberMask(
TRI))
634 const MachineFunction &MF = *BB->getParent();
638 for (MCRegUnit Unit :
TRI->regunits(
Reg))
639 RUClobbers.
set(
static_cast<unsigned>(Unit));
641 for (MCRegUnit Unit :
TRI->regunits(
Reg))
642 RUClobbers.
set(
static_cast<unsigned>(Unit));
645 SpeculationState = SpeculateUnknown;
646 for (MachineInstr &
MI : *BB)
647 ProcessMI(&
MI, RUDefs, RUClobbers, StoredFIs, Candidates, CurLoop);
651 BitVector TermRUs(NumRegUnits);
653 if (TI != Preheader->
end()) {
654 for (
const MachineOperand &MO : TI->operands()) {
660 for (MCRegUnit Unit :
TRI->regunits(
Reg))
661 TermRUs.set(
static_cast<unsigned>(Unit));
673 for (CandidateInfo &Candidate : Candidates) {
674 if (Candidate.FI != std::numeric_limits<int>::min() &&
675 StoredFIs.
count(Candidate.FI))
680 for (MCRegUnit Unit :
TRI->regunits(Def)) {
681 if (RUClobbers.
test(
static_cast<unsigned>(Unit)) ||
682 TermRUs.test(
static_cast<unsigned>(Unit))) {
691 MachineInstr *
MI = Candidate.MI;
692 for (
const MachineOperand &MO :
MI->all_uses()) {
695 for (MCRegUnit Unit :
TRI->regunits(MO.getReg())) {
696 if (RUDefs.
test(
static_cast<unsigned>(Unit)) ||
697 RUClobbers.
test(
static_cast<unsigned>(Unit))) {
710 HoistPostRA(
MI, Candidate.Def, CurLoop);
716void MachineLICMImpl::AddToLiveIns(MCRegister
Reg, MachineLoop *CurLoop) {
717 for (MachineBasicBlock *BB : CurLoop->
getBlocks()) {
718 if (!BB->isLiveIn(
Reg))
720 for (MachineInstr &
MI : *BB) {
721 for (MachineOperand &MO :
MI.all_uses()) {
724 if (
TRI->regsOverlap(
Reg, MO.getReg()))
733void MachineLICMImpl::HoistPostRA(MachineInstr *
MI,
Register Def,
734 MachineLoop *CurLoop) {
744 MachineBasicBlock *
MBB =
MI->getParent();
750 assert(!
MI->isDebugInstr() &&
"Should not hoist debug inst");
756 AddToLiveIns(Def, CurLoop);
764bool MachineLICMImpl::IsGuaranteedToExecute(MachineBasicBlock *BB,
765 MachineLoop *CurLoop) {
766 if (SpeculationState != SpeculateUnknown)
767 return SpeculationState == SpeculateFalse;
773 for (MachineBasicBlock *CurrentLoopExitingBlock : CurrentLoopExitingBlocks)
775 SpeculationState = SpeculateTrue;
780 SpeculationState = SpeculateFalse;
784void MachineLICMImpl::EnterScope(MachineBasicBlock *
MBB) {
791void MachineLICMImpl::ExitScope(MachineBasicBlock *
MBB) {
799void MachineLICMImpl::ExitScopeIfDone(
801 DenseMap<MachineDomTreeNode *, unsigned> &OpenChildren,
802 const DenseMap<MachineDomTreeNode *, MachineDomTreeNode *> &ParentMap) {
803 if (OpenChildren[Node])
807 ExitScope(
Node->getBlock());
810 if (!Parent || --OpenChildren[Parent] != 0)
821 MachineLoop *CurLoop) {
822 MachineBasicBlock *Preheader = getOrCreatePreheader(CurLoop);
828 DenseMap<MachineDomTreeNode*, MachineDomTreeNode*> ParentMap;
829 DenseMap<MachineDomTreeNode*, unsigned> OpenChildren;
833 while (!WorkList.
empty()) {
835 assert(Node &&
"Null dominator tree node?");
836 MachineBasicBlock *BB =
Node->getBlock();
841 if (
ML &&
ML->getHeader()->isEHPad())
854 OpenChildren[
Node] = 0;
861 size_t WorkListStart = WorkList.
size();
863 ParentMap[Child] =
Node;
866 std::reverse(WorkList.
begin() + WorkListStart, WorkList.
end());
867 OpenChildren[
Node] = WorkList.
size() - WorkListStart;
876 InitRegPressure(Preheader);
880 MachineBasicBlock *
MBB =
Node->getBlock();
885 SpeculationState = SpeculateUnknown;
887 unsigned HoistRes = HoistResult::NotHoisted;
888 HoistRes = Hoist(&
MI, Preheader, CurLoop);
889 if (HoistRes & HoistResult::NotHoisted) {
892 SmallVector<MachineLoop *> InnerLoopWorkList;
893 for (MachineLoop *L = MLI->
getLoopFor(
MI.getParent()); L != CurLoop;
894 L =
L->getParentLoop())
897 while (!InnerLoopWorkList.
empty()) {
898 MachineLoop *InnerLoop = InnerLoopWorkList.
pop_back_val();
900 if (InnerLoopPreheader) {
901 HoistRes = Hoist(&
MI, InnerLoopPreheader, InnerLoop);
902 if (HoistRes & HoistResult::Hoisted)
908 if (HoistRes & HoistResult::ErasedMI)
911 UpdateRegPressure(&
MI);
915 ExitScopeIfDone(Node, OpenChildren, ParentMap);
926void MachineLICMImpl::InitRegPressure(MachineBasicBlock *BB) {
934 MachineBasicBlock *
TBB =
nullptr, *FBB =
nullptr;
940 for (
const MachineInstr &
MI : *BB)
941 UpdateRegPressure(&
MI,
true);
945void MachineLICMImpl::UpdateRegPressure(
const MachineInstr *
MI,
946 bool ConsiderUnseenAsDef) {
947 auto Cost = calcRegisterCost(
MI,
true, ConsiderUnseenAsDef);
948 for (
const auto &[Class, Weight] :
Cost) {
949 if (
static_cast<int>(RegPressure[Class]) < -Weight)
962SmallDenseMap<unsigned, int>
963MachineLICMImpl::calcRegisterCost(
const MachineInstr *
MI,
bool ConsiderSeen,
964 bool ConsiderUnseenAsDef) {
965 SmallDenseMap<unsigned, int>
Cost;
966 if (
MI->isImplicitDef())
968 for (
unsigned i = 0, e =
MI->getDesc().getNumOperands(); i != e; ++i) {
969 const MachineOperand &MO =
MI->getOperand(i);
977 bool isNew = ConsiderSeen ? RegSeen.
insert(
Reg).second :
false;
980 RegClassWeight
W =
TRI->getRegClassWeight(RC);
983 RCCost =
W.RegWeight;
986 if (isNew && !isKill && ConsiderUnseenAsDef)
988 RCCost =
W.RegWeight;
989 else if (!isNew && isKill)
990 RCCost = -
W.RegWeight;
994 const int *PS =
TRI->getRegClassPressureSets(RC);
995 for (; *PS != -1; ++PS)
1004 assert(
MI.mayLoad() &&
"Expected MI that loads!");
1008 if (
MI.memoperands_empty())
1013 if (PSV->isGOT() || PSV->isConstantPool())
1030 bool FoundCallerPresReg =
false;
1031 if (!
MI.mayStore() ||
MI.hasUnmodeledSideEffects() ||
1032 (
MI.getNumOperands() == 0))
1041 if (
Reg.isVirtual())
1043 if (
Reg.isVirtual())
1045 if (!
TRI->isCallerPreservedPhysReg(
Reg.asMCReg(), *
MI.getMF()))
1048 FoundCallerPresReg =
true;
1049 }
else if (!MO.
isImm()) {
1053 return FoundCallerPresReg;
1071 Register CopySrcReg =
MI.getOperand(1).getReg();
1075 if (!
TRI->isCallerPreservedPhysReg(CopySrcReg.
asMCReg(), *MF))
1078 Register CopyDstReg =
MI.getOperand(0).getReg();
1091bool MachineLICMImpl::IsLICMCandidate(MachineInstr &
I, MachineLoop *CurLoop) {
1093 bool DontMoveAcrossStore = !
HoistConstLoads || !AllowedToHoistLoads[CurLoop];
1094 if ((!
I.isSafeToMove(DontMoveAcrossStore)) &&
1107 !IsGuaranteedToExecute(
I.getParent(), CurLoop)) {
1116 if (
I.isConvergent())
1119 if (!
TII->shouldHoist(
I, CurLoop))
1126bool MachineLICMImpl::IsLoopInvariantInst(MachineInstr &
I,
1127 MachineLoop *CurLoop) {
1128 if (!IsLICMCandidate(
I, CurLoop)) {
1129 LLVM_DEBUG(
dbgs() <<
"LICM: Instruction not a LICM candidate\n");
1137bool MachineLICMImpl::HasLoopPHIUse(
const MachineInstr *
MI,
1138 MachineLoop *CurLoop) {
1141 MI = Work.pop_back_val();
1142 for (
const MachineOperand &MO :
MI->all_defs()) {
1148 if (
UseMI.isPHI()) {
1162 Work.push_back(&
UseMI);
1165 }
while (!Work.empty());
1171bool MachineLICMImpl::HasHighOperandLatency(MachineInstr &
MI,
unsigned DefIdx,
1173 MachineLoop *CurLoop)
const {
1178 if (
UseMI.isCopyLike())
1182 for (
unsigned i = 0, e =
UseMI.getNumOperands(); i != e; ++i) {
1183 const MachineOperand &MO =
UseMI.getOperand(i);
1190 if (
TII->hasHighOperandLatency(SchedModel, MRI,
MI, DefIdx,
UseMI, i))
1203bool MachineLICMImpl::IsCheapInstruction(MachineInstr &
MI)
const {
1207 bool isCheap =
false;
1208 unsigned NumDefs =
MI.getDesc().getNumDefs();
1209 for (
unsigned i = 0, e =
MI.getNumOperands(); NumDefs && i != e; ++i) {
1210 MachineOperand &DefMO =
MI.getOperand(i);
1218 if (!
TII->hasLowDefLatency(SchedModel,
MI, i))
1228bool MachineLICMImpl::CanCauseHighRegPressure(
1229 const SmallDenseMap<unsigned, int> &
Cost,
bool CheapInstr) {
1230 for (
const auto &[Class, Weight] :
Cost) {
1234 int Limit = RegLimit[
Class];
1241 for (
const auto &RP : BackTrace)
1242 if (
static_cast<int>(RP[Class]) + Weight >= Limit)
1252void MachineLICMImpl::UpdateBackTraceRegPressure(
const MachineInstr *
MI) {
1255 auto Cost = calcRegisterCost(
MI,
false,
1259 for (
auto &RP : BackTrace)
1260 for (
const auto &[Class, Weight] :
Cost)
1266bool MachineLICMImpl::IsProfitableToHoist(MachineInstr &
MI,
1267 MachineLoop *CurLoop) {
1268 if (
MI.isImplicitDef())
1286 bool CheapInstr = IsCheapInstruction(
MI);
1287 bool CreatesCopy = HasLoopPHIUse(&
MI, CurLoop);
1290 if (CheapInstr && CreatesCopy) {
1297 if (
TII->isTriviallyReMaterializable(
MI))
1302 for (
unsigned i = 0, e =
MI.getDesc().getNumOperands(); i != e; ++i) {
1303 const MachineOperand &MO =
MI.getOperand(i);
1309 if (MO.
isDef() && HasHighOperandLatency(
MI, i,
Reg, CurLoop)) {
1322 auto Cost = calcRegisterCost(&
MI,
false,
1327 if (!CanCauseHighRegPressure(
Cost, CheapInstr)) {
1343 (!IsGuaranteedToExecute(
MI.getParent(), CurLoop) && !MayCSE(&
MI))) {
1351 if (
MI.isCopy() ||
MI.isRegSequence()) {
1355 [
this](
const MachineOperand &UseOp) {
1356 return !UseOp.isReg() || UseOp.getReg().isVirtual() ||
1357 MRI->isConstantPhysReg(UseOp.getReg());
1359 IsLoopInvariantInst(
MI, CurLoop) &&
1361 [&CurLoop,
this, DefReg,
1363 if (!CurLoop->contains(&UseMI))
1370 if (CanCauseHighRegPressure(Cost, false) &&
1371 !CurLoop->isLoopInvariant(UseMI, DefReg))
1381 if (!
TII->isTriviallyReMaterializable(
MI) &&
1382 !
MI.isDereferenceableInvariantLoad()) {
1393MachineInstr *MachineLICMImpl::ExtractHoistableLoad(MachineInstr *
MI,
1394 MachineLoop *CurLoop) {
1396 if (
MI->canFoldAsLoad())
1402 if (!
MI->isDereferenceableInvariantLoad())
1406 unsigned LoadRegIndex;
1408 TII->getOpcodeAfterMemoryUnfold(
MI->getOpcode(),
1412 if (NewOpc == 0)
return nullptr;
1413 const MCInstrDesc &MID =
TII->get(NewOpc);
1414 MachineFunction &MF = *
MI->getMF();
1419 SmallVector<MachineInstr *, 2> NewMIs;
1425 "unfoldMemoryOperand failed when getOpcodeAfterMemoryUnfold "
1428 "Unfolded a load into multiple instructions!");
1429 MachineBasicBlock *
MBB =
MI->getParent();
1435 if (!IsLoopInvariantInst(*NewMIs[0], CurLoop) ||
1436 !IsProfitableToHoist(*NewMIs[0], CurLoop)) {
1437 NewMIs[0]->eraseFromParent();
1438 NewMIs[1]->eraseFromParent();
1443 UpdateRegPressure(NewMIs[1]);
1448 if (
MI->shouldUpdateAdditionalCallInfo())
1451 MI->eraseFromParent();
1458void MachineLICMImpl::InitCSEMap(MachineBasicBlock *BB) {
1459 for (MachineInstr &
MI : *BB)
1465void MachineLICMImpl::InitializeLoadsHoistableLoops() {
1471 while (!Worklist.empty()) {
1472 auto *
L = Worklist.pop_back_val();
1473 AllowedToHoistLoads[
L] =
true;
1485 for (
auto *Loop :
reverse(LoopsInPreOrder)) {
1486 for (
auto *
MBB : Loop->blocks()) {
1488 if (!AllowedToHoistLoads[Loop])
1490 for (
auto &
MI : *
MBB) {
1491 if (!
MI.isLoadFoldBarrier() && !
MI.mayStore() && !
MI.isCall() &&
1492 !(
MI.mayLoad() &&
MI.hasOrderedMemoryRef()))
1494 for (MachineLoop *L = Loop;
L !=
nullptr;
L =
L->getParentLoop())
1495 AllowedToHoistLoads[
L] =
false;
1505MachineLICMImpl::LookForDuplicate(
const MachineInstr *
MI,
1506 std::vector<MachineInstr *> &PrevMIs) {
1507 for (MachineInstr *PrevMI : PrevMIs)
1508 if (
TII->produceSameValue(*
MI, *PrevMI, (PreRegAlloc ? MRI :
nullptr)))
1518bool MachineLICMImpl::EliminateCSE(
1520 DenseMap<
unsigned, std::vector<MachineInstr *>>::iterator &CI) {
1523 if (
MI->isImplicitDef())
1528 if (
MI->mayLoad() && !
MI->isDereferenceableInvariantLoad())
1531 if (MachineInstr *Dup = LookForDuplicate(
MI, CI->second)) {
1536 SmallVector<unsigned, 2> Defs;
1537 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
1538 const MachineOperand &MO =
MI->getOperand(i);
1542 MO.
getReg() == Dup->getOperand(i).getReg()) &&
1543 "Instructions with different phys regs are not identical!");
1550 for (
unsigned i = 0, e = Defs.
size(); i != e; ++i) {
1551 unsigned Idx = Defs[i];
1553 Register DupReg = Dup->getOperand(Idx).getReg();
1558 for (
unsigned j = 0;
j != i; ++
j)
1559 MRI->
setRegClass(Dup->getOperand(Defs[j]).getReg(), OrigRCs[j]);
1564 for (
unsigned Idx : Defs) {
1566 Register DupReg = Dup->getOperand(Idx).getReg();
1571 Dup->getOperand(Idx).setIsDead(
false);
1574 MI->eraseFromParent();
1583bool MachineLICMImpl::MayCSE(MachineInstr *
MI) {
1584 if (
MI->mayLoad() && !
MI->isDereferenceableInvariantLoad())
1587 unsigned Opcode =
MI->getOpcode();
1588 for (
auto &Map : CSEMap) {
1591 DenseMap<unsigned, std::vector<MachineInstr *>>::iterator CI =
1592 Map.second.find(Opcode);
1595 if (CI ==
Map.second.end() ||
MI->isImplicitDef())
1597 if (LookForDuplicate(
MI, CI->second) !=
nullptr)
1608unsigned MachineLICMImpl::Hoist(MachineInstr *
MI, MachineBasicBlock *Preheader,
1609 MachineLoop *CurLoop) {
1610 MachineBasicBlock *SrcBlock =
MI->getParent();
1615 isTgtHotterThanSrc(SrcBlock, Preheader)) {
1616 ++NumNotHoistedDueToHotness;
1617 return HoistResult::NotHoisted;
1620 bool HasExtractHoistableLoad =
false;
1621 if (!IsLoopInvariantInst(*
MI, CurLoop) ||
1622 !IsProfitableToHoist(*
MI, CurLoop)) {
1624 MI = ExtractHoistableLoad(
MI, CurLoop);
1626 return HoistResult::NotHoisted;
1627 HasExtractHoistableLoad =
true;
1638 dbgs() <<
"Hoisting " << *
MI;
1639 if (
MI->getParent()->getBasicBlock())
1649 InitCSEMap(Preheader);
1650 FirstInLoop =
false;
1654 unsigned Opcode =
MI->getOpcode();
1655 bool HasCSEDone =
false;
1656 for (
auto &Map : CSEMap) {
1659 DenseMap<unsigned, std::vector<MachineInstr *>>::iterator CI =
1660 Map.second.find(Opcode);
1661 if (CI !=
Map.second.end()) {
1662 if (EliminateCSE(
MI, CI)) {
1677 assert(!
MI->isDebugInstr() &&
"Should not hoist debug inst");
1681 UpdateBackTraceRegPressure(
MI);
1686 for (MachineOperand &MO :
MI->all_defs())
1690 CSEMap[Preheader][Opcode].push_back(
MI);
1696 if (HasCSEDone || HasExtractHoistableLoad)
1697 return HoistResult::Hoisted | HoistResult::ErasedMI;
1698 return HoistResult::Hoisted;
1702MachineBasicBlock *MachineLICMImpl::getOrCreatePreheader(MachineLoop *CurLoop) {
1711 MachineBasicBlock *NewPreheader = Pred->SplitCriticalEdge(
1712 CurLoop->
getHeader(), LegacyPass, MFAM,
nullptr, MDTU);
1715 return NewPreheader;
1723bool MachineLICMImpl::isTgtHotterThanSrc(MachineBasicBlock *SrcBlock,
1724 MachineBasicBlock *TgtBlock) {
1733 double Ratio = (double)DstBF / SrcBF;
1739template <
typename DerivedT,
bool PreRegAlloc>
1742 bool Changed = MachineLICMImpl(PreRegAlloc,
nullptr, &MFAM).run(MF);