10b57cec5SDimitry Andric //===- MachineLICM.cpp - Machine Loop Invariant Code Motion Pass ----------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This pass performs loop invariant code motion on machine instructions. We
100b57cec5SDimitry Andric // attempt to remove as much code from the body of a loop as possible.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric // This pass is not intended to be a replacement or a complete alternative
130b57cec5SDimitry Andric // for the LLVM-IR-level LICM pass. It is only designed to hoist simple
140b57cec5SDimitry Andric // constructs that are not exposed before lowering and instruction selection.
150b57cec5SDimitry Andric //
160b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
170b57cec5SDimitry Andric
180b57cec5SDimitry Andric #include "llvm/ADT/BitVector.h"
190b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h"
200b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
210b57cec5SDimitry Andric #include "llvm/ADT/SmallSet.h"
220b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
230b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h"
240b57cec5SDimitry Andric #include "llvm/Analysis/AliasAnalysis.h"
250b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
26480093f4SDimitry Andric #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
270b57cec5SDimitry Andric #include "llvm/CodeGen/MachineDominators.h"
280b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
290b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
300b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h"
310b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
320b57cec5SDimitry Andric #include "llvm/CodeGen/MachineLoopInfo.h"
330b57cec5SDimitry Andric #include "llvm/CodeGen/MachineMemOperand.h"
340b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
350b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
360b57cec5SDimitry Andric #include "llvm/CodeGen/PseudoSourceValue.h"
370b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
380b57cec5SDimitry Andric #include "llvm/CodeGen/TargetLowering.h"
390b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
400b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSchedule.h"
410b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
420b57cec5SDimitry Andric #include "llvm/IR/DebugLoc.h"
43480093f4SDimitry Andric #include "llvm/InitializePasses.h"
440b57cec5SDimitry Andric #include "llvm/MC/MCInstrDesc.h"
45e8d8bef9SDimitry Andric #include "llvm/MC/MCRegister.h"
460b57cec5SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
470b57cec5SDimitry Andric #include "llvm/Pass.h"
480b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
490b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
500b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
510b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
520b57cec5SDimitry Andric #include <algorithm>
530b57cec5SDimitry Andric #include <cassert>
540b57cec5SDimitry Andric #include <limits>
550b57cec5SDimitry Andric #include <vector>
560b57cec5SDimitry Andric
570b57cec5SDimitry Andric using namespace llvm;
580b57cec5SDimitry Andric
590b57cec5SDimitry Andric #define DEBUG_TYPE "machinelicm"
600b57cec5SDimitry Andric
610b57cec5SDimitry Andric static cl::opt<bool>
620b57cec5SDimitry Andric AvoidSpeculation("avoid-speculation",
630b57cec5SDimitry Andric cl::desc("MachineLICM should avoid speculation"),
640b57cec5SDimitry Andric cl::init(true), cl::Hidden);
650b57cec5SDimitry Andric
660b57cec5SDimitry Andric static cl::opt<bool>
670b57cec5SDimitry Andric HoistCheapInsts("hoist-cheap-insts",
680b57cec5SDimitry Andric cl::desc("MachineLICM should hoist even cheap instructions"),
690b57cec5SDimitry Andric cl::init(false), cl::Hidden);
700b57cec5SDimitry Andric
710b57cec5SDimitry Andric static cl::opt<bool>
720b57cec5SDimitry Andric HoistConstStores("hoist-const-stores",
730b57cec5SDimitry Andric cl::desc("Hoist invariant stores"),
740b57cec5SDimitry Andric cl::init(true), cl::Hidden);
75*c9157d92SDimitry Andric
76*c9157d92SDimitry Andric static cl::opt<bool> HoistConstLoads("hoist-const-loads",
77*c9157d92SDimitry Andric cl::desc("Hoist invariant loads"),
78*c9157d92SDimitry Andric cl::init(true), cl::Hidden);
79*c9157d92SDimitry Andric
80480093f4SDimitry Andric // The default threshold of 100 (i.e. if target block is 100 times hotter)
81480093f4SDimitry Andric // is based on empirical data on a single target and is subject to tuning.
82480093f4SDimitry Andric static cl::opt<unsigned>
83480093f4SDimitry Andric BlockFrequencyRatioThreshold("block-freq-ratio-threshold",
84480093f4SDimitry Andric cl::desc("Do not hoist instructions if target"
85480093f4SDimitry Andric "block is N times hotter than the source."),
86480093f4SDimitry Andric cl::init(100), cl::Hidden);
87480093f4SDimitry Andric
88480093f4SDimitry Andric enum class UseBFI { None, PGO, All };
89480093f4SDimitry Andric
90480093f4SDimitry Andric static cl::opt<UseBFI>
91480093f4SDimitry Andric DisableHoistingToHotterBlocks("disable-hoisting-to-hotter-blocks",
92480093f4SDimitry Andric cl::desc("Disable hoisting instructions to"
93480093f4SDimitry Andric " hotter blocks"),
94e8d8bef9SDimitry Andric cl::init(UseBFI::PGO), cl::Hidden,
95480093f4SDimitry Andric cl::values(clEnumValN(UseBFI::None, "none",
96480093f4SDimitry Andric "disable the feature"),
97480093f4SDimitry Andric clEnumValN(UseBFI::PGO, "pgo",
98480093f4SDimitry Andric "enable the feature when using profile data"),
99480093f4SDimitry Andric clEnumValN(UseBFI::All, "all",
100480093f4SDimitry Andric "enable the feature with/wo profile data")));
1010b57cec5SDimitry Andric
1020b57cec5SDimitry Andric STATISTIC(NumHoisted,
1030b57cec5SDimitry Andric "Number of machine instructions hoisted out of loops");
1040b57cec5SDimitry Andric STATISTIC(NumLowRP,
1050b57cec5SDimitry Andric "Number of instructions hoisted in low reg pressure situation");
1060b57cec5SDimitry Andric STATISTIC(NumHighLatency,
1070b57cec5SDimitry Andric "Number of high latency instructions hoisted");
1080b57cec5SDimitry Andric STATISTIC(NumCSEed,
1090b57cec5SDimitry Andric "Number of hoisted machine instructions CSEed");
1100b57cec5SDimitry Andric STATISTIC(NumPostRAHoisted,
1110b57cec5SDimitry Andric "Number of machine instructions hoisted out of loops post regalloc");
1120b57cec5SDimitry Andric STATISTIC(NumStoreConst,
1130b57cec5SDimitry Andric "Number of stores of const phys reg hoisted out of loops");
114480093f4SDimitry Andric STATISTIC(NumNotHoistedDueToHotness,
115480093f4SDimitry Andric "Number of instructions not hoisted due to block frequency");
1160b57cec5SDimitry Andric
1170b57cec5SDimitry Andric namespace {
118*c9157d92SDimitry Andric enum HoistResult { NotHoisted = 1, Hoisted = 2, ErasedMI = 4 };
1190b57cec5SDimitry Andric
1200b57cec5SDimitry Andric class MachineLICMBase : public MachineFunctionPass {
121fe013be4SDimitry Andric const TargetInstrInfo *TII = nullptr;
122fe013be4SDimitry Andric const TargetLoweringBase *TLI = nullptr;
123fe013be4SDimitry Andric const TargetRegisterInfo *TRI = nullptr;
124fe013be4SDimitry Andric const MachineFrameInfo *MFI = nullptr;
125fe013be4SDimitry Andric MachineRegisterInfo *MRI = nullptr;
1260b57cec5SDimitry Andric TargetSchedModel SchedModel;
127fe013be4SDimitry Andric bool PreRegAlloc = false;
128fe013be4SDimitry Andric bool HasProfileData = false;
1290b57cec5SDimitry Andric
1300b57cec5SDimitry Andric // Various analyses that we use...
131fe013be4SDimitry Andric AliasAnalysis *AA = nullptr; // Alias analysis info.
132fe013be4SDimitry Andric MachineBlockFrequencyInfo *MBFI = nullptr; // Machine block frequncy info
133fe013be4SDimitry Andric MachineLoopInfo *MLI = nullptr; // Current MachineLoopInfo
134fe013be4SDimitry Andric MachineDominatorTree *DT = nullptr; // Machine dominator tree for the cur loop
1350b57cec5SDimitry Andric
1360b57cec5SDimitry Andric // State that is updated as we process loops
137fe013be4SDimitry Andric bool Changed = false; // True if a loop is changed.
138fe013be4SDimitry Andric bool FirstInLoop = false; // True if it's the first LICM in the loop.
1390b57cec5SDimitry Andric
140*c9157d92SDimitry Andric // Holds information about whether it is allowed to move load instructions
141*c9157d92SDimitry Andric // out of the loop
142*c9157d92SDimitry Andric SmallDenseMap<MachineLoop *, bool> AllowedToHoistLoads;
143*c9157d92SDimitry Andric
144*c9157d92SDimitry Andric // Exit blocks of each Loop.
145*c9157d92SDimitry Andric DenseMap<MachineLoop *, SmallVector<MachineBasicBlock *, 8>> ExitBlockMap;
146*c9157d92SDimitry Andric
isExitBlock(MachineLoop * CurLoop,const MachineBasicBlock * MBB)147*c9157d92SDimitry Andric bool isExitBlock(MachineLoop *CurLoop, const MachineBasicBlock *MBB) {
148*c9157d92SDimitry Andric if (ExitBlockMap.contains(CurLoop))
149*c9157d92SDimitry Andric return is_contained(ExitBlockMap[CurLoop], MBB);
150*c9157d92SDimitry Andric
1510b57cec5SDimitry Andric SmallVector<MachineBasicBlock *, 8> ExitBlocks;
152*c9157d92SDimitry Andric CurLoop->getExitBlocks(ExitBlocks);
153*c9157d92SDimitry Andric ExitBlockMap[CurLoop] = ExitBlocks;
1540b57cec5SDimitry Andric return is_contained(ExitBlocks, MBB);
1550b57cec5SDimitry Andric }
1560b57cec5SDimitry Andric
1570b57cec5SDimitry Andric // Track 'estimated' register pressure.
158e8d8bef9SDimitry Andric SmallSet<Register, 32> RegSeen;
1590b57cec5SDimitry Andric SmallVector<unsigned, 8> RegPressure;
1600b57cec5SDimitry Andric
1610b57cec5SDimitry Andric // Register pressure "limit" per register pressure set. If the pressure
1620b57cec5SDimitry Andric // is higher than the limit, then it's considered high.
1630b57cec5SDimitry Andric SmallVector<unsigned, 8> RegLimit;
1640b57cec5SDimitry Andric
1650b57cec5SDimitry Andric // Register pressure on path leading from loop preheader to current BB.
1660b57cec5SDimitry Andric SmallVector<SmallVector<unsigned, 8>, 16> BackTrace;
1670b57cec5SDimitry Andric
168*c9157d92SDimitry Andric // For each opcode per preheader, keep a list of potential CSE instructions.
169*c9157d92SDimitry Andric DenseMap<MachineBasicBlock *,
170*c9157d92SDimitry Andric DenseMap<unsigned, std::vector<MachineInstr *>>>
171*c9157d92SDimitry Andric CSEMap;
1720b57cec5SDimitry Andric
1730b57cec5SDimitry Andric enum {
1740b57cec5SDimitry Andric SpeculateFalse = 0,
1750b57cec5SDimitry Andric SpeculateTrue = 1,
1760b57cec5SDimitry Andric SpeculateUnknown = 2
1770b57cec5SDimitry Andric };
1780b57cec5SDimitry Andric
1790b57cec5SDimitry Andric // If a MBB does not dominate loop exiting blocks then it may not safe
1800b57cec5SDimitry Andric // to hoist loads from this block.
1810b57cec5SDimitry Andric // Tri-state: 0 - false, 1 - true, 2 - unknown
182fe013be4SDimitry Andric unsigned SpeculationState = SpeculateUnknown;
1830b57cec5SDimitry Andric
1840b57cec5SDimitry Andric public:
MachineLICMBase(char & PassID,bool PreRegAlloc)1850b57cec5SDimitry Andric MachineLICMBase(char &PassID, bool PreRegAlloc)
1860b57cec5SDimitry Andric : MachineFunctionPass(PassID), PreRegAlloc(PreRegAlloc) {}
1870b57cec5SDimitry Andric
1880b57cec5SDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override;
1890b57cec5SDimitry Andric
getAnalysisUsage(AnalysisUsage & AU) const1900b57cec5SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override {
1910b57cec5SDimitry Andric AU.addRequired<MachineLoopInfo>();
192480093f4SDimitry Andric if (DisableHoistingToHotterBlocks != UseBFI::None)
193480093f4SDimitry Andric AU.addRequired<MachineBlockFrequencyInfo>();
1940b57cec5SDimitry Andric AU.addRequired<MachineDominatorTree>();
1950b57cec5SDimitry Andric AU.addRequired<AAResultsWrapperPass>();
1960b57cec5SDimitry Andric AU.addPreserved<MachineLoopInfo>();
1970b57cec5SDimitry Andric MachineFunctionPass::getAnalysisUsage(AU);
1980b57cec5SDimitry Andric }
1990b57cec5SDimitry Andric
releaseMemory()2000b57cec5SDimitry Andric void releaseMemory() override {
2010b57cec5SDimitry Andric RegSeen.clear();
2020b57cec5SDimitry Andric RegPressure.clear();
2030b57cec5SDimitry Andric RegLimit.clear();
2040b57cec5SDimitry Andric BackTrace.clear();
2050b57cec5SDimitry Andric CSEMap.clear();
206*c9157d92SDimitry Andric ExitBlockMap.clear();
2070b57cec5SDimitry Andric }
2080b57cec5SDimitry Andric
2090b57cec5SDimitry Andric private:
2100b57cec5SDimitry Andric /// Keep track of information about hoisting candidates.
2110b57cec5SDimitry Andric struct CandidateInfo {
2120b57cec5SDimitry Andric MachineInstr *MI;
2130b57cec5SDimitry Andric unsigned Def;
2140b57cec5SDimitry Andric int FI;
2150b57cec5SDimitry Andric
CandidateInfo__anon32eb8ca40111::MachineLICMBase::CandidateInfo2160b57cec5SDimitry Andric CandidateInfo(MachineInstr *mi, unsigned def, int fi)
2170b57cec5SDimitry Andric : MI(mi), Def(def), FI(fi) {}
2180b57cec5SDimitry Andric };
2190b57cec5SDimitry Andric
220*c9157d92SDimitry Andric void HoistRegionPostRA(MachineLoop *CurLoop,
221*c9157d92SDimitry Andric MachineBasicBlock *CurPreheader);
2220b57cec5SDimitry Andric
223*c9157d92SDimitry Andric void HoistPostRA(MachineInstr *MI, unsigned Def, MachineLoop *CurLoop,
224*c9157d92SDimitry Andric MachineBasicBlock *CurPreheader);
2250b57cec5SDimitry Andric
2260b57cec5SDimitry Andric void ProcessMI(MachineInstr *MI, BitVector &PhysRegDefs,
2270b57cec5SDimitry Andric BitVector &PhysRegClobbers, SmallSet<int, 32> &StoredFIs,
228*c9157d92SDimitry Andric SmallVectorImpl<CandidateInfo> &Candidates,
229*c9157d92SDimitry Andric MachineLoop *CurLoop);
2300b57cec5SDimitry Andric
231*c9157d92SDimitry Andric void AddToLiveIns(MCRegister Reg, MachineLoop *CurLoop);
2320b57cec5SDimitry Andric
233*c9157d92SDimitry Andric bool IsLICMCandidate(MachineInstr &I, MachineLoop *CurLoop);
2340b57cec5SDimitry Andric
235*c9157d92SDimitry Andric bool IsLoopInvariantInst(MachineInstr &I, MachineLoop *CurLoop);
2360b57cec5SDimitry Andric
237*c9157d92SDimitry Andric bool HasLoopPHIUse(const MachineInstr *MI, MachineLoop *CurLoop);
2380b57cec5SDimitry Andric
239*c9157d92SDimitry Andric bool HasHighOperandLatency(MachineInstr &MI, unsigned DefIdx, Register Reg,
240*c9157d92SDimitry Andric MachineLoop *CurLoop) const;
2410b57cec5SDimitry Andric
2420b57cec5SDimitry Andric bool IsCheapInstruction(MachineInstr &MI) const;
2430b57cec5SDimitry Andric
2440b57cec5SDimitry Andric bool CanCauseHighRegPressure(const DenseMap<unsigned, int> &Cost,
2450b57cec5SDimitry Andric bool Cheap);
2460b57cec5SDimitry Andric
2470b57cec5SDimitry Andric void UpdateBackTraceRegPressure(const MachineInstr *MI);
2480b57cec5SDimitry Andric
249*c9157d92SDimitry Andric bool IsProfitableToHoist(MachineInstr &MI, MachineLoop *CurLoop);
2500b57cec5SDimitry Andric
251*c9157d92SDimitry Andric bool IsGuaranteedToExecute(MachineBasicBlock *BB, MachineLoop *CurLoop);
2520b57cec5SDimitry Andric
253fcaf7f86SDimitry Andric bool isTriviallyReMaterializable(const MachineInstr &MI) const;
254349cc55cSDimitry Andric
2550b57cec5SDimitry Andric void EnterScope(MachineBasicBlock *MBB);
2560b57cec5SDimitry Andric
2570b57cec5SDimitry Andric void ExitScope(MachineBasicBlock *MBB);
2580b57cec5SDimitry Andric
2590b57cec5SDimitry Andric void ExitScopeIfDone(
2600b57cec5SDimitry Andric MachineDomTreeNode *Node,
2610b57cec5SDimitry Andric DenseMap<MachineDomTreeNode *, unsigned> &OpenChildren,
26281ad6265SDimitry Andric const DenseMap<MachineDomTreeNode *, MachineDomTreeNode *> &ParentMap);
2630b57cec5SDimitry Andric
264*c9157d92SDimitry Andric void HoistOutOfLoop(MachineDomTreeNode *HeaderN, MachineLoop *CurLoop,
265*c9157d92SDimitry Andric MachineBasicBlock *CurPreheader);
2660b57cec5SDimitry Andric
2670b57cec5SDimitry Andric void InitRegPressure(MachineBasicBlock *BB);
2680b57cec5SDimitry Andric
2690b57cec5SDimitry Andric DenseMap<unsigned, int> calcRegisterCost(const MachineInstr *MI,
2700b57cec5SDimitry Andric bool ConsiderSeen,
2710b57cec5SDimitry Andric bool ConsiderUnseenAsDef);
2720b57cec5SDimitry Andric
2730b57cec5SDimitry Andric void UpdateRegPressure(const MachineInstr *MI,
2740b57cec5SDimitry Andric bool ConsiderUnseenAsDef = false);
2750b57cec5SDimitry Andric
276*c9157d92SDimitry Andric MachineInstr *ExtractHoistableLoad(MachineInstr *MI, MachineLoop *CurLoop);
2770b57cec5SDimitry Andric
278e8d8bef9SDimitry Andric MachineInstr *LookForDuplicate(const MachineInstr *MI,
279e8d8bef9SDimitry Andric std::vector<MachineInstr *> &PrevMIs);
2800b57cec5SDimitry Andric
281e8d8bef9SDimitry Andric bool
282e8d8bef9SDimitry Andric EliminateCSE(MachineInstr *MI,
283e8d8bef9SDimitry Andric DenseMap<unsigned, std::vector<MachineInstr *>>::iterator &CI);
2840b57cec5SDimitry Andric
2850b57cec5SDimitry Andric bool MayCSE(MachineInstr *MI);
2860b57cec5SDimitry Andric
287*c9157d92SDimitry Andric unsigned Hoist(MachineInstr *MI, MachineBasicBlock *Preheader,
288*c9157d92SDimitry Andric MachineLoop *CurLoop);
2890b57cec5SDimitry Andric
2900b57cec5SDimitry Andric void InitCSEMap(MachineBasicBlock *BB);
2910b57cec5SDimitry Andric
292*c9157d92SDimitry Andric void InitializeLoadsHoistableLoops();
293*c9157d92SDimitry Andric
294480093f4SDimitry Andric bool isTgtHotterThanSrc(MachineBasicBlock *SrcBlock,
295480093f4SDimitry Andric MachineBasicBlock *TgtBlock);
296*c9157d92SDimitry Andric MachineBasicBlock *getCurPreheader(MachineLoop *CurLoop,
297*c9157d92SDimitry Andric MachineBasicBlock *CurPreheader);
2980b57cec5SDimitry Andric };
2990b57cec5SDimitry Andric
3000b57cec5SDimitry Andric class MachineLICM : public MachineLICMBase {
3010b57cec5SDimitry Andric public:
3020b57cec5SDimitry Andric static char ID;
MachineLICM()3030b57cec5SDimitry Andric MachineLICM() : MachineLICMBase(ID, false) {
3040b57cec5SDimitry Andric initializeMachineLICMPass(*PassRegistry::getPassRegistry());
3050b57cec5SDimitry Andric }
3060b57cec5SDimitry Andric };
3070b57cec5SDimitry Andric
3080b57cec5SDimitry Andric class EarlyMachineLICM : public MachineLICMBase {
3090b57cec5SDimitry Andric public:
3100b57cec5SDimitry Andric static char ID;
EarlyMachineLICM()3110b57cec5SDimitry Andric EarlyMachineLICM() : MachineLICMBase(ID, true) {
3120b57cec5SDimitry Andric initializeEarlyMachineLICMPass(*PassRegistry::getPassRegistry());
3130b57cec5SDimitry Andric }
3140b57cec5SDimitry Andric };
3150b57cec5SDimitry Andric
3160b57cec5SDimitry Andric } // end anonymous namespace
3170b57cec5SDimitry Andric
3180b57cec5SDimitry Andric char MachineLICM::ID;
3190b57cec5SDimitry Andric char EarlyMachineLICM::ID;
3200b57cec5SDimitry Andric
3210b57cec5SDimitry Andric char &llvm::MachineLICMID = MachineLICM::ID;
3220b57cec5SDimitry Andric char &llvm::EarlyMachineLICMID = EarlyMachineLICM::ID;
3230b57cec5SDimitry Andric
3240b57cec5SDimitry Andric INITIALIZE_PASS_BEGIN(MachineLICM, DEBUG_TYPE,
3250b57cec5SDimitry Andric "Machine Loop Invariant Code Motion", false, false)
INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)3260b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
327480093f4SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineBlockFrequencyInfo)
3280b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
3290b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
3300b57cec5SDimitry Andric INITIALIZE_PASS_END(MachineLICM, DEBUG_TYPE,
3310b57cec5SDimitry Andric "Machine Loop Invariant Code Motion", false, false)
3320b57cec5SDimitry Andric
3330b57cec5SDimitry Andric INITIALIZE_PASS_BEGIN(EarlyMachineLICM, "early-machinelicm",
3340b57cec5SDimitry Andric "Early Machine Loop Invariant Code Motion", false, false)
3350b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
336480093f4SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineBlockFrequencyInfo)
3370b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
3380b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
3390b57cec5SDimitry Andric INITIALIZE_PASS_END(EarlyMachineLICM, "early-machinelicm",
3400b57cec5SDimitry Andric "Early Machine Loop Invariant Code Motion", false, false)
3410b57cec5SDimitry Andric
3420b57cec5SDimitry Andric bool MachineLICMBase::runOnMachineFunction(MachineFunction &MF) {
3430b57cec5SDimitry Andric if (skipFunction(MF.getFunction()))
3440b57cec5SDimitry Andric return false;
3450b57cec5SDimitry Andric
3460b57cec5SDimitry Andric Changed = FirstInLoop = false;
3470b57cec5SDimitry Andric const TargetSubtargetInfo &ST = MF.getSubtarget();
3480b57cec5SDimitry Andric TII = ST.getInstrInfo();
3490b57cec5SDimitry Andric TLI = ST.getTargetLowering();
3500b57cec5SDimitry Andric TRI = ST.getRegisterInfo();
3510b57cec5SDimitry Andric MFI = &MF.getFrameInfo();
3520b57cec5SDimitry Andric MRI = &MF.getRegInfo();
3530b57cec5SDimitry Andric SchedModel.init(&ST);
3540b57cec5SDimitry Andric
3550b57cec5SDimitry Andric PreRegAlloc = MRI->isSSA();
356480093f4SDimitry Andric HasProfileData = MF.getFunction().hasProfileData();
3570b57cec5SDimitry Andric
3580b57cec5SDimitry Andric if (PreRegAlloc)
3590b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "******** Pre-regalloc Machine LICM: ");
3600b57cec5SDimitry Andric else
3610b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "******** Post-regalloc Machine LICM: ");
3620b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << MF.getName() << " ********\n");
3630b57cec5SDimitry Andric
3640b57cec5SDimitry Andric if (PreRegAlloc) {
3650b57cec5SDimitry Andric // Estimate register pressure during pre-regalloc pass.
3660b57cec5SDimitry Andric unsigned NumRPS = TRI->getNumRegPressureSets();
3670b57cec5SDimitry Andric RegPressure.resize(NumRPS);
3680b57cec5SDimitry Andric std::fill(RegPressure.begin(), RegPressure.end(), 0);
3690b57cec5SDimitry Andric RegLimit.resize(NumRPS);
3700b57cec5SDimitry Andric for (unsigned i = 0, e = NumRPS; i != e; ++i)
3710b57cec5SDimitry Andric RegLimit[i] = TRI->getRegPressureSetLimit(MF, i);
3720b57cec5SDimitry Andric }
3730b57cec5SDimitry Andric
3740b57cec5SDimitry Andric // Get our Loop information...
375480093f4SDimitry Andric if (DisableHoistingToHotterBlocks != UseBFI::None)
376480093f4SDimitry Andric MBFI = &getAnalysis<MachineBlockFrequencyInfo>();
3770b57cec5SDimitry Andric MLI = &getAnalysis<MachineLoopInfo>();
3780b57cec5SDimitry Andric DT = &getAnalysis<MachineDominatorTree>();
3790b57cec5SDimitry Andric AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
3800b57cec5SDimitry Andric
381*c9157d92SDimitry Andric if (HoistConstLoads)
382*c9157d92SDimitry Andric InitializeLoadsHoistableLoops();
383*c9157d92SDimitry Andric
3840b57cec5SDimitry Andric SmallVector<MachineLoop *, 8> Worklist(MLI->begin(), MLI->end());
3850b57cec5SDimitry Andric while (!Worklist.empty()) {
386*c9157d92SDimitry Andric MachineLoop *CurLoop = Worklist.pop_back_val();
387*c9157d92SDimitry Andric MachineBasicBlock *CurPreheader = nullptr;
3880b57cec5SDimitry Andric
3890b57cec5SDimitry Andric if (!PreRegAlloc)
390*c9157d92SDimitry Andric HoistRegionPostRA(CurLoop, CurPreheader);
3910b57cec5SDimitry Andric else {
3920b57cec5SDimitry Andric // CSEMap is initialized for loop header when the first instruction is
3930b57cec5SDimitry Andric // being hoisted.
3940b57cec5SDimitry Andric MachineDomTreeNode *N = DT->getNode(CurLoop->getHeader());
3950b57cec5SDimitry Andric FirstInLoop = true;
396*c9157d92SDimitry Andric HoistOutOfLoop(N, CurLoop, CurPreheader);
3970b57cec5SDimitry Andric CSEMap.clear();
3980b57cec5SDimitry Andric }
3990b57cec5SDimitry Andric }
4000b57cec5SDimitry Andric
4010b57cec5SDimitry Andric return Changed;
4020b57cec5SDimitry Andric }
4030b57cec5SDimitry Andric
4040b57cec5SDimitry Andric /// Return true if instruction stores to the specified frame.
InstructionStoresToFI(const MachineInstr * MI,int FI)4050b57cec5SDimitry Andric static bool InstructionStoresToFI(const MachineInstr *MI, int FI) {
4060b57cec5SDimitry Andric // Check mayStore before memory operands so that e.g. DBG_VALUEs will return
4070b57cec5SDimitry Andric // true since they have no memory operands.
4080b57cec5SDimitry Andric if (!MI->mayStore())
4090b57cec5SDimitry Andric return false;
4100b57cec5SDimitry Andric // If we lost memory operands, conservatively assume that the instruction
4110b57cec5SDimitry Andric // writes to all slots.
4120b57cec5SDimitry Andric if (MI->memoperands_empty())
4130b57cec5SDimitry Andric return true;
4140b57cec5SDimitry Andric for (const MachineMemOperand *MemOp : MI->memoperands()) {
4150b57cec5SDimitry Andric if (!MemOp->isStore() || !MemOp->getPseudoValue())
4160b57cec5SDimitry Andric continue;
4170b57cec5SDimitry Andric if (const FixedStackPseudoSourceValue *Value =
4180b57cec5SDimitry Andric dyn_cast<FixedStackPseudoSourceValue>(MemOp->getPseudoValue())) {
4190b57cec5SDimitry Andric if (Value->getFrameIndex() == FI)
4200b57cec5SDimitry Andric return true;
4210b57cec5SDimitry Andric }
4220b57cec5SDimitry Andric }
4230b57cec5SDimitry Andric return false;
4240b57cec5SDimitry Andric }
4250b57cec5SDimitry Andric
4260b57cec5SDimitry Andric /// Examine the instruction for potentai LICM candidate. Also
4270b57cec5SDimitry Andric /// gather register def and frame object update information.
ProcessMI(MachineInstr * MI,BitVector & PhysRegDefs,BitVector & PhysRegClobbers,SmallSet<int,32> & StoredFIs,SmallVectorImpl<CandidateInfo> & Candidates,MachineLoop * CurLoop)428*c9157d92SDimitry Andric void MachineLICMBase::ProcessMI(MachineInstr *MI, BitVector &PhysRegDefs,
4290b57cec5SDimitry Andric BitVector &PhysRegClobbers,
4300b57cec5SDimitry Andric SmallSet<int, 32> &StoredFIs,
431*c9157d92SDimitry Andric SmallVectorImpl<CandidateInfo> &Candidates,
432*c9157d92SDimitry Andric MachineLoop *CurLoop) {
4330b57cec5SDimitry Andric bool RuledOut = false;
4340b57cec5SDimitry Andric bool HasNonInvariantUse = false;
4350b57cec5SDimitry Andric unsigned Def = 0;
4360b57cec5SDimitry Andric for (const MachineOperand &MO : MI->operands()) {
4370b57cec5SDimitry Andric if (MO.isFI()) {
4380b57cec5SDimitry Andric // Remember if the instruction stores to the frame index.
4390b57cec5SDimitry Andric int FI = MO.getIndex();
4400b57cec5SDimitry Andric if (!StoredFIs.count(FI) &&
4410b57cec5SDimitry Andric MFI->isSpillSlotObjectIndex(FI) &&
4420b57cec5SDimitry Andric InstructionStoresToFI(MI, FI))
4430b57cec5SDimitry Andric StoredFIs.insert(FI);
4440b57cec5SDimitry Andric HasNonInvariantUse = true;
4450b57cec5SDimitry Andric continue;
4460b57cec5SDimitry Andric }
4470b57cec5SDimitry Andric
4480b57cec5SDimitry Andric // We can't hoist an instruction defining a physreg that is clobbered in
4490b57cec5SDimitry Andric // the loop.
4500b57cec5SDimitry Andric if (MO.isRegMask()) {
4510b57cec5SDimitry Andric PhysRegClobbers.setBitsNotInMask(MO.getRegMask());
4520b57cec5SDimitry Andric continue;
4530b57cec5SDimitry Andric }
4540b57cec5SDimitry Andric
4550b57cec5SDimitry Andric if (!MO.isReg())
4560b57cec5SDimitry Andric continue;
4578bcb0991SDimitry Andric Register Reg = MO.getReg();
4580b57cec5SDimitry Andric if (!Reg)
4590b57cec5SDimitry Andric continue;
460bdd1243dSDimitry Andric assert(Reg.isPhysical() && "Not expecting virtual register!");
4610b57cec5SDimitry Andric
4620b57cec5SDimitry Andric if (!MO.isDef()) {
4630b57cec5SDimitry Andric if (Reg && (PhysRegDefs.test(Reg) || PhysRegClobbers.test(Reg)))
4640b57cec5SDimitry Andric // If it's using a non-loop-invariant register, then it's obviously not
4650b57cec5SDimitry Andric // safe to hoist.
4660b57cec5SDimitry Andric HasNonInvariantUse = true;
4670b57cec5SDimitry Andric continue;
4680b57cec5SDimitry Andric }
4690b57cec5SDimitry Andric
4700b57cec5SDimitry Andric if (MO.isImplicit()) {
4710b57cec5SDimitry Andric for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
4720b57cec5SDimitry Andric PhysRegClobbers.set(*AI);
4730b57cec5SDimitry Andric if (!MO.isDead())
4740b57cec5SDimitry Andric // Non-dead implicit def? This cannot be hoisted.
4750b57cec5SDimitry Andric RuledOut = true;
4760b57cec5SDimitry Andric // No need to check if a dead implicit def is also defined by
4770b57cec5SDimitry Andric // another instruction.
4780b57cec5SDimitry Andric continue;
4790b57cec5SDimitry Andric }
4800b57cec5SDimitry Andric
4810b57cec5SDimitry Andric // FIXME: For now, avoid instructions with multiple defs, unless
4820b57cec5SDimitry Andric // it's a dead implicit def.
4830b57cec5SDimitry Andric if (Def)
4840b57cec5SDimitry Andric RuledOut = true;
4850b57cec5SDimitry Andric else
4860b57cec5SDimitry Andric Def = Reg;
4870b57cec5SDimitry Andric
4880b57cec5SDimitry Andric // If we have already seen another instruction that defines the same
4890b57cec5SDimitry Andric // register, then this is not safe. Two defs is indicated by setting a
4900b57cec5SDimitry Andric // PhysRegClobbers bit.
4910b57cec5SDimitry Andric for (MCRegAliasIterator AS(Reg, TRI, true); AS.isValid(); ++AS) {
4920b57cec5SDimitry Andric if (PhysRegDefs.test(*AS))
4930b57cec5SDimitry Andric PhysRegClobbers.set(*AS);
4940b57cec5SDimitry Andric }
4950b57cec5SDimitry Andric // Need a second loop because MCRegAliasIterator can visit the same
4960b57cec5SDimitry Andric // register twice.
4970b57cec5SDimitry Andric for (MCRegAliasIterator AS(Reg, TRI, true); AS.isValid(); ++AS)
4980b57cec5SDimitry Andric PhysRegDefs.set(*AS);
4990b57cec5SDimitry Andric
5000b57cec5SDimitry Andric if (PhysRegClobbers.test(Reg))
5010b57cec5SDimitry Andric // MI defined register is seen defined by another instruction in
5020b57cec5SDimitry Andric // the loop, it cannot be a LICM candidate.
5030b57cec5SDimitry Andric RuledOut = true;
5040b57cec5SDimitry Andric }
5050b57cec5SDimitry Andric
5060b57cec5SDimitry Andric // Only consider reloads for now and remats which do not have register
5070b57cec5SDimitry Andric // operands. FIXME: Consider unfold load folding instructions.
5080b57cec5SDimitry Andric if (Def && !RuledOut) {
5090b57cec5SDimitry Andric int FI = std::numeric_limits<int>::min();
510*c9157d92SDimitry Andric if ((!HasNonInvariantUse && IsLICMCandidate(*MI, CurLoop)) ||
5110b57cec5SDimitry Andric (TII->isLoadFromStackSlot(*MI, FI) && MFI->isSpillSlotObjectIndex(FI)))
5120b57cec5SDimitry Andric Candidates.push_back(CandidateInfo(MI, Def, FI));
5130b57cec5SDimitry Andric }
5140b57cec5SDimitry Andric }
5150b57cec5SDimitry Andric
5160b57cec5SDimitry Andric /// Walk the specified region of the CFG and hoist loop invariants out to the
5170b57cec5SDimitry Andric /// preheader.
HoistRegionPostRA(MachineLoop * CurLoop,MachineBasicBlock * CurPreheader)518*c9157d92SDimitry Andric void MachineLICMBase::HoistRegionPostRA(MachineLoop *CurLoop,
519*c9157d92SDimitry Andric MachineBasicBlock *CurPreheader) {
520*c9157d92SDimitry Andric MachineBasicBlock *Preheader = getCurPreheader(CurLoop, CurPreheader);
5210b57cec5SDimitry Andric if (!Preheader)
5220b57cec5SDimitry Andric return;
5230b57cec5SDimitry Andric
5240b57cec5SDimitry Andric unsigned NumRegs = TRI->getNumRegs();
5250b57cec5SDimitry Andric BitVector PhysRegDefs(NumRegs); // Regs defined once in the loop.
5260b57cec5SDimitry Andric BitVector PhysRegClobbers(NumRegs); // Regs defined more than once.
5270b57cec5SDimitry Andric
5280b57cec5SDimitry Andric SmallVector<CandidateInfo, 32> Candidates;
5290b57cec5SDimitry Andric SmallSet<int, 32> StoredFIs;
5300b57cec5SDimitry Andric
5310b57cec5SDimitry Andric // Walk the entire region, count number of defs for each register, and
5320b57cec5SDimitry Andric // collect potential LICM candidates.
5330b57cec5SDimitry Andric for (MachineBasicBlock *BB : CurLoop->getBlocks()) {
5340b57cec5SDimitry Andric // If the header of the loop containing this basic block is a landing pad,
5350b57cec5SDimitry Andric // then don't try to hoist instructions out of this loop.
5360b57cec5SDimitry Andric const MachineLoop *ML = MLI->getLoopFor(BB);
5370b57cec5SDimitry Andric if (ML && ML->getHeader()->isEHPad()) continue;
5380b57cec5SDimitry Andric
5390b57cec5SDimitry Andric // Conservatively treat live-in's as an external def.
5400b57cec5SDimitry Andric // FIXME: That means a reload that're reused in successor block(s) will not
5410b57cec5SDimitry Andric // be LICM'ed.
5420b57cec5SDimitry Andric for (const auto &LI : BB->liveins()) {
5430b57cec5SDimitry Andric for (MCRegAliasIterator AI(LI.PhysReg, TRI, true); AI.isValid(); ++AI)
5440b57cec5SDimitry Andric PhysRegDefs.set(*AI);
5450b57cec5SDimitry Andric }
5460b57cec5SDimitry Andric
547271697daSDimitry Andric // Funclet entry blocks will clobber all registers
548271697daSDimitry Andric if (const uint32_t *Mask = BB->getBeginClobberMask(TRI))
549271697daSDimitry Andric PhysRegClobbers.setBitsNotInMask(Mask);
550271697daSDimitry Andric
5510b57cec5SDimitry Andric SpeculationState = SpeculateUnknown;
5520b57cec5SDimitry Andric for (MachineInstr &MI : *BB)
553*c9157d92SDimitry Andric ProcessMI(&MI, PhysRegDefs, PhysRegClobbers, StoredFIs, Candidates,
554*c9157d92SDimitry Andric CurLoop);
5550b57cec5SDimitry Andric }
5560b57cec5SDimitry Andric
5570b57cec5SDimitry Andric // Gather the registers read / clobbered by the terminator.
5580b57cec5SDimitry Andric BitVector TermRegs(NumRegs);
5590b57cec5SDimitry Andric MachineBasicBlock::iterator TI = Preheader->getFirstTerminator();
5600b57cec5SDimitry Andric if (TI != Preheader->end()) {
5610b57cec5SDimitry Andric for (const MachineOperand &MO : TI->operands()) {
5620b57cec5SDimitry Andric if (!MO.isReg())
5630b57cec5SDimitry Andric continue;
5648bcb0991SDimitry Andric Register Reg = MO.getReg();
5650b57cec5SDimitry Andric if (!Reg)
5660b57cec5SDimitry Andric continue;
5670b57cec5SDimitry Andric for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
5680b57cec5SDimitry Andric TermRegs.set(*AI);
5690b57cec5SDimitry Andric }
5700b57cec5SDimitry Andric }
5710b57cec5SDimitry Andric
5720b57cec5SDimitry Andric // Now evaluate whether the potential candidates qualify.
5730b57cec5SDimitry Andric // 1. Check if the candidate defined register is defined by another
5740b57cec5SDimitry Andric // instruction in the loop.
5750b57cec5SDimitry Andric // 2. If the candidate is a load from stack slot (always true for now),
5760b57cec5SDimitry Andric // check if the slot is stored anywhere in the loop.
5770b57cec5SDimitry Andric // 3. Make sure candidate def should not clobber
5780b57cec5SDimitry Andric // registers read by the terminator. Similarly its def should not be
5790b57cec5SDimitry Andric // clobbered by the terminator.
5800b57cec5SDimitry Andric for (CandidateInfo &Candidate : Candidates) {
5810b57cec5SDimitry Andric if (Candidate.FI != std::numeric_limits<int>::min() &&
5820b57cec5SDimitry Andric StoredFIs.count(Candidate.FI))
5830b57cec5SDimitry Andric continue;
5840b57cec5SDimitry Andric
5850b57cec5SDimitry Andric unsigned Def = Candidate.Def;
5860b57cec5SDimitry Andric if (!PhysRegClobbers.test(Def) && !TermRegs.test(Def)) {
5870b57cec5SDimitry Andric bool Safe = true;
5880b57cec5SDimitry Andric MachineInstr *MI = Candidate.MI;
589fe013be4SDimitry Andric for (const MachineOperand &MO : MI->all_uses()) {
590fe013be4SDimitry Andric if (!MO.getReg())
5910b57cec5SDimitry Andric continue;
5928bcb0991SDimitry Andric Register Reg = MO.getReg();
5930b57cec5SDimitry Andric if (PhysRegDefs.test(Reg) ||
5940b57cec5SDimitry Andric PhysRegClobbers.test(Reg)) {
5950b57cec5SDimitry Andric // If it's using a non-loop-invariant register, then it's obviously
5960b57cec5SDimitry Andric // not safe to hoist.
5970b57cec5SDimitry Andric Safe = false;
5980b57cec5SDimitry Andric break;
5990b57cec5SDimitry Andric }
6000b57cec5SDimitry Andric }
6010b57cec5SDimitry Andric if (Safe)
602*c9157d92SDimitry Andric HoistPostRA(MI, Candidate.Def, CurLoop, CurPreheader);
6030b57cec5SDimitry Andric }
6040b57cec5SDimitry Andric }
6050b57cec5SDimitry Andric }
6060b57cec5SDimitry Andric
6070b57cec5SDimitry Andric /// Add register 'Reg' to the livein sets of BBs in the current loop, and make
6080b57cec5SDimitry Andric /// sure it is not killed by any instructions in the loop.
AddToLiveIns(MCRegister Reg,MachineLoop * CurLoop)609*c9157d92SDimitry Andric void MachineLICMBase::AddToLiveIns(MCRegister Reg, MachineLoop *CurLoop) {
6100b57cec5SDimitry Andric for (MachineBasicBlock *BB : CurLoop->getBlocks()) {
6110b57cec5SDimitry Andric if (!BB->isLiveIn(Reg))
6120b57cec5SDimitry Andric BB->addLiveIn(Reg);
6130b57cec5SDimitry Andric for (MachineInstr &MI : *BB) {
614fe013be4SDimitry Andric for (MachineOperand &MO : MI.all_uses()) {
615fe013be4SDimitry Andric if (!MO.getReg())
616fe013be4SDimitry Andric continue;
617*c9157d92SDimitry Andric if (TRI->regsOverlap(Reg, MO.getReg()))
6180b57cec5SDimitry Andric MO.setIsKill(false);
6190b57cec5SDimitry Andric }
6200b57cec5SDimitry Andric }
6210b57cec5SDimitry Andric }
6220b57cec5SDimitry Andric }
6230b57cec5SDimitry Andric
6240b57cec5SDimitry Andric /// When an instruction is found to only use loop invariant operands that is
6250b57cec5SDimitry Andric /// safe to hoist, this instruction is called to do the dirty work.
HoistPostRA(MachineInstr * MI,unsigned Def,MachineLoop * CurLoop,MachineBasicBlock * CurPreheader)626*c9157d92SDimitry Andric void MachineLICMBase::HoistPostRA(MachineInstr *MI, unsigned Def,
627*c9157d92SDimitry Andric MachineLoop *CurLoop,
628*c9157d92SDimitry Andric MachineBasicBlock *CurPreheader) {
629*c9157d92SDimitry Andric MachineBasicBlock *Preheader = getCurPreheader(CurLoop, CurPreheader);
6300b57cec5SDimitry Andric
6310b57cec5SDimitry Andric // Now move the instructions to the predecessor, inserting it before any
6320b57cec5SDimitry Andric // terminator instructions.
6330b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Hoisting to " << printMBBReference(*Preheader)
6340b57cec5SDimitry Andric << " from " << printMBBReference(*MI->getParent()) << ": "
6350b57cec5SDimitry Andric << *MI);
6360b57cec5SDimitry Andric
6370b57cec5SDimitry Andric // Splice the instruction to the preheader.
6380b57cec5SDimitry Andric MachineBasicBlock *MBB = MI->getParent();
6390b57cec5SDimitry Andric Preheader->splice(Preheader->getFirstTerminator(), MBB, MI);
6400b57cec5SDimitry Andric
6415ffd83dbSDimitry Andric // Since we are moving the instruction out of its basic block, we do not
6425ffd83dbSDimitry Andric // retain its debug location. Doing so would degrade the debugging
6435ffd83dbSDimitry Andric // experience and adversely affect the accuracy of profiling information.
6445ffd83dbSDimitry Andric assert(!MI->isDebugInstr() && "Should not hoist debug inst");
6455ffd83dbSDimitry Andric MI->setDebugLoc(DebugLoc());
6465ffd83dbSDimitry Andric
6470b57cec5SDimitry Andric // Add register to livein list to all the BBs in the current loop since a
6480b57cec5SDimitry Andric // loop invariant must be kept live throughout the whole loop. This is
6490b57cec5SDimitry Andric // important to ensure later passes do not scavenge the def register.
650*c9157d92SDimitry Andric AddToLiveIns(Def, CurLoop);
6510b57cec5SDimitry Andric
6520b57cec5SDimitry Andric ++NumPostRAHoisted;
6530b57cec5SDimitry Andric Changed = true;
6540b57cec5SDimitry Andric }
6550b57cec5SDimitry Andric
6560b57cec5SDimitry Andric /// Check if this mbb is guaranteed to execute. If not then a load from this mbb
6570b57cec5SDimitry Andric /// may not be safe to hoist.
IsGuaranteedToExecute(MachineBasicBlock * BB,MachineLoop * CurLoop)658*c9157d92SDimitry Andric bool MachineLICMBase::IsGuaranteedToExecute(MachineBasicBlock *BB,
659*c9157d92SDimitry Andric MachineLoop *CurLoop) {
6600b57cec5SDimitry Andric if (SpeculationState != SpeculateUnknown)
6610b57cec5SDimitry Andric return SpeculationState == SpeculateFalse;
6620b57cec5SDimitry Andric
6630b57cec5SDimitry Andric if (BB != CurLoop->getHeader()) {
6640b57cec5SDimitry Andric // Check loop exiting blocks.
6650b57cec5SDimitry Andric SmallVector<MachineBasicBlock*, 8> CurrentLoopExitingBlocks;
6660b57cec5SDimitry Andric CurLoop->getExitingBlocks(CurrentLoopExitingBlocks);
6670b57cec5SDimitry Andric for (MachineBasicBlock *CurrentLoopExitingBlock : CurrentLoopExitingBlocks)
6680b57cec5SDimitry Andric if (!DT->dominates(BB, CurrentLoopExitingBlock)) {
6690b57cec5SDimitry Andric SpeculationState = SpeculateTrue;
6700b57cec5SDimitry Andric return false;
6710b57cec5SDimitry Andric }
6720b57cec5SDimitry Andric }
6730b57cec5SDimitry Andric
6740b57cec5SDimitry Andric SpeculationState = SpeculateFalse;
6750b57cec5SDimitry Andric return true;
6760b57cec5SDimitry Andric }
6770b57cec5SDimitry Andric
678349cc55cSDimitry Andric /// Check if \p MI is trivially remateralizable and if it does not have any
679349cc55cSDimitry Andric /// virtual register uses. Even though rematerializable RA might not actually
680349cc55cSDimitry Andric /// rematerialize it in this scenario. In that case we do not want to hoist such
681349cc55cSDimitry Andric /// instruction out of the loop in a belief RA will sink it back if needed.
isTriviallyReMaterializable(const MachineInstr & MI) const682fcaf7f86SDimitry Andric bool MachineLICMBase::isTriviallyReMaterializable(
683fcaf7f86SDimitry Andric const MachineInstr &MI) const {
684fcaf7f86SDimitry Andric if (!TII->isTriviallyReMaterializable(MI))
685349cc55cSDimitry Andric return false;
686349cc55cSDimitry Andric
687fe013be4SDimitry Andric for (const MachineOperand &MO : MI.all_uses()) {
688fe013be4SDimitry Andric if (MO.getReg().isVirtual())
689349cc55cSDimitry Andric return false;
690349cc55cSDimitry Andric }
691349cc55cSDimitry Andric
692349cc55cSDimitry Andric return true;
693349cc55cSDimitry Andric }
694349cc55cSDimitry Andric
EnterScope(MachineBasicBlock * MBB)6950b57cec5SDimitry Andric void MachineLICMBase::EnterScope(MachineBasicBlock *MBB) {
6960b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Entering " << printMBBReference(*MBB) << '\n');
6970b57cec5SDimitry Andric
6980b57cec5SDimitry Andric // Remember livein register pressure.
6990b57cec5SDimitry Andric BackTrace.push_back(RegPressure);
7000b57cec5SDimitry Andric }
7010b57cec5SDimitry Andric
ExitScope(MachineBasicBlock * MBB)7020b57cec5SDimitry Andric void MachineLICMBase::ExitScope(MachineBasicBlock *MBB) {
7030b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Exiting " << printMBBReference(*MBB) << '\n');
7040b57cec5SDimitry Andric BackTrace.pop_back();
7050b57cec5SDimitry Andric }
7060b57cec5SDimitry Andric
7070b57cec5SDimitry Andric /// Destroy scope for the MBB that corresponds to the given dominator tree node
7080b57cec5SDimitry Andric /// if its a leaf or all of its children are done. Walk up the dominator tree to
7090b57cec5SDimitry Andric /// destroy ancestors which are now done.
ExitScopeIfDone(MachineDomTreeNode * Node,DenseMap<MachineDomTreeNode *,unsigned> & OpenChildren,const DenseMap<MachineDomTreeNode *,MachineDomTreeNode * > & ParentMap)7100b57cec5SDimitry Andric void MachineLICMBase::ExitScopeIfDone(MachineDomTreeNode *Node,
7110b57cec5SDimitry Andric DenseMap<MachineDomTreeNode*, unsigned> &OpenChildren,
71281ad6265SDimitry Andric const DenseMap<MachineDomTreeNode*, MachineDomTreeNode*> &ParentMap) {
7130b57cec5SDimitry Andric if (OpenChildren[Node])
7140b57cec5SDimitry Andric return;
7150b57cec5SDimitry Andric
71681ad6265SDimitry Andric for(;;) {
7170b57cec5SDimitry Andric ExitScope(Node->getBlock());
7180b57cec5SDimitry Andric // Now traverse upwards to pop ancestors whose offsprings are all done.
71981ad6265SDimitry Andric MachineDomTreeNode *Parent = ParentMap.lookup(Node);
72081ad6265SDimitry Andric if (!Parent || --OpenChildren[Parent] != 0)
7210b57cec5SDimitry Andric break;
7220b57cec5SDimitry Andric Node = Parent;
7230b57cec5SDimitry Andric }
7240b57cec5SDimitry Andric }
7250b57cec5SDimitry Andric
7260b57cec5SDimitry Andric /// Walk the specified loop in the CFG (defined by all blocks dominated by the
7270b57cec5SDimitry Andric /// specified header block, and that are in the current loop) in depth first
7280b57cec5SDimitry Andric /// order w.r.t the DominatorTree. This allows us to visit definitions before
7290b57cec5SDimitry Andric /// uses, allowing us to hoist a loop body in one pass without iteration.
HoistOutOfLoop(MachineDomTreeNode * HeaderN,MachineLoop * CurLoop,MachineBasicBlock * CurPreheader)730*c9157d92SDimitry Andric void MachineLICMBase::HoistOutOfLoop(MachineDomTreeNode *HeaderN,
731*c9157d92SDimitry Andric MachineLoop *CurLoop,
732*c9157d92SDimitry Andric MachineBasicBlock *CurPreheader) {
733*c9157d92SDimitry Andric MachineBasicBlock *Preheader = getCurPreheader(CurLoop, CurPreheader);
7340b57cec5SDimitry Andric if (!Preheader)
7350b57cec5SDimitry Andric return;
7360b57cec5SDimitry Andric
7370b57cec5SDimitry Andric SmallVector<MachineDomTreeNode*, 32> Scopes;
7380b57cec5SDimitry Andric SmallVector<MachineDomTreeNode*, 8> WorkList;
7390b57cec5SDimitry Andric DenseMap<MachineDomTreeNode*, MachineDomTreeNode*> ParentMap;
7400b57cec5SDimitry Andric DenseMap<MachineDomTreeNode*, unsigned> OpenChildren;
7410b57cec5SDimitry Andric
7420b57cec5SDimitry Andric // Perform a DFS walk to determine the order of visit.
7430b57cec5SDimitry Andric WorkList.push_back(HeaderN);
7440b57cec5SDimitry Andric while (!WorkList.empty()) {
7450b57cec5SDimitry Andric MachineDomTreeNode *Node = WorkList.pop_back_val();
7460b57cec5SDimitry Andric assert(Node && "Null dominator tree node?");
7470b57cec5SDimitry Andric MachineBasicBlock *BB = Node->getBlock();
7480b57cec5SDimitry Andric
7490b57cec5SDimitry Andric // If the header of the loop containing this basic block is a landing pad,
7500b57cec5SDimitry Andric // then don't try to hoist instructions out of this loop.
7510b57cec5SDimitry Andric const MachineLoop *ML = MLI->getLoopFor(BB);
7520b57cec5SDimitry Andric if (ML && ML->getHeader()->isEHPad())
7530b57cec5SDimitry Andric continue;
7540b57cec5SDimitry Andric
7550b57cec5SDimitry Andric // If this subregion is not in the top level loop at all, exit.
7560b57cec5SDimitry Andric if (!CurLoop->contains(BB))
7570b57cec5SDimitry Andric continue;
7580b57cec5SDimitry Andric
7590b57cec5SDimitry Andric Scopes.push_back(Node);
7605ffd83dbSDimitry Andric unsigned NumChildren = Node->getNumChildren();
7610b57cec5SDimitry Andric
7620b57cec5SDimitry Andric // Don't hoist things out of a large switch statement. This often causes
7630b57cec5SDimitry Andric // code to be hoisted that wasn't going to be executed, and increases
7640b57cec5SDimitry Andric // register pressure in a situation where it's likely to matter.
7650b57cec5SDimitry Andric if (BB->succ_size() >= 25)
7660b57cec5SDimitry Andric NumChildren = 0;
7670b57cec5SDimitry Andric
7680b57cec5SDimitry Andric OpenChildren[Node] = NumChildren;
7695ffd83dbSDimitry Andric if (NumChildren) {
7700b57cec5SDimitry Andric // Add children in reverse order as then the next popped worklist node is
7710b57cec5SDimitry Andric // the first child of this node. This means we ultimately traverse the
7720b57cec5SDimitry Andric // DOM tree in exactly the same order as if we'd recursed.
7735ffd83dbSDimitry Andric for (MachineDomTreeNode *Child : reverse(Node->children())) {
7740b57cec5SDimitry Andric ParentMap[Child] = Node;
7750b57cec5SDimitry Andric WorkList.push_back(Child);
7760b57cec5SDimitry Andric }
7770b57cec5SDimitry Andric }
7785ffd83dbSDimitry Andric }
7790b57cec5SDimitry Andric
7800b57cec5SDimitry Andric if (Scopes.size() == 0)
7810b57cec5SDimitry Andric return;
7820b57cec5SDimitry Andric
7830b57cec5SDimitry Andric // Compute registers which are livein into the loop headers.
7840b57cec5SDimitry Andric RegSeen.clear();
7850b57cec5SDimitry Andric BackTrace.clear();
7860b57cec5SDimitry Andric InitRegPressure(Preheader);
7870b57cec5SDimitry Andric
7880b57cec5SDimitry Andric // Now perform LICM.
7890b57cec5SDimitry Andric for (MachineDomTreeNode *Node : Scopes) {
7900b57cec5SDimitry Andric MachineBasicBlock *MBB = Node->getBlock();
7910b57cec5SDimitry Andric
7920b57cec5SDimitry Andric EnterScope(MBB);
7930b57cec5SDimitry Andric
7940b57cec5SDimitry Andric // Process the block
7950b57cec5SDimitry Andric SpeculationState = SpeculateUnknown;
796349cc55cSDimitry Andric for (MachineInstr &MI : llvm::make_early_inc_range(*MBB)) {
797*c9157d92SDimitry Andric unsigned HoistRes = HoistResult::NotHoisted;
798*c9157d92SDimitry Andric HoistRes = Hoist(&MI, Preheader, CurLoop);
799*c9157d92SDimitry Andric if (HoistRes & HoistResult::NotHoisted) {
800*c9157d92SDimitry Andric // We have failed to hoist MI to outermost loop's preheader. If MI is in
801*c9157d92SDimitry Andric // a subloop, try to hoist it to subloop's preheader.
802*c9157d92SDimitry Andric SmallVector<MachineLoop *> InnerLoopWorkList;
803*c9157d92SDimitry Andric for (MachineLoop *L = MLI->getLoopFor(MI.getParent()); L != CurLoop;
804*c9157d92SDimitry Andric L = L->getParentLoop())
805*c9157d92SDimitry Andric InnerLoopWorkList.push_back(L);
806*c9157d92SDimitry Andric
807*c9157d92SDimitry Andric while (!InnerLoopWorkList.empty()) {
808*c9157d92SDimitry Andric MachineLoop *InnerLoop = InnerLoopWorkList.pop_back_val();
809*c9157d92SDimitry Andric MachineBasicBlock *InnerLoopPreheader = InnerLoop->getLoopPreheader();
810*c9157d92SDimitry Andric if (InnerLoopPreheader) {
811*c9157d92SDimitry Andric HoistRes = Hoist(&MI, InnerLoopPreheader, InnerLoop);
812*c9157d92SDimitry Andric if (HoistRes & HoistResult::Hoisted)
813*c9157d92SDimitry Andric break;
814*c9157d92SDimitry Andric }
815*c9157d92SDimitry Andric }
816*c9157d92SDimitry Andric }
817*c9157d92SDimitry Andric
818*c9157d92SDimitry Andric if (HoistRes & HoistResult::ErasedMI)
819*c9157d92SDimitry Andric continue;
820*c9157d92SDimitry Andric
821349cc55cSDimitry Andric UpdateRegPressure(&MI);
8220b57cec5SDimitry Andric }
8230b57cec5SDimitry Andric
8240b57cec5SDimitry Andric // If it's a leaf node, it's done. Traverse upwards to pop ancestors.
8250b57cec5SDimitry Andric ExitScopeIfDone(Node, OpenChildren, ParentMap);
8260b57cec5SDimitry Andric }
8270b57cec5SDimitry Andric }
8280b57cec5SDimitry Andric
isOperandKill(const MachineOperand & MO,MachineRegisterInfo * MRI)8290b57cec5SDimitry Andric static bool isOperandKill(const MachineOperand &MO, MachineRegisterInfo *MRI) {
8300b57cec5SDimitry Andric return MO.isKill() || MRI->hasOneNonDBGUse(MO.getReg());
8310b57cec5SDimitry Andric }
8320b57cec5SDimitry Andric
8330b57cec5SDimitry Andric /// Find all virtual register references that are liveout of the preheader to
8340b57cec5SDimitry Andric /// initialize the starting "register pressure". Note this does not count live
8350b57cec5SDimitry Andric /// through (livein but not used) registers.
InitRegPressure(MachineBasicBlock * BB)8360b57cec5SDimitry Andric void MachineLICMBase::InitRegPressure(MachineBasicBlock *BB) {
8370b57cec5SDimitry Andric std::fill(RegPressure.begin(), RegPressure.end(), 0);
8380b57cec5SDimitry Andric
8390b57cec5SDimitry Andric // If the preheader has only a single predecessor and it ends with a
8400b57cec5SDimitry Andric // fallthrough or an unconditional branch, then scan its predecessor for live
8410b57cec5SDimitry Andric // defs as well. This happens whenever the preheader is created by splitting
8420b57cec5SDimitry Andric // the critical edge from the loop predecessor to the loop header.
8430b57cec5SDimitry Andric if (BB->pred_size() == 1) {
8440b57cec5SDimitry Andric MachineBasicBlock *TBB = nullptr, *FBB = nullptr;
8450b57cec5SDimitry Andric SmallVector<MachineOperand, 4> Cond;
8460b57cec5SDimitry Andric if (!TII->analyzeBranch(*BB, TBB, FBB, Cond, false) && Cond.empty())
8470b57cec5SDimitry Andric InitRegPressure(*BB->pred_begin());
8480b57cec5SDimitry Andric }
8490b57cec5SDimitry Andric
8500b57cec5SDimitry Andric for (const MachineInstr &MI : *BB)
8510b57cec5SDimitry Andric UpdateRegPressure(&MI, /*ConsiderUnseenAsDef=*/true);
8520b57cec5SDimitry Andric }
8530b57cec5SDimitry Andric
8540b57cec5SDimitry Andric /// Update estimate of register pressure after the specified instruction.
UpdateRegPressure(const MachineInstr * MI,bool ConsiderUnseenAsDef)8550b57cec5SDimitry Andric void MachineLICMBase::UpdateRegPressure(const MachineInstr *MI,
8560b57cec5SDimitry Andric bool ConsiderUnseenAsDef) {
8570b57cec5SDimitry Andric auto Cost = calcRegisterCost(MI, /*ConsiderSeen=*/true, ConsiderUnseenAsDef);
8580b57cec5SDimitry Andric for (const auto &RPIdAndCost : Cost) {
8590b57cec5SDimitry Andric unsigned Class = RPIdAndCost.first;
8600b57cec5SDimitry Andric if (static_cast<int>(RegPressure[Class]) < -RPIdAndCost.second)
8610b57cec5SDimitry Andric RegPressure[Class] = 0;
8620b57cec5SDimitry Andric else
8630b57cec5SDimitry Andric RegPressure[Class] += RPIdAndCost.second;
8640b57cec5SDimitry Andric }
8650b57cec5SDimitry Andric }
8660b57cec5SDimitry Andric
8670b57cec5SDimitry Andric /// Calculate the additional register pressure that the registers used in MI
8680b57cec5SDimitry Andric /// cause.
8690b57cec5SDimitry Andric ///
8700b57cec5SDimitry Andric /// If 'ConsiderSeen' is true, updates 'RegSeen' and uses the information to
8710b57cec5SDimitry Andric /// figure out which usages are live-ins.
8720b57cec5SDimitry Andric /// FIXME: Figure out a way to consider 'RegSeen' from all code paths.
8730b57cec5SDimitry Andric DenseMap<unsigned, int>
calcRegisterCost(const MachineInstr * MI,bool ConsiderSeen,bool ConsiderUnseenAsDef)8740b57cec5SDimitry Andric MachineLICMBase::calcRegisterCost(const MachineInstr *MI, bool ConsiderSeen,
8750b57cec5SDimitry Andric bool ConsiderUnseenAsDef) {
8760b57cec5SDimitry Andric DenseMap<unsigned, int> Cost;
8770b57cec5SDimitry Andric if (MI->isImplicitDef())
8780b57cec5SDimitry Andric return Cost;
8790b57cec5SDimitry Andric for (unsigned i = 0, e = MI->getDesc().getNumOperands(); i != e; ++i) {
8800b57cec5SDimitry Andric const MachineOperand &MO = MI->getOperand(i);
8810b57cec5SDimitry Andric if (!MO.isReg() || MO.isImplicit())
8820b57cec5SDimitry Andric continue;
8838bcb0991SDimitry Andric Register Reg = MO.getReg();
884bdd1243dSDimitry Andric if (!Reg.isVirtual())
8850b57cec5SDimitry Andric continue;
8860b57cec5SDimitry Andric
8870b57cec5SDimitry Andric // FIXME: It seems bad to use RegSeen only for some of these calculations.
8880b57cec5SDimitry Andric bool isNew = ConsiderSeen ? RegSeen.insert(Reg).second : false;
8890b57cec5SDimitry Andric const TargetRegisterClass *RC = MRI->getRegClass(Reg);
8900b57cec5SDimitry Andric
8910b57cec5SDimitry Andric RegClassWeight W = TRI->getRegClassWeight(RC);
8920b57cec5SDimitry Andric int RCCost = 0;
8930b57cec5SDimitry Andric if (MO.isDef())
8940b57cec5SDimitry Andric RCCost = W.RegWeight;
8950b57cec5SDimitry Andric else {
8960b57cec5SDimitry Andric bool isKill = isOperandKill(MO, MRI);
8970b57cec5SDimitry Andric if (isNew && !isKill && ConsiderUnseenAsDef)
8980b57cec5SDimitry Andric // Haven't seen this, it must be a livein.
8990b57cec5SDimitry Andric RCCost = W.RegWeight;
9000b57cec5SDimitry Andric else if (!isNew && isKill)
9010b57cec5SDimitry Andric RCCost = -W.RegWeight;
9020b57cec5SDimitry Andric }
9030b57cec5SDimitry Andric if (RCCost == 0)
9040b57cec5SDimitry Andric continue;
9050b57cec5SDimitry Andric const int *PS = TRI->getRegClassPressureSets(RC);
9060b57cec5SDimitry Andric for (; *PS != -1; ++PS) {
907fe013be4SDimitry Andric if (!Cost.contains(*PS))
9080b57cec5SDimitry Andric Cost[*PS] = RCCost;
9090b57cec5SDimitry Andric else
9100b57cec5SDimitry Andric Cost[*PS] += RCCost;
9110b57cec5SDimitry Andric }
9120b57cec5SDimitry Andric }
9130b57cec5SDimitry Andric return Cost;
9140b57cec5SDimitry Andric }
9150b57cec5SDimitry Andric
9160b57cec5SDimitry Andric /// Return true if this machine instruction loads from global offset table or
9170b57cec5SDimitry Andric /// constant pool.
mayLoadFromGOTOrConstantPool(MachineInstr & MI)9180b57cec5SDimitry Andric static bool mayLoadFromGOTOrConstantPool(MachineInstr &MI) {
9190b57cec5SDimitry Andric assert(MI.mayLoad() && "Expected MI that loads!");
9200b57cec5SDimitry Andric
9210b57cec5SDimitry Andric // If we lost memory operands, conservatively assume that the instruction
9220b57cec5SDimitry Andric // reads from everything..
9230b57cec5SDimitry Andric if (MI.memoperands_empty())
9240b57cec5SDimitry Andric return true;
9250b57cec5SDimitry Andric
9260b57cec5SDimitry Andric for (MachineMemOperand *MemOp : MI.memoperands())
9270b57cec5SDimitry Andric if (const PseudoSourceValue *PSV = MemOp->getPseudoValue())
9280b57cec5SDimitry Andric if (PSV->isGOT() || PSV->isConstantPool())
9290b57cec5SDimitry Andric return true;
9300b57cec5SDimitry Andric
9310b57cec5SDimitry Andric return false;
9320b57cec5SDimitry Andric }
9330b57cec5SDimitry Andric
9340b57cec5SDimitry Andric // This function iterates through all the operands of the input store MI and
9350b57cec5SDimitry Andric // checks that each register operand statisfies isCallerPreservedPhysReg.
9360b57cec5SDimitry Andric // This means, the value being stored and the address where it is being stored
9370b57cec5SDimitry Andric // is constant throughout the body of the function (not including prologue and
9380b57cec5SDimitry Andric // epilogue). When called with an MI that isn't a store, it returns false.
9390b57cec5SDimitry Andric // A future improvement can be to check if the store registers are constant
9400b57cec5SDimitry Andric // throughout the loop rather than throughout the funtion.
isInvariantStore(const MachineInstr & MI,const TargetRegisterInfo * TRI,const MachineRegisterInfo * MRI)9410b57cec5SDimitry Andric static bool isInvariantStore(const MachineInstr &MI,
9420b57cec5SDimitry Andric const TargetRegisterInfo *TRI,
9430b57cec5SDimitry Andric const MachineRegisterInfo *MRI) {
9440b57cec5SDimitry Andric
9450b57cec5SDimitry Andric bool FoundCallerPresReg = false;
9460b57cec5SDimitry Andric if (!MI.mayStore() || MI.hasUnmodeledSideEffects() ||
9470b57cec5SDimitry Andric (MI.getNumOperands() == 0))
9480b57cec5SDimitry Andric return false;
9490b57cec5SDimitry Andric
9500b57cec5SDimitry Andric // Check that all register operands are caller-preserved physical registers.
9510b57cec5SDimitry Andric for (const MachineOperand &MO : MI.operands()) {
9520b57cec5SDimitry Andric if (MO.isReg()) {
9538bcb0991SDimitry Andric Register Reg = MO.getReg();
9540b57cec5SDimitry Andric // If operand is a virtual register, check if it comes from a copy of a
9550b57cec5SDimitry Andric // physical register.
956bdd1243dSDimitry Andric if (Reg.isVirtual())
9570b57cec5SDimitry Andric Reg = TRI->lookThruCopyLike(MO.getReg(), MRI);
958bdd1243dSDimitry Andric if (Reg.isVirtual())
9590b57cec5SDimitry Andric return false;
960e8d8bef9SDimitry Andric if (!TRI->isCallerPreservedPhysReg(Reg.asMCReg(), *MI.getMF()))
9610b57cec5SDimitry Andric return false;
9620b57cec5SDimitry Andric else
9630b57cec5SDimitry Andric FoundCallerPresReg = true;
9640b57cec5SDimitry Andric } else if (!MO.isImm()) {
9650b57cec5SDimitry Andric return false;
9660b57cec5SDimitry Andric }
9670b57cec5SDimitry Andric }
9680b57cec5SDimitry Andric return FoundCallerPresReg;
9690b57cec5SDimitry Andric }
9700b57cec5SDimitry Andric
9710b57cec5SDimitry Andric // Return true if the input MI is a copy instruction that feeds an invariant
9720b57cec5SDimitry Andric // store instruction. This means that the src of the copy has to satisfy
9730b57cec5SDimitry Andric // isCallerPreservedPhysReg and atleast one of it's users should satisfy
9740b57cec5SDimitry Andric // isInvariantStore.
isCopyFeedingInvariantStore(const MachineInstr & MI,const MachineRegisterInfo * MRI,const TargetRegisterInfo * TRI)9750b57cec5SDimitry Andric static bool isCopyFeedingInvariantStore(const MachineInstr &MI,
9760b57cec5SDimitry Andric const MachineRegisterInfo *MRI,
9770b57cec5SDimitry Andric const TargetRegisterInfo *TRI) {
9780b57cec5SDimitry Andric
9790b57cec5SDimitry Andric // FIXME: If targets would like to look through instructions that aren't
9800b57cec5SDimitry Andric // pure copies, this can be updated to a query.
9810b57cec5SDimitry Andric if (!MI.isCopy())
9820b57cec5SDimitry Andric return false;
9830b57cec5SDimitry Andric
9840b57cec5SDimitry Andric const MachineFunction *MF = MI.getMF();
9850b57cec5SDimitry Andric // Check that we are copying a constant physical register.
9868bcb0991SDimitry Andric Register CopySrcReg = MI.getOperand(1).getReg();
987bdd1243dSDimitry Andric if (CopySrcReg.isVirtual())
9880b57cec5SDimitry Andric return false;
9890b57cec5SDimitry Andric
990e8d8bef9SDimitry Andric if (!TRI->isCallerPreservedPhysReg(CopySrcReg.asMCReg(), *MF))
9910b57cec5SDimitry Andric return false;
9920b57cec5SDimitry Andric
9938bcb0991SDimitry Andric Register CopyDstReg = MI.getOperand(0).getReg();
9940b57cec5SDimitry Andric // Check if any of the uses of the copy are invariant stores.
995bdd1243dSDimitry Andric assert(CopyDstReg.isVirtual() && "copy dst is not a virtual reg");
9960b57cec5SDimitry Andric
9970b57cec5SDimitry Andric for (MachineInstr &UseMI : MRI->use_instructions(CopyDstReg)) {
9980b57cec5SDimitry Andric if (UseMI.mayStore() && isInvariantStore(UseMI, TRI, MRI))
9990b57cec5SDimitry Andric return true;
10000b57cec5SDimitry Andric }
10010b57cec5SDimitry Andric return false;
10020b57cec5SDimitry Andric }
10030b57cec5SDimitry Andric
10040b57cec5SDimitry Andric /// Returns true if the instruction may be a suitable candidate for LICM.
10050b57cec5SDimitry Andric /// e.g. If the instruction is a call, then it's obviously not safe to hoist it.
IsLICMCandidate(MachineInstr & I,MachineLoop * CurLoop)1006*c9157d92SDimitry Andric bool MachineLICMBase::IsLICMCandidate(MachineInstr &I, MachineLoop *CurLoop) {
10070b57cec5SDimitry Andric // Check if it's safe to move the instruction.
1008*c9157d92SDimitry Andric bool DontMoveAcrossStore = !HoistConstLoads || !AllowedToHoistLoads[CurLoop];
10090b57cec5SDimitry Andric if ((!I.isSafeToMove(AA, DontMoveAcrossStore)) &&
10100b57cec5SDimitry Andric !(HoistConstStores && isInvariantStore(I, TRI, MRI))) {
1011e8d8bef9SDimitry Andric LLVM_DEBUG(dbgs() << "LICM: Instruction not safe to move.\n");
10120b57cec5SDimitry Andric return false;
10130b57cec5SDimitry Andric }
10140b57cec5SDimitry Andric
1015fe6060f1SDimitry Andric // If it is a load then check if it is guaranteed to execute by making sure
1016fe6060f1SDimitry Andric // that it dominates all exiting blocks. If it doesn't, then there is a path
1017fe6060f1SDimitry Andric // out of the loop which does not execute this load, so we can't hoist it.
1018fe6060f1SDimitry Andric // Loads from constant memory are safe to speculate, for example indexed load
1019fe6060f1SDimitry Andric // from a jump table.
10200b57cec5SDimitry Andric // Stores and side effects are already checked by isSafeToMove.
10210b57cec5SDimitry Andric if (I.mayLoad() && !mayLoadFromGOTOrConstantPool(I) &&
1022*c9157d92SDimitry Andric !IsGuaranteedToExecute(I.getParent(), CurLoop)) {
1023e8d8bef9SDimitry Andric LLVM_DEBUG(dbgs() << "LICM: Load not guaranteed to execute.\n");
1024e8d8bef9SDimitry Andric return false;
1025e8d8bef9SDimitry Andric }
1026e8d8bef9SDimitry Andric
1027e8d8bef9SDimitry Andric // Convergent attribute has been used on operations that involve inter-thread
1028e8d8bef9SDimitry Andric // communication which results are implicitly affected by the enclosing
1029e8d8bef9SDimitry Andric // control flows. It is not safe to hoist or sink such operations across
1030e8d8bef9SDimitry Andric // control flow.
1031e8d8bef9SDimitry Andric if (I.isConvergent())
10320b57cec5SDimitry Andric return false;
10330b57cec5SDimitry Andric
103481ad6265SDimitry Andric if (!TII->shouldHoist(I, CurLoop))
103581ad6265SDimitry Andric return false;
103681ad6265SDimitry Andric
10370b57cec5SDimitry Andric return true;
10380b57cec5SDimitry Andric }
10390b57cec5SDimitry Andric
10400b57cec5SDimitry Andric /// Returns true if the instruction is loop invariant.
IsLoopInvariantInst(MachineInstr & I,MachineLoop * CurLoop)1041*c9157d92SDimitry Andric bool MachineLICMBase::IsLoopInvariantInst(MachineInstr &I,
1042*c9157d92SDimitry Andric MachineLoop *CurLoop) {
1043*c9157d92SDimitry Andric if (!IsLICMCandidate(I, CurLoop)) {
1044e8d8bef9SDimitry Andric LLVM_DEBUG(dbgs() << "LICM: Instruction not a LICM candidate\n");
10450b57cec5SDimitry Andric return false;
10460b57cec5SDimitry Andric }
1047e8d8bef9SDimitry Andric return CurLoop->isLoopInvariant(I);
10480b57cec5SDimitry Andric }
10490b57cec5SDimitry Andric
10500b57cec5SDimitry Andric /// Return true if the specified instruction is used by a phi node and hoisting
10510b57cec5SDimitry Andric /// it could cause a copy to be inserted.
HasLoopPHIUse(const MachineInstr * MI,MachineLoop * CurLoop)1052*c9157d92SDimitry Andric bool MachineLICMBase::HasLoopPHIUse(const MachineInstr *MI,
1053*c9157d92SDimitry Andric MachineLoop *CurLoop) {
10540b57cec5SDimitry Andric SmallVector<const MachineInstr *, 8> Work(1, MI);
10550b57cec5SDimitry Andric do {
10560b57cec5SDimitry Andric MI = Work.pop_back_val();
1057fe013be4SDimitry Andric for (const MachineOperand &MO : MI->all_defs()) {
10588bcb0991SDimitry Andric Register Reg = MO.getReg();
1059bdd1243dSDimitry Andric if (!Reg.isVirtual())
10600b57cec5SDimitry Andric continue;
10610b57cec5SDimitry Andric for (MachineInstr &UseMI : MRI->use_instructions(Reg)) {
10620b57cec5SDimitry Andric // A PHI may cause a copy to be inserted.
10630b57cec5SDimitry Andric if (UseMI.isPHI()) {
10640b57cec5SDimitry Andric // A PHI inside the loop causes a copy because the live range of Reg is
10650b57cec5SDimitry Andric // extended across the PHI.
10660b57cec5SDimitry Andric if (CurLoop->contains(&UseMI))
10670b57cec5SDimitry Andric return true;
10680b57cec5SDimitry Andric // A PHI in an exit block can cause a copy to be inserted if the PHI
10690b57cec5SDimitry Andric // has multiple predecessors in the loop with different values.
10700b57cec5SDimitry Andric // For now, approximate by rejecting all exit blocks.
1071*c9157d92SDimitry Andric if (isExitBlock(CurLoop, UseMI.getParent()))
10720b57cec5SDimitry Andric return true;
10730b57cec5SDimitry Andric continue;
10740b57cec5SDimitry Andric }
10750b57cec5SDimitry Andric // Look past copies as well.
10760b57cec5SDimitry Andric if (UseMI.isCopy() && CurLoop->contains(&UseMI))
10770b57cec5SDimitry Andric Work.push_back(&UseMI);
10780b57cec5SDimitry Andric }
10790b57cec5SDimitry Andric }
10800b57cec5SDimitry Andric } while (!Work.empty());
10810b57cec5SDimitry Andric return false;
10820b57cec5SDimitry Andric }
10830b57cec5SDimitry Andric
10840b57cec5SDimitry Andric /// Compute operand latency between a def of 'Reg' and an use in the current
10850b57cec5SDimitry Andric /// loop, return true if the target considered it high.
HasHighOperandLatency(MachineInstr & MI,unsigned DefIdx,Register Reg,MachineLoop * CurLoop) const1086e8d8bef9SDimitry Andric bool MachineLICMBase::HasHighOperandLatency(MachineInstr &MI, unsigned DefIdx,
1087*c9157d92SDimitry Andric Register Reg,
1088*c9157d92SDimitry Andric MachineLoop *CurLoop) const {
10890b57cec5SDimitry Andric if (MRI->use_nodbg_empty(Reg))
10900b57cec5SDimitry Andric return false;
10910b57cec5SDimitry Andric
10920b57cec5SDimitry Andric for (MachineInstr &UseMI : MRI->use_nodbg_instructions(Reg)) {
10930b57cec5SDimitry Andric if (UseMI.isCopyLike())
10940b57cec5SDimitry Andric continue;
10950b57cec5SDimitry Andric if (!CurLoop->contains(UseMI.getParent()))
10960b57cec5SDimitry Andric continue;
10970b57cec5SDimitry Andric for (unsigned i = 0, e = UseMI.getNumOperands(); i != e; ++i) {
10980b57cec5SDimitry Andric const MachineOperand &MO = UseMI.getOperand(i);
10990b57cec5SDimitry Andric if (!MO.isReg() || !MO.isUse())
11000b57cec5SDimitry Andric continue;
11018bcb0991SDimitry Andric Register MOReg = MO.getReg();
11020b57cec5SDimitry Andric if (MOReg != Reg)
11030b57cec5SDimitry Andric continue;
11040b57cec5SDimitry Andric
11050b57cec5SDimitry Andric if (TII->hasHighOperandLatency(SchedModel, MRI, MI, DefIdx, UseMI, i))
11060b57cec5SDimitry Andric return true;
11070b57cec5SDimitry Andric }
11080b57cec5SDimitry Andric
11090b57cec5SDimitry Andric // Only look at the first in loop use.
11100b57cec5SDimitry Andric break;
11110b57cec5SDimitry Andric }
11120b57cec5SDimitry Andric
11130b57cec5SDimitry Andric return false;
11140b57cec5SDimitry Andric }
11150b57cec5SDimitry Andric
11160b57cec5SDimitry Andric /// Return true if the instruction is marked "cheap" or the operand latency
11170b57cec5SDimitry Andric /// between its def and a use is one or less.
IsCheapInstruction(MachineInstr & MI) const11180b57cec5SDimitry Andric bool MachineLICMBase::IsCheapInstruction(MachineInstr &MI) const {
11190b57cec5SDimitry Andric if (TII->isAsCheapAsAMove(MI) || MI.isCopyLike())
11200b57cec5SDimitry Andric return true;
11210b57cec5SDimitry Andric
11220b57cec5SDimitry Andric bool isCheap = false;
11230b57cec5SDimitry Andric unsigned NumDefs = MI.getDesc().getNumDefs();
11240b57cec5SDimitry Andric for (unsigned i = 0, e = MI.getNumOperands(); NumDefs && i != e; ++i) {
11250b57cec5SDimitry Andric MachineOperand &DefMO = MI.getOperand(i);
11260b57cec5SDimitry Andric if (!DefMO.isReg() || !DefMO.isDef())
11270b57cec5SDimitry Andric continue;
11280b57cec5SDimitry Andric --NumDefs;
11298bcb0991SDimitry Andric Register Reg = DefMO.getReg();
1130bdd1243dSDimitry Andric if (Reg.isPhysical())
11310b57cec5SDimitry Andric continue;
11320b57cec5SDimitry Andric
11330b57cec5SDimitry Andric if (!TII->hasLowDefLatency(SchedModel, MI, i))
11340b57cec5SDimitry Andric return false;
11350b57cec5SDimitry Andric isCheap = true;
11360b57cec5SDimitry Andric }
11370b57cec5SDimitry Andric
11380b57cec5SDimitry Andric return isCheap;
11390b57cec5SDimitry Andric }
11400b57cec5SDimitry Andric
11410b57cec5SDimitry Andric /// Visit BBs from header to current BB, check if hoisting an instruction of the
11420b57cec5SDimitry Andric /// given cost matrix can cause high register pressure.
11430b57cec5SDimitry Andric bool
CanCauseHighRegPressure(const DenseMap<unsigned,int> & Cost,bool CheapInstr)11440b57cec5SDimitry Andric MachineLICMBase::CanCauseHighRegPressure(const DenseMap<unsigned, int>& Cost,
11450b57cec5SDimitry Andric bool CheapInstr) {
11460b57cec5SDimitry Andric for (const auto &RPIdAndCost : Cost) {
11470b57cec5SDimitry Andric if (RPIdAndCost.second <= 0)
11480b57cec5SDimitry Andric continue;
11490b57cec5SDimitry Andric
11500b57cec5SDimitry Andric unsigned Class = RPIdAndCost.first;
11510b57cec5SDimitry Andric int Limit = RegLimit[Class];
11520b57cec5SDimitry Andric
11530b57cec5SDimitry Andric // Don't hoist cheap instructions if they would increase register pressure,
11540b57cec5SDimitry Andric // even if we're under the limit.
11550b57cec5SDimitry Andric if (CheapInstr && !HoistCheapInsts)
11560b57cec5SDimitry Andric return true;
11570b57cec5SDimitry Andric
11580b57cec5SDimitry Andric for (const auto &RP : BackTrace)
11590b57cec5SDimitry Andric if (static_cast<int>(RP[Class]) + RPIdAndCost.second >= Limit)
11600b57cec5SDimitry Andric return true;
11610b57cec5SDimitry Andric }
11620b57cec5SDimitry Andric
11630b57cec5SDimitry Andric return false;
11640b57cec5SDimitry Andric }
11650b57cec5SDimitry Andric
11660b57cec5SDimitry Andric /// Traverse the back trace from header to the current block and update their
11670b57cec5SDimitry Andric /// register pressures to reflect the effect of hoisting MI from the current
11680b57cec5SDimitry Andric /// block to the preheader.
UpdateBackTraceRegPressure(const MachineInstr * MI)11690b57cec5SDimitry Andric void MachineLICMBase::UpdateBackTraceRegPressure(const MachineInstr *MI) {
11700b57cec5SDimitry Andric // First compute the 'cost' of the instruction, i.e. its contribution
11710b57cec5SDimitry Andric // to register pressure.
11720b57cec5SDimitry Andric auto Cost = calcRegisterCost(MI, /*ConsiderSeen=*/false,
11730b57cec5SDimitry Andric /*ConsiderUnseenAsDef=*/false);
11740b57cec5SDimitry Andric
11750b57cec5SDimitry Andric // Update register pressure of blocks from loop header to current block.
11760b57cec5SDimitry Andric for (auto &RP : BackTrace)
11770b57cec5SDimitry Andric for (const auto &RPIdAndCost : Cost)
11780b57cec5SDimitry Andric RP[RPIdAndCost.first] += RPIdAndCost.second;
11790b57cec5SDimitry Andric }
11800b57cec5SDimitry Andric
11810b57cec5SDimitry Andric /// Return true if it is potentially profitable to hoist the given loop
11820b57cec5SDimitry Andric /// invariant.
IsProfitableToHoist(MachineInstr & MI,MachineLoop * CurLoop)1183*c9157d92SDimitry Andric bool MachineLICMBase::IsProfitableToHoist(MachineInstr &MI,
1184*c9157d92SDimitry Andric MachineLoop *CurLoop) {
11850b57cec5SDimitry Andric if (MI.isImplicitDef())
11860b57cec5SDimitry Andric return true;
11870b57cec5SDimitry Andric
11880b57cec5SDimitry Andric // Besides removing computation from the loop, hoisting an instruction has
11890b57cec5SDimitry Andric // these effects:
11900b57cec5SDimitry Andric //
11910b57cec5SDimitry Andric // - The value defined by the instruction becomes live across the entire
11920b57cec5SDimitry Andric // loop. This increases register pressure in the loop.
11930b57cec5SDimitry Andric //
11940b57cec5SDimitry Andric // - If the value is used by a PHI in the loop, a copy will be required for
11950b57cec5SDimitry Andric // lowering the PHI after extending the live range.
11960b57cec5SDimitry Andric //
11970b57cec5SDimitry Andric // - When hoisting the last use of a value in the loop, that value no longer
11980b57cec5SDimitry Andric // needs to be live in the loop. This lowers register pressure in the loop.
11990b57cec5SDimitry Andric
12000b57cec5SDimitry Andric if (HoistConstStores && isCopyFeedingInvariantStore(MI, MRI, TRI))
12010b57cec5SDimitry Andric return true;
12020b57cec5SDimitry Andric
12030b57cec5SDimitry Andric bool CheapInstr = IsCheapInstruction(MI);
1204*c9157d92SDimitry Andric bool CreatesCopy = HasLoopPHIUse(&MI, CurLoop);
12050b57cec5SDimitry Andric
12060b57cec5SDimitry Andric // Don't hoist a cheap instruction if it would create a copy in the loop.
12070b57cec5SDimitry Andric if (CheapInstr && CreatesCopy) {
12080b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Won't hoist cheap instr with loop PHI use: " << MI);
12090b57cec5SDimitry Andric return false;
12100b57cec5SDimitry Andric }
12110b57cec5SDimitry Andric
1212349cc55cSDimitry Andric // Rematerializable instructions should always be hoisted providing the
1213349cc55cSDimitry Andric // register allocator can just pull them down again when needed.
1214fcaf7f86SDimitry Andric if (isTriviallyReMaterializable(MI))
12150b57cec5SDimitry Andric return true;
12160b57cec5SDimitry Andric
12170b57cec5SDimitry Andric // FIXME: If there are long latency loop-invariant instructions inside the
12180b57cec5SDimitry Andric // loop at this point, why didn't the optimizer's LICM hoist them?
12190b57cec5SDimitry Andric for (unsigned i = 0, e = MI.getDesc().getNumOperands(); i != e; ++i) {
12200b57cec5SDimitry Andric const MachineOperand &MO = MI.getOperand(i);
12210b57cec5SDimitry Andric if (!MO.isReg() || MO.isImplicit())
12220b57cec5SDimitry Andric continue;
12238bcb0991SDimitry Andric Register Reg = MO.getReg();
1224bdd1243dSDimitry Andric if (!Reg.isVirtual())
12250b57cec5SDimitry Andric continue;
1226*c9157d92SDimitry Andric if (MO.isDef() && HasHighOperandLatency(MI, i, Reg, CurLoop)) {
12270b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Hoist High Latency: " << MI);
12280b57cec5SDimitry Andric ++NumHighLatency;
12290b57cec5SDimitry Andric return true;
12300b57cec5SDimitry Andric }
12310b57cec5SDimitry Andric }
12320b57cec5SDimitry Andric
12330b57cec5SDimitry Andric // Estimate register pressure to determine whether to LICM the instruction.
12340b57cec5SDimitry Andric // In low register pressure situation, we can be more aggressive about
12350b57cec5SDimitry Andric // hoisting. Also, favors hoisting long latency instructions even in
12360b57cec5SDimitry Andric // moderately high pressure situation.
12370b57cec5SDimitry Andric // Cheap instructions will only be hoisted if they don't increase register
12380b57cec5SDimitry Andric // pressure at all.
12390b57cec5SDimitry Andric auto Cost = calcRegisterCost(&MI, /*ConsiderSeen=*/false,
12400b57cec5SDimitry Andric /*ConsiderUnseenAsDef=*/false);
12410b57cec5SDimitry Andric
12420b57cec5SDimitry Andric // Visit BBs from header to current BB, if hoisting this doesn't cause
12430b57cec5SDimitry Andric // high register pressure, then it's safe to proceed.
12440b57cec5SDimitry Andric if (!CanCauseHighRegPressure(Cost, CheapInstr)) {
12450b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Hoist non-reg-pressure: " << MI);
12460b57cec5SDimitry Andric ++NumLowRP;
12470b57cec5SDimitry Andric return true;
12480b57cec5SDimitry Andric }
12490b57cec5SDimitry Andric
12500b57cec5SDimitry Andric // Don't risk increasing register pressure if it would create copies.
12510b57cec5SDimitry Andric if (CreatesCopy) {
12520b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Won't hoist instr with loop PHI use: " << MI);
12530b57cec5SDimitry Andric return false;
12540b57cec5SDimitry Andric }
12550b57cec5SDimitry Andric
12560b57cec5SDimitry Andric // Do not "speculate" in high register pressure situation. If an
12570b57cec5SDimitry Andric // instruction is not guaranteed to be executed in the loop, it's best to be
12580b57cec5SDimitry Andric // conservative.
12590b57cec5SDimitry Andric if (AvoidSpeculation &&
1260*c9157d92SDimitry Andric (!IsGuaranteedToExecute(MI.getParent(), CurLoop) && !MayCSE(&MI))) {
12610b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Won't speculate: " << MI);
12620b57cec5SDimitry Andric return false;
12630b57cec5SDimitry Andric }
12640b57cec5SDimitry Andric
1265*c9157d92SDimitry Andric // If we have a COPY with other uses in the loop, hoist to allow the users to
1266*c9157d92SDimitry Andric // also be hoisted.
1267*c9157d92SDimitry Andric if (MI.isCopy() && MI.getOperand(0).isReg() &&
1268*c9157d92SDimitry Andric MI.getOperand(0).getReg().isVirtual() && MI.getOperand(1).isReg() &&
1269*c9157d92SDimitry Andric MI.getOperand(1).getReg().isVirtual() &&
1270*c9157d92SDimitry Andric IsLoopInvariantInst(MI, CurLoop) &&
1271*c9157d92SDimitry Andric any_of(MRI->use_nodbg_instructions(MI.getOperand(0).getReg()),
1272*c9157d92SDimitry Andric [&CurLoop](MachineInstr &UseMI) {
1273*c9157d92SDimitry Andric return CurLoop->contains(&UseMI);
1274*c9157d92SDimitry Andric }))
1275*c9157d92SDimitry Andric return true;
1276*c9157d92SDimitry Andric
12770b57cec5SDimitry Andric // High register pressure situation, only hoist if the instruction is going
12780b57cec5SDimitry Andric // to be remat'ed.
1279fcaf7f86SDimitry Andric if (!isTriviallyReMaterializable(MI) &&
1280fcaf7f86SDimitry Andric !MI.isDereferenceableInvariantLoad()) {
12810b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Can't remat / high reg-pressure: " << MI);
12820b57cec5SDimitry Andric return false;
12830b57cec5SDimitry Andric }
12840b57cec5SDimitry Andric
12850b57cec5SDimitry Andric return true;
12860b57cec5SDimitry Andric }
12870b57cec5SDimitry Andric
12880b57cec5SDimitry Andric /// Unfold a load from the given machineinstr if the load itself could be
12890b57cec5SDimitry Andric /// hoisted. Return the unfolded and hoistable load, or null if the load
12900b57cec5SDimitry Andric /// couldn't be unfolded or if it wouldn't be hoistable.
ExtractHoistableLoad(MachineInstr * MI,MachineLoop * CurLoop)1291*c9157d92SDimitry Andric MachineInstr *MachineLICMBase::ExtractHoistableLoad(MachineInstr *MI,
1292*c9157d92SDimitry Andric MachineLoop *CurLoop) {
12930b57cec5SDimitry Andric // Don't unfold simple loads.
12940b57cec5SDimitry Andric if (MI->canFoldAsLoad())
12950b57cec5SDimitry Andric return nullptr;
12960b57cec5SDimitry Andric
12970b57cec5SDimitry Andric // If not, we may be able to unfold a load and hoist that.
12980b57cec5SDimitry Andric // First test whether the instruction is loading from an amenable
12990b57cec5SDimitry Andric // memory location.
1300fcaf7f86SDimitry Andric if (!MI->isDereferenceableInvariantLoad())
13010b57cec5SDimitry Andric return nullptr;
13020b57cec5SDimitry Andric
13030b57cec5SDimitry Andric // Next determine the register class for a temporary register.
13040b57cec5SDimitry Andric unsigned LoadRegIndex;
13050b57cec5SDimitry Andric unsigned NewOpc =
13060b57cec5SDimitry Andric TII->getOpcodeAfterMemoryUnfold(MI->getOpcode(),
13070b57cec5SDimitry Andric /*UnfoldLoad=*/true,
13080b57cec5SDimitry Andric /*UnfoldStore=*/false,
13090b57cec5SDimitry Andric &LoadRegIndex);
13100b57cec5SDimitry Andric if (NewOpc == 0) return nullptr;
13110b57cec5SDimitry Andric const MCInstrDesc &MID = TII->get(NewOpc);
13120b57cec5SDimitry Andric MachineFunction &MF = *MI->getMF();
13130b57cec5SDimitry Andric const TargetRegisterClass *RC = TII->getRegClass(MID, LoadRegIndex, TRI, MF);
13140b57cec5SDimitry Andric // Ok, we're unfolding. Create a temporary register and do the unfold.
13158bcb0991SDimitry Andric Register Reg = MRI->createVirtualRegister(RC);
13160b57cec5SDimitry Andric
13170b57cec5SDimitry Andric SmallVector<MachineInstr *, 2> NewMIs;
13180b57cec5SDimitry Andric bool Success = TII->unfoldMemoryOperand(MF, *MI, Reg,
13190b57cec5SDimitry Andric /*UnfoldLoad=*/true,
13200b57cec5SDimitry Andric /*UnfoldStore=*/false, NewMIs);
13210b57cec5SDimitry Andric (void)Success;
13220b57cec5SDimitry Andric assert(Success &&
13230b57cec5SDimitry Andric "unfoldMemoryOperand failed when getOpcodeAfterMemoryUnfold "
13240b57cec5SDimitry Andric "succeeded!");
13250b57cec5SDimitry Andric assert(NewMIs.size() == 2 &&
13260b57cec5SDimitry Andric "Unfolded a load into multiple instructions!");
13270b57cec5SDimitry Andric MachineBasicBlock *MBB = MI->getParent();
13280b57cec5SDimitry Andric MachineBasicBlock::iterator Pos = MI;
13290b57cec5SDimitry Andric MBB->insert(Pos, NewMIs[0]);
13300b57cec5SDimitry Andric MBB->insert(Pos, NewMIs[1]);
13310b57cec5SDimitry Andric // If unfolding produced a load that wasn't loop-invariant or profitable to
13320b57cec5SDimitry Andric // hoist, discard the new instructions and bail.
1333*c9157d92SDimitry Andric if (!IsLoopInvariantInst(*NewMIs[0], CurLoop) ||
1334*c9157d92SDimitry Andric !IsProfitableToHoist(*NewMIs[0], CurLoop)) {
13350b57cec5SDimitry Andric NewMIs[0]->eraseFromParent();
13360b57cec5SDimitry Andric NewMIs[1]->eraseFromParent();
13370b57cec5SDimitry Andric return nullptr;
13380b57cec5SDimitry Andric }
13390b57cec5SDimitry Andric
13400b57cec5SDimitry Andric // Update register pressure for the unfolded instruction.
13410b57cec5SDimitry Andric UpdateRegPressure(NewMIs[1]);
13420b57cec5SDimitry Andric
13430b57cec5SDimitry Andric // Otherwise we successfully unfolded a load that we can hoist.
13445ffd83dbSDimitry Andric
13455ffd83dbSDimitry Andric // Update the call site info.
13465ffd83dbSDimitry Andric if (MI->shouldUpdateCallSiteInfo())
13475ffd83dbSDimitry Andric MF.eraseCallSiteInfo(MI);
13485ffd83dbSDimitry Andric
13490b57cec5SDimitry Andric MI->eraseFromParent();
13500b57cec5SDimitry Andric return NewMIs[0];
13510b57cec5SDimitry Andric }
13520b57cec5SDimitry Andric
13530b57cec5SDimitry Andric /// Initialize the CSE map with instructions that are in the current loop
13540b57cec5SDimitry Andric /// preheader that may become duplicates of instructions that are hoisted
13550b57cec5SDimitry Andric /// out of the loop.
InitCSEMap(MachineBasicBlock * BB)13560b57cec5SDimitry Andric void MachineLICMBase::InitCSEMap(MachineBasicBlock *BB) {
13570b57cec5SDimitry Andric for (MachineInstr &MI : *BB)
1358*c9157d92SDimitry Andric CSEMap[BB][MI.getOpcode()].push_back(&MI);
1359*c9157d92SDimitry Andric }
1360*c9157d92SDimitry Andric
1361*c9157d92SDimitry Andric /// Initialize AllowedToHoistLoads with information about whether invariant
1362*c9157d92SDimitry Andric /// loads can be moved outside a given loop
InitializeLoadsHoistableLoops()1363*c9157d92SDimitry Andric void MachineLICMBase::InitializeLoadsHoistableLoops() {
1364*c9157d92SDimitry Andric SmallVector<MachineLoop *, 8> Worklist(MLI->begin(), MLI->end());
1365*c9157d92SDimitry Andric SmallVector<MachineLoop *, 8> LoopsInPreOrder;
1366*c9157d92SDimitry Andric
1367*c9157d92SDimitry Andric // Mark all loops as hoistable initially and prepare a list of loops in
1368*c9157d92SDimitry Andric // pre-order DFS.
1369*c9157d92SDimitry Andric while (!Worklist.empty()) {
1370*c9157d92SDimitry Andric auto *L = Worklist.pop_back_val();
1371*c9157d92SDimitry Andric AllowedToHoistLoads[L] = true;
1372*c9157d92SDimitry Andric LoopsInPreOrder.push_back(L);
1373*c9157d92SDimitry Andric Worklist.insert(Worklist.end(), L->getSubLoops().begin(),
1374*c9157d92SDimitry Andric L->getSubLoops().end());
1375*c9157d92SDimitry Andric }
1376*c9157d92SDimitry Andric
1377*c9157d92SDimitry Andric // Going from the innermost to outermost loops, check if a loop has
1378*c9157d92SDimitry Andric // instructions preventing invariant load hoisting. If such instruction is
1379*c9157d92SDimitry Andric // found, mark this loop and its parent as non-hoistable and continue
1380*c9157d92SDimitry Andric // investigating the next loop.
1381*c9157d92SDimitry Andric // Visiting in a reversed pre-ordered DFS manner
1382*c9157d92SDimitry Andric // allows us to not process all the instructions of the outer loop if the
1383*c9157d92SDimitry Andric // inner loop is proved to be non-load-hoistable.
1384*c9157d92SDimitry Andric for (auto *Loop : reverse(LoopsInPreOrder)) {
1385*c9157d92SDimitry Andric for (auto *MBB : Loop->blocks()) {
1386*c9157d92SDimitry Andric // If this loop has already been marked as non-hoistable, skip it.
1387*c9157d92SDimitry Andric if (!AllowedToHoistLoads[Loop])
1388*c9157d92SDimitry Andric continue;
1389*c9157d92SDimitry Andric for (auto &MI : *MBB) {
1390*c9157d92SDimitry Andric if (!MI.mayStore() && !MI.isCall() &&
1391*c9157d92SDimitry Andric !(MI.mayLoad() && MI.hasOrderedMemoryRef()))
1392*c9157d92SDimitry Andric continue;
1393*c9157d92SDimitry Andric for (MachineLoop *L = Loop; L != nullptr; L = L->getParentLoop())
1394*c9157d92SDimitry Andric AllowedToHoistLoads[L] = false;
1395*c9157d92SDimitry Andric break;
1396*c9157d92SDimitry Andric }
1397*c9157d92SDimitry Andric }
1398*c9157d92SDimitry Andric }
13990b57cec5SDimitry Andric }
14000b57cec5SDimitry Andric
14010b57cec5SDimitry Andric /// Find an instruction amount PrevMIs that is a duplicate of MI.
14020b57cec5SDimitry Andric /// Return this instruction if it's found.
1403e8d8bef9SDimitry Andric MachineInstr *
LookForDuplicate(const MachineInstr * MI,std::vector<MachineInstr * > & PrevMIs)14040b57cec5SDimitry Andric MachineLICMBase::LookForDuplicate(const MachineInstr *MI,
1405e8d8bef9SDimitry Andric std::vector<MachineInstr *> &PrevMIs) {
1406e8d8bef9SDimitry Andric for (MachineInstr *PrevMI : PrevMIs)
14070b57cec5SDimitry Andric if (TII->produceSameValue(*MI, *PrevMI, (PreRegAlloc ? MRI : nullptr)))
14080b57cec5SDimitry Andric return PrevMI;
14090b57cec5SDimitry Andric
14100b57cec5SDimitry Andric return nullptr;
14110b57cec5SDimitry Andric }
14120b57cec5SDimitry Andric
14130b57cec5SDimitry Andric /// Given a LICM'ed instruction, look for an instruction on the preheader that
14140b57cec5SDimitry Andric /// computes the same value. If it's found, do a RAU on with the definition of
14150b57cec5SDimitry Andric /// the existing instruction rather than hoisting the instruction to the
14160b57cec5SDimitry Andric /// preheader.
EliminateCSE(MachineInstr * MI,DenseMap<unsigned,std::vector<MachineInstr * >>::iterator & CI)1417e8d8bef9SDimitry Andric bool MachineLICMBase::EliminateCSE(
1418e8d8bef9SDimitry Andric MachineInstr *MI,
1419e8d8bef9SDimitry Andric DenseMap<unsigned, std::vector<MachineInstr *>>::iterator &CI) {
14200b57cec5SDimitry Andric // Do not CSE implicit_def so ProcessImplicitDefs can properly propagate
14210b57cec5SDimitry Andric // the undef property onto uses.
1422*c9157d92SDimitry Andric if (MI->isImplicitDef())
1423*c9157d92SDimitry Andric return false;
1424*c9157d92SDimitry Andric
1425*c9157d92SDimitry Andric // Do not CSE normal loads because between them could be store instructions
1426*c9157d92SDimitry Andric // that change the loaded value
1427*c9157d92SDimitry Andric if (MI->mayLoad() && !MI->isDereferenceableInvariantLoad())
14280b57cec5SDimitry Andric return false;
14290b57cec5SDimitry Andric
1430e8d8bef9SDimitry Andric if (MachineInstr *Dup = LookForDuplicate(MI, CI->second)) {
14310b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "CSEing " << *MI << " with " << *Dup);
14320b57cec5SDimitry Andric
14330b57cec5SDimitry Andric // Replace virtual registers defined by MI by their counterparts defined
14340b57cec5SDimitry Andric // by Dup.
14350b57cec5SDimitry Andric SmallVector<unsigned, 2> Defs;
14360b57cec5SDimitry Andric for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
14370b57cec5SDimitry Andric const MachineOperand &MO = MI->getOperand(i);
14380b57cec5SDimitry Andric
14390b57cec5SDimitry Andric // Physical registers may not differ here.
1440bdd1243dSDimitry Andric assert((!MO.isReg() || MO.getReg() == 0 || !MO.getReg().isPhysical() ||
14410b57cec5SDimitry Andric MO.getReg() == Dup->getOperand(i).getReg()) &&
14420b57cec5SDimitry Andric "Instructions with different phys regs are not identical!");
14430b57cec5SDimitry Andric
1444bdd1243dSDimitry Andric if (MO.isReg() && MO.isDef() && !MO.getReg().isPhysical())
14450b57cec5SDimitry Andric Defs.push_back(i);
14460b57cec5SDimitry Andric }
14470b57cec5SDimitry Andric
14480b57cec5SDimitry Andric SmallVector<const TargetRegisterClass*, 2> OrigRCs;
14490b57cec5SDimitry Andric for (unsigned i = 0, e = Defs.size(); i != e; ++i) {
14500b57cec5SDimitry Andric unsigned Idx = Defs[i];
14518bcb0991SDimitry Andric Register Reg = MI->getOperand(Idx).getReg();
14528bcb0991SDimitry Andric Register DupReg = Dup->getOperand(Idx).getReg();
14530b57cec5SDimitry Andric OrigRCs.push_back(MRI->getRegClass(DupReg));
14540b57cec5SDimitry Andric
14550b57cec5SDimitry Andric if (!MRI->constrainRegClass(DupReg, MRI->getRegClass(Reg))) {
14560b57cec5SDimitry Andric // Restore old RCs if more than one defs.
14570b57cec5SDimitry Andric for (unsigned j = 0; j != i; ++j)
14580b57cec5SDimitry Andric MRI->setRegClass(Dup->getOperand(Defs[j]).getReg(), OrigRCs[j]);
14590b57cec5SDimitry Andric return false;
14600b57cec5SDimitry Andric }
14610b57cec5SDimitry Andric }
14620b57cec5SDimitry Andric
14630b57cec5SDimitry Andric for (unsigned Idx : Defs) {
14648bcb0991SDimitry Andric Register Reg = MI->getOperand(Idx).getReg();
14658bcb0991SDimitry Andric Register DupReg = Dup->getOperand(Idx).getReg();
14660b57cec5SDimitry Andric MRI->replaceRegWith(Reg, DupReg);
14670b57cec5SDimitry Andric MRI->clearKillFlags(DupReg);
1468e8d8bef9SDimitry Andric // Clear Dup dead flag if any, we reuse it for Reg.
1469e8d8bef9SDimitry Andric if (!MRI->use_nodbg_empty(DupReg))
1470e8d8bef9SDimitry Andric Dup->getOperand(Idx).setIsDead(false);
14710b57cec5SDimitry Andric }
14720b57cec5SDimitry Andric
14730b57cec5SDimitry Andric MI->eraseFromParent();
14740b57cec5SDimitry Andric ++NumCSEed;
14750b57cec5SDimitry Andric return true;
14760b57cec5SDimitry Andric }
14770b57cec5SDimitry Andric return false;
14780b57cec5SDimitry Andric }
14790b57cec5SDimitry Andric
14800b57cec5SDimitry Andric /// Return true if the given instruction will be CSE'd if it's hoisted out of
14810b57cec5SDimitry Andric /// the loop.
MayCSE(MachineInstr * MI)14820b57cec5SDimitry Andric bool MachineLICMBase::MayCSE(MachineInstr *MI) {
1483*c9157d92SDimitry Andric if (MI->mayLoad() && !MI->isDereferenceableInvariantLoad())
14840b57cec5SDimitry Andric return false;
14850b57cec5SDimitry Andric
1486*c9157d92SDimitry Andric unsigned Opcode = MI->getOpcode();
1487*c9157d92SDimitry Andric for (auto &Map : CSEMap) {
1488*c9157d92SDimitry Andric // Check this CSEMap's preheader dominates MI's basic block.
1489*c9157d92SDimitry Andric if (DT->dominates(Map.first, MI->getParent())) {
1490*c9157d92SDimitry Andric DenseMap<unsigned, std::vector<MachineInstr *>>::iterator CI =
1491*c9157d92SDimitry Andric Map.second.find(Opcode);
1492*c9157d92SDimitry Andric // Do not CSE implicit_def so ProcessImplicitDefs can properly propagate
1493*c9157d92SDimitry Andric // the undef property onto uses.
1494*c9157d92SDimitry Andric if (CI == Map.second.end() || MI->isImplicitDef())
1495*c9157d92SDimitry Andric continue;
1496*c9157d92SDimitry Andric if (LookForDuplicate(MI, CI->second) != nullptr)
1497*c9157d92SDimitry Andric return true;
1498*c9157d92SDimitry Andric }
1499*c9157d92SDimitry Andric }
1500*c9157d92SDimitry Andric
1501*c9157d92SDimitry Andric return false;
15020b57cec5SDimitry Andric }
15030b57cec5SDimitry Andric
15040b57cec5SDimitry Andric /// When an instruction is found to use only loop invariant operands
15050b57cec5SDimitry Andric /// that are safe to hoist, this instruction is called to do the dirty work.
15060b57cec5SDimitry Andric /// It returns true if the instruction is hoisted.
Hoist(MachineInstr * MI,MachineBasicBlock * Preheader,MachineLoop * CurLoop)1507*c9157d92SDimitry Andric unsigned MachineLICMBase::Hoist(MachineInstr *MI, MachineBasicBlock *Preheader,
1508*c9157d92SDimitry Andric MachineLoop *CurLoop) {
1509480093f4SDimitry Andric MachineBasicBlock *SrcBlock = MI->getParent();
1510480093f4SDimitry Andric
1511480093f4SDimitry Andric // Disable the instruction hoisting due to block hotness
1512480093f4SDimitry Andric if ((DisableHoistingToHotterBlocks == UseBFI::All ||
1513480093f4SDimitry Andric (DisableHoistingToHotterBlocks == UseBFI::PGO && HasProfileData)) &&
1514480093f4SDimitry Andric isTgtHotterThanSrc(SrcBlock, Preheader)) {
1515480093f4SDimitry Andric ++NumNotHoistedDueToHotness;
1516*c9157d92SDimitry Andric return HoistResult::NotHoisted;
1517480093f4SDimitry Andric }
15180b57cec5SDimitry Andric // First check whether we should hoist this instruction.
1519*c9157d92SDimitry Andric bool HasExtractHoistableLoad = false;
1520*c9157d92SDimitry Andric if (!IsLoopInvariantInst(*MI, CurLoop) ||
1521*c9157d92SDimitry Andric !IsProfitableToHoist(*MI, CurLoop)) {
15220b57cec5SDimitry Andric // If not, try unfolding a hoistable load.
1523*c9157d92SDimitry Andric MI = ExtractHoistableLoad(MI, CurLoop);
1524*c9157d92SDimitry Andric if (!MI)
1525*c9157d92SDimitry Andric return HoistResult::NotHoisted;
1526*c9157d92SDimitry Andric HasExtractHoistableLoad = true;
15270b57cec5SDimitry Andric }
15280b57cec5SDimitry Andric
15290b57cec5SDimitry Andric // If we have hoisted an instruction that may store, it can only be a constant
15300b57cec5SDimitry Andric // store.
15310b57cec5SDimitry Andric if (MI->mayStore())
15320b57cec5SDimitry Andric NumStoreConst++;
15330b57cec5SDimitry Andric
15340b57cec5SDimitry Andric // Now move the instructions to the predecessor, inserting it before any
15350b57cec5SDimitry Andric // terminator instructions.
15360b57cec5SDimitry Andric LLVM_DEBUG({
15370b57cec5SDimitry Andric dbgs() << "Hoisting " << *MI;
15380b57cec5SDimitry Andric if (MI->getParent()->getBasicBlock())
15390b57cec5SDimitry Andric dbgs() << " from " << printMBBReference(*MI->getParent());
15400b57cec5SDimitry Andric if (Preheader->getBasicBlock())
15410b57cec5SDimitry Andric dbgs() << " to " << printMBBReference(*Preheader);
15420b57cec5SDimitry Andric dbgs() << "\n";
15430b57cec5SDimitry Andric });
15440b57cec5SDimitry Andric
15450b57cec5SDimitry Andric // If this is the first instruction being hoisted to the preheader,
15460b57cec5SDimitry Andric // initialize the CSE map with potential common expressions.
15470b57cec5SDimitry Andric if (FirstInLoop) {
15480b57cec5SDimitry Andric InitCSEMap(Preheader);
15490b57cec5SDimitry Andric FirstInLoop = false;
15500b57cec5SDimitry Andric }
15510b57cec5SDimitry Andric
15520b57cec5SDimitry Andric // Look for opportunity to CSE the hoisted instruction.
15530b57cec5SDimitry Andric unsigned Opcode = MI->getOpcode();
1554*c9157d92SDimitry Andric bool HasCSEDone = false;
1555*c9157d92SDimitry Andric for (auto &Map : CSEMap) {
1556*c9157d92SDimitry Andric // Check this CSEMap's preheader dominates MI's basic block.
1557*c9157d92SDimitry Andric if (DT->dominates(Map.first, MI->getParent())) {
1558e8d8bef9SDimitry Andric DenseMap<unsigned, std::vector<MachineInstr *>>::iterator CI =
1559*c9157d92SDimitry Andric Map.second.find(Opcode);
1560*c9157d92SDimitry Andric if (CI != Map.second.end()) {
1561*c9157d92SDimitry Andric if (EliminateCSE(MI, CI)) {
1562*c9157d92SDimitry Andric HasCSEDone = true;
1563*c9157d92SDimitry Andric break;
1564*c9157d92SDimitry Andric }
1565*c9157d92SDimitry Andric }
1566*c9157d92SDimitry Andric }
1567*c9157d92SDimitry Andric }
1568*c9157d92SDimitry Andric
1569*c9157d92SDimitry Andric if (!HasCSEDone) {
15700b57cec5SDimitry Andric // Otherwise, splice the instruction to the preheader.
15710b57cec5SDimitry Andric Preheader->splice(Preheader->getFirstTerminator(),MI->getParent(),MI);
15720b57cec5SDimitry Andric
15730b57cec5SDimitry Andric // Since we are moving the instruction out of its basic block, we do not
15740b57cec5SDimitry Andric // retain its debug location. Doing so would degrade the debugging
15750b57cec5SDimitry Andric // experience and adversely affect the accuracy of profiling information.
15765ffd83dbSDimitry Andric assert(!MI->isDebugInstr() && "Should not hoist debug inst");
15770b57cec5SDimitry Andric MI->setDebugLoc(DebugLoc());
15780b57cec5SDimitry Andric
15790b57cec5SDimitry Andric // Update register pressure for BBs from header to this block.
15800b57cec5SDimitry Andric UpdateBackTraceRegPressure(MI);
15810b57cec5SDimitry Andric
15820b57cec5SDimitry Andric // Clear the kill flags of any register this instruction defines,
15830b57cec5SDimitry Andric // since they may need to be live throughout the entire loop
15840b57cec5SDimitry Andric // rather than just live for part of it.
1585fe013be4SDimitry Andric for (MachineOperand &MO : MI->all_defs())
1586fe013be4SDimitry Andric if (!MO.isDead())
15870b57cec5SDimitry Andric MRI->clearKillFlags(MO.getReg());
15880b57cec5SDimitry Andric
1589*c9157d92SDimitry Andric CSEMap[Preheader][Opcode].push_back(MI);
15900b57cec5SDimitry Andric }
15910b57cec5SDimitry Andric
15920b57cec5SDimitry Andric ++NumHoisted;
15930b57cec5SDimitry Andric Changed = true;
15940b57cec5SDimitry Andric
1595*c9157d92SDimitry Andric if (HasCSEDone || HasExtractHoistableLoad)
1596*c9157d92SDimitry Andric return HoistResult::Hoisted | HoistResult::ErasedMI;
1597*c9157d92SDimitry Andric return HoistResult::Hoisted;
15980b57cec5SDimitry Andric }
15990b57cec5SDimitry Andric
16000b57cec5SDimitry Andric /// Get the preheader for the current loop, splitting a critical edge if needed.
1601*c9157d92SDimitry Andric MachineBasicBlock *
getCurPreheader(MachineLoop * CurLoop,MachineBasicBlock * CurPreheader)1602*c9157d92SDimitry Andric MachineLICMBase::getCurPreheader(MachineLoop *CurLoop,
1603*c9157d92SDimitry Andric MachineBasicBlock *CurPreheader) {
16040b57cec5SDimitry Andric // Determine the block to which to hoist instructions. If we can't find a
16050b57cec5SDimitry Andric // suitable loop predecessor, we can't do any hoisting.
16060b57cec5SDimitry Andric
16070b57cec5SDimitry Andric // If we've tried to get a preheader and failed, don't try again.
16080b57cec5SDimitry Andric if (CurPreheader == reinterpret_cast<MachineBasicBlock *>(-1))
16090b57cec5SDimitry Andric return nullptr;
16100b57cec5SDimitry Andric
16110b57cec5SDimitry Andric if (!CurPreheader) {
16120b57cec5SDimitry Andric CurPreheader = CurLoop->getLoopPreheader();
16130b57cec5SDimitry Andric if (!CurPreheader) {
16140b57cec5SDimitry Andric MachineBasicBlock *Pred = CurLoop->getLoopPredecessor();
16150b57cec5SDimitry Andric if (!Pred) {
16160b57cec5SDimitry Andric CurPreheader = reinterpret_cast<MachineBasicBlock *>(-1);
16170b57cec5SDimitry Andric return nullptr;
16180b57cec5SDimitry Andric }
16190b57cec5SDimitry Andric
16200b57cec5SDimitry Andric CurPreheader = Pred->SplitCriticalEdge(CurLoop->getHeader(), *this);
16210b57cec5SDimitry Andric if (!CurPreheader) {
16220b57cec5SDimitry Andric CurPreheader = reinterpret_cast<MachineBasicBlock *>(-1);
16230b57cec5SDimitry Andric return nullptr;
16240b57cec5SDimitry Andric }
16250b57cec5SDimitry Andric }
16260b57cec5SDimitry Andric }
16270b57cec5SDimitry Andric return CurPreheader;
16280b57cec5SDimitry Andric }
1629480093f4SDimitry Andric
1630480093f4SDimitry Andric /// Is the target basic block at least "BlockFrequencyRatioThreshold"
1631480093f4SDimitry Andric /// times hotter than the source basic block.
isTgtHotterThanSrc(MachineBasicBlock * SrcBlock,MachineBasicBlock * TgtBlock)1632480093f4SDimitry Andric bool MachineLICMBase::isTgtHotterThanSrc(MachineBasicBlock *SrcBlock,
1633480093f4SDimitry Andric MachineBasicBlock *TgtBlock) {
1634480093f4SDimitry Andric // Parse source and target basic block frequency from MBFI
1635480093f4SDimitry Andric uint64_t SrcBF = MBFI->getBlockFreq(SrcBlock).getFrequency();
1636480093f4SDimitry Andric uint64_t DstBF = MBFI->getBlockFreq(TgtBlock).getFrequency();
1637480093f4SDimitry Andric
1638480093f4SDimitry Andric // Disable the hoisting if source block frequency is zero
1639480093f4SDimitry Andric if (!SrcBF)
1640480093f4SDimitry Andric return true;
1641480093f4SDimitry Andric
1642480093f4SDimitry Andric double Ratio = (double)DstBF / SrcBF;
1643480093f4SDimitry Andric
1644480093f4SDimitry Andric // Compare the block frequency ratio with the threshold
1645480093f4SDimitry Andric return Ratio > BlockFrequencyRatioThreshold;
1646480093f4SDimitry Andric }
1647