1044eb2f6SDimitry Andric //===- MachineLICM.cpp - Machine Loop Invariant Code Motion Pass ----------===//
2009b1c42SEd Schouten //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6009b1c42SEd Schouten //
7009b1c42SEd Schouten //===----------------------------------------------------------------------===//
8009b1c42SEd Schouten //
9009b1c42SEd Schouten // This pass performs loop invariant code motion on machine instructions. We
10009b1c42SEd Schouten // attempt to remove as much code from the body of a loop as possible.
11009b1c42SEd Schouten //
12009b1c42SEd Schouten // This pass is not intended to be a replacement or a complete alternative
13009b1c42SEd Schouten // for the LLVM-IR-level LICM pass. It is only designed to hoist simple
14009b1c42SEd Schouten // constructs that are not exposed before lowering and instruction selection.
15009b1c42SEd Schouten //
16009b1c42SEd Schouten //===----------------------------------------------------------------------===//
17009b1c42SEd Schouten
18044eb2f6SDimitry Andric #include "llvm/ADT/BitVector.h"
194a16efa3SDimitry Andric #include "llvm/ADT/DenseMap.h"
20044eb2f6SDimitry Andric #include "llvm/ADT/STLExtras.h"
214a16efa3SDimitry Andric #include "llvm/ADT/SmallSet.h"
22044eb2f6SDimitry Andric #include "llvm/ADT/SmallVector.h"
234a16efa3SDimitry Andric #include "llvm/ADT/Statistic.h"
244a16efa3SDimitry Andric #include "llvm/Analysis/AliasAnalysis.h"
25044eb2f6SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
26706b4fc4SDimitry Andric #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
27009b1c42SEd Schouten #include "llvm/CodeGen/MachineDominators.h"
28d7f7719eSRoman Divacky #include "llvm/CodeGen/MachineFrameInfo.h"
29044eb2f6SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
30044eb2f6SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h"
31044eb2f6SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
32009b1c42SEd Schouten #include "llvm/CodeGen/MachineLoopInfo.h"
3336bf506aSRoman Divacky #include "llvm/CodeGen/MachineMemOperand.h"
34044eb2f6SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
35009b1c42SEd Schouten #include "llvm/CodeGen/MachineRegisterInfo.h"
3636bf506aSRoman Divacky #include "llvm/CodeGen/PseudoSourceValue.h"
37044eb2f6SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
38044eb2f6SDimitry Andric #include "llvm/CodeGen/TargetLowering.h"
39044eb2f6SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
403a0822f0SDimitry Andric #include "llvm/CodeGen/TargetSchedule.h"
41044eb2f6SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
42044eb2f6SDimitry Andric #include "llvm/IR/DebugLoc.h"
43706b4fc4SDimitry Andric #include "llvm/InitializePasses.h"
44044eb2f6SDimitry Andric #include "llvm/MC/MCInstrDesc.h"
45b60736ecSDimitry Andric #include "llvm/MC/MCRegister.h"
46044eb2f6SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
47044eb2f6SDimitry Andric #include "llvm/Pass.h"
48044eb2f6SDimitry Andric #include "llvm/Support/Casting.h"
4930815c53SDimitry Andric #include "llvm/Support/CommandLine.h"
50009b1c42SEd Schouten #include "llvm/Support/Debug.h"
5159850d08SRoman Divacky #include "llvm/Support/raw_ostream.h"
52044eb2f6SDimitry Andric #include <algorithm>
53044eb2f6SDimitry Andric #include <cassert>
54044eb2f6SDimitry Andric #include <limits>
55044eb2f6SDimitry Andric #include <vector>
56044eb2f6SDimitry Andric
57009b1c42SEd Schouten using namespace llvm;
58009b1c42SEd Schouten
59ab44ce3dSDimitry Andric #define DEBUG_TYPE "machinelicm"
605ca98fd9SDimitry Andric
6130815c53SDimitry Andric static cl::opt<bool>
6230815c53SDimitry Andric AvoidSpeculation("avoid-speculation",
6330815c53SDimitry Andric cl::desc("MachineLICM should avoid speculation"),
6463faed5bSDimitry Andric cl::init(true), cl::Hidden);
6530815c53SDimitry Andric
6667c32a98SDimitry Andric static cl::opt<bool>
6767c32a98SDimitry Andric HoistCheapInsts("hoist-cheap-insts",
6867c32a98SDimitry Andric cl::desc("MachineLICM should hoist even cheap instructions"),
6967c32a98SDimitry Andric cl::init(false), cl::Hidden);
7067c32a98SDimitry Andric
715a5ac124SDimitry Andric static cl::opt<bool>
72eb11fae6SDimitry Andric HoistConstStores("hoist-const-stores",
73eb11fae6SDimitry Andric cl::desc("Hoist invariant stores"),
74eb11fae6SDimitry Andric cl::init(true), cl::Hidden);
75b1c73532SDimitry Andric
76b1c73532SDimitry Andric static cl::opt<bool> HoistConstLoads("hoist-const-loads",
77b1c73532SDimitry Andric cl::desc("Hoist invariant loads"),
78b1c73532SDimitry Andric cl::init(true), cl::Hidden);
79b1c73532SDimitry Andric
80706b4fc4SDimitry Andric // The default threshold of 100 (i.e. if target block is 100 times hotter)
81706b4fc4SDimitry Andric // is based on empirical data on a single target and is subject to tuning.
82706b4fc4SDimitry Andric static cl::opt<unsigned>
83706b4fc4SDimitry Andric BlockFrequencyRatioThreshold("block-freq-ratio-threshold",
84706b4fc4SDimitry Andric cl::desc("Do not hoist instructions if target"
85706b4fc4SDimitry Andric "block is N times hotter than the source."),
86706b4fc4SDimitry Andric cl::init(100), cl::Hidden);
87706b4fc4SDimitry Andric
88706b4fc4SDimitry Andric enum class UseBFI { None, PGO, All };
89706b4fc4SDimitry Andric
90706b4fc4SDimitry Andric static cl::opt<UseBFI>
91706b4fc4SDimitry Andric DisableHoistingToHotterBlocks("disable-hoisting-to-hotter-blocks",
92706b4fc4SDimitry Andric cl::desc("Disable hoisting instructions to"
93706b4fc4SDimitry Andric " hotter blocks"),
94b60736ecSDimitry Andric cl::init(UseBFI::PGO), cl::Hidden,
95706b4fc4SDimitry Andric cl::values(clEnumValN(UseBFI::None, "none",
96706b4fc4SDimitry Andric "disable the feature"),
97706b4fc4SDimitry Andric clEnumValN(UseBFI::PGO, "pgo",
98706b4fc4SDimitry Andric "enable the feature when using profile data"),
99706b4fc4SDimitry Andric clEnumValN(UseBFI::All, "all",
100706b4fc4SDimitry Andric "enable the feature with/wo profile data")));
1015a5ac124SDimitry Andric
102cf099d11SDimitry Andric STATISTIC(NumHoisted,
103cf099d11SDimitry Andric "Number of machine instructions hoisted out of loops");
104cf099d11SDimitry Andric STATISTIC(NumLowRP,
105cf099d11SDimitry Andric "Number of instructions hoisted in low reg pressure situation");
106cf099d11SDimitry Andric STATISTIC(NumHighLatency,
107cf099d11SDimitry Andric "Number of high latency instructions hoisted");
108cf099d11SDimitry Andric STATISTIC(NumCSEed,
109cf099d11SDimitry Andric "Number of hoisted machine instructions CSEed");
110d7f7719eSRoman Divacky STATISTIC(NumPostRAHoisted,
111d7f7719eSRoman Divacky "Number of machine instructions hoisted out of loops post regalloc");
112eb11fae6SDimitry Andric STATISTIC(NumStoreConst,
113eb11fae6SDimitry Andric "Number of stores of const phys reg hoisted out of loops");
114706b4fc4SDimitry Andric STATISTIC(NumNotHoistedDueToHotness,
115706b4fc4SDimitry Andric "Number of instructions not hoisted due to block frequency");
116009b1c42SEd Schouten
117009b1c42SEd Schouten namespace {
118b1c73532SDimitry Andric enum HoistResult { NotHoisted = 1, Hoisted = 2, ErasedMI = 4 };
119044eb2f6SDimitry Andric
120eb11fae6SDimitry Andric class MachineLICMBase : public MachineFunctionPass {
1217fa27ce4SDimitry Andric const TargetInstrInfo *TII = nullptr;
1227fa27ce4SDimitry Andric const TargetLoweringBase *TLI = nullptr;
1237fa27ce4SDimitry Andric const TargetRegisterInfo *TRI = nullptr;
1247fa27ce4SDimitry Andric const MachineFrameInfo *MFI = nullptr;
1257fa27ce4SDimitry Andric MachineRegisterInfo *MRI = nullptr;
1263a0822f0SDimitry Andric TargetSchedModel SchedModel;
1277fa27ce4SDimitry Andric bool PreRegAlloc = false;
1287fa27ce4SDimitry Andric bool HasProfileData = false;
129009b1c42SEd Schouten
130009b1c42SEd Schouten // Various analyses that we use...
1317fa27ce4SDimitry Andric AliasAnalysis *AA = nullptr; // Alias analysis info.
1327fa27ce4SDimitry Andric MachineBlockFrequencyInfo *MBFI = nullptr; // Machine block frequncy info
1337fa27ce4SDimitry Andric MachineLoopInfo *MLI = nullptr; // Current MachineLoopInfo
1347fa27ce4SDimitry Andric MachineDominatorTree *DT = nullptr; // Machine dominator tree for the cur loop
135009b1c42SEd Schouten
136009b1c42SEd Schouten // State that is updated as we process loops
1377fa27ce4SDimitry Andric bool Changed = false; // True if a loop is changed.
1387fa27ce4SDimitry Andric bool FirstInLoop = false; // True if it's the first LICM in the loop.
139009b1c42SEd Schouten
140b1c73532SDimitry Andric // Holds information about whether it is allowed to move load instructions
141b1c73532SDimitry Andric // out of the loop
142b1c73532SDimitry Andric SmallDenseMap<MachineLoop *, bool> AllowedToHoistLoads;
143b1c73532SDimitry Andric
144b1c73532SDimitry Andric // Exit blocks of each Loop.
145b1c73532SDimitry Andric DenseMap<MachineLoop *, SmallVector<MachineBasicBlock *, 8>> ExitBlockMap;
146b1c73532SDimitry Andric
isExitBlock(MachineLoop * CurLoop,const MachineBasicBlock * MBB)147b1c73532SDimitry Andric bool isExitBlock(MachineLoop *CurLoop, const MachineBasicBlock *MBB) {
148b1c73532SDimitry Andric if (ExitBlockMap.contains(CurLoop))
149b1c73532SDimitry Andric return is_contained(ExitBlockMap[CurLoop], MBB);
150b1c73532SDimitry Andric
15163faed5bSDimitry Andric SmallVector<MachineBasicBlock *, 8> ExitBlocks;
152b1c73532SDimitry Andric CurLoop->getExitBlocks(ExitBlocks);
153b1c73532SDimitry Andric ExitBlockMap[CurLoop] = ExitBlocks;
154b915e9e0SDimitry Andric return is_contained(ExitBlocks, MBB);
15563faed5bSDimitry Andric }
156d7f7719eSRoman Divacky
157cf099d11SDimitry Andric // Track 'estimated' register pressure.
158ac9a064cSDimitry Andric SmallDenseSet<Register> RegSeen;
159cf099d11SDimitry Andric SmallVector<unsigned, 8> RegPressure;
160cf099d11SDimitry Andric
1615a5ac124SDimitry Andric // Register pressure "limit" per register pressure set. If the pressure
162cf099d11SDimitry Andric // is higher than the limit, then it's considered high.
163cf099d11SDimitry Andric SmallVector<unsigned, 8> RegLimit;
164cf099d11SDimitry Andric
165cf099d11SDimitry Andric // Register pressure on path leading from loop preheader to current BB.
166cf099d11SDimitry Andric SmallVector<SmallVector<unsigned, 8>, 16> BackTrace;
167cf099d11SDimitry Andric
168b1c73532SDimitry Andric // For each opcode per preheader, keep a list of potential CSE instructions.
169b1c73532SDimitry Andric DenseMap<MachineBasicBlock *,
170b1c73532SDimitry Andric DenseMap<unsigned, std::vector<MachineInstr *>>>
171b1c73532SDimitry Andric CSEMap;
172d7f7719eSRoman Divacky
17330815c53SDimitry Andric enum {
17430815c53SDimitry Andric SpeculateFalse = 0,
17530815c53SDimitry Andric SpeculateTrue = 1,
17630815c53SDimitry Andric SpeculateUnknown = 2
17730815c53SDimitry Andric };
17830815c53SDimitry Andric
17930815c53SDimitry Andric // If a MBB does not dominate loop exiting blocks then it may not safe
18030815c53SDimitry Andric // to hoist loads from this block.
18130815c53SDimitry Andric // Tri-state: 0 - false, 1 - true, 2 - unknown
1827fa27ce4SDimitry Andric unsigned SpeculationState = SpeculateUnknown;
18330815c53SDimitry Andric
184009b1c42SEd Schouten public:
MachineLICMBase(char & PassID,bool PreRegAlloc)185eb11fae6SDimitry Andric MachineLICMBase(char &PassID, bool PreRegAlloc)
186eb11fae6SDimitry Andric : MachineFunctionPass(PassID), PreRegAlloc(PreRegAlloc) {}
187009b1c42SEd Schouten
1885ca98fd9SDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override;
189009b1c42SEd Schouten
getAnalysisUsage(AnalysisUsage & AU) const1905ca98fd9SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override {
191ac9a064cSDimitry Andric AU.addRequired<MachineLoopInfoWrapperPass>();
192706b4fc4SDimitry Andric if (DisableHoistingToHotterBlocks != UseBFI::None)
193ac9a064cSDimitry Andric AU.addRequired<MachineBlockFrequencyInfoWrapperPass>();
194ac9a064cSDimitry Andric AU.addRequired<MachineDominatorTreeWrapperPass>();
195dd58ef01SDimitry Andric AU.addRequired<AAResultsWrapperPass>();
196ac9a064cSDimitry Andric AU.addPreserved<MachineLoopInfoWrapperPass>();
197009b1c42SEd Schouten MachineFunctionPass::getAnalysisUsage(AU);
198009b1c42SEd Schouten }
199009b1c42SEd Schouten
releaseMemory()2005ca98fd9SDimitry Andric void releaseMemory() override {
201cf099d11SDimitry Andric RegSeen.clear();
202cf099d11SDimitry Andric RegPressure.clear();
203cf099d11SDimitry Andric RegLimit.clear();
204cf099d11SDimitry Andric BackTrace.clear();
205009b1c42SEd Schouten CSEMap.clear();
206b1c73532SDimitry Andric ExitBlockMap.clear();
207009b1c42SEd Schouten }
208009b1c42SEd Schouten
209009b1c42SEd Schouten private:
210dd58ef01SDimitry Andric /// Keep track of information about hoisting candidates.
211d7f7719eSRoman Divacky struct CandidateInfo {
212d7f7719eSRoman Divacky MachineInstr *MI;
213d7f7719eSRoman Divacky unsigned Def;
214d7f7719eSRoman Divacky int FI;
215044eb2f6SDimitry Andric
CandidateInfo__anon211e68230111::MachineLICMBase::CandidateInfo216d7f7719eSRoman Divacky CandidateInfo(MachineInstr *mi, unsigned def, int fi)
217d7f7719eSRoman Divacky : MI(mi), Def(def), FI(fi) {}
218d7f7719eSRoman Divacky };
219d7f7719eSRoman Divacky
220b1c73532SDimitry Andric void HoistRegionPostRA(MachineLoop *CurLoop,
221b1c73532SDimitry Andric MachineBasicBlock *CurPreheader);
222d7f7719eSRoman Divacky
223b1c73532SDimitry Andric void HoistPostRA(MachineInstr *MI, unsigned Def, MachineLoop *CurLoop,
224b1c73532SDimitry Andric MachineBasicBlock *CurPreheader);
225d7f7719eSRoman Divacky
226ac9a064cSDimitry Andric void ProcessMI(MachineInstr *MI, BitVector &RUDefs, BitVector &RUClobbers,
227ac9a064cSDimitry Andric SmallDenseSet<int> &StoredFIs,
228b1c73532SDimitry Andric SmallVectorImpl<CandidateInfo> &Candidates,
229b1c73532SDimitry Andric MachineLoop *CurLoop);
230d7f7719eSRoman Divacky
231b1c73532SDimitry Andric void AddToLiveIns(MCRegister Reg, MachineLoop *CurLoop);
232d7f7719eSRoman Divacky
233b1c73532SDimitry Andric bool IsLICMCandidate(MachineInstr &I, MachineLoop *CurLoop);
234d7f7719eSRoman Divacky
235b1c73532SDimitry Andric bool IsLoopInvariantInst(MachineInstr &I, MachineLoop *CurLoop);
236009b1c42SEd Schouten
237b1c73532SDimitry Andric bool HasLoopPHIUse(const MachineInstr *MI, MachineLoop *CurLoop);
2386b943ff3SDimitry Andric
239b1c73532SDimitry Andric bool HasHighOperandLatency(MachineInstr &MI, unsigned DefIdx, Register Reg,
240b1c73532SDimitry Andric MachineLoop *CurLoop) const;
241cf099d11SDimitry Andric
242cf099d11SDimitry Andric bool IsCheapInstruction(MachineInstr &MI) const;
243cf099d11SDimitry Andric
2445a5ac124SDimitry Andric bool CanCauseHighRegPressure(const DenseMap<unsigned, int> &Cost,
2455a5ac124SDimitry Andric bool Cheap);
246cf099d11SDimitry Andric
247cf099d11SDimitry Andric void UpdateBackTraceRegPressure(const MachineInstr *MI);
248cf099d11SDimitry Andric
249b1c73532SDimitry Andric bool IsProfitableToHoist(MachineInstr &MI, MachineLoop *CurLoop);
250009b1c42SEd Schouten
251b1c73532SDimitry Andric bool IsGuaranteedToExecute(MachineBasicBlock *BB, MachineLoop *CurLoop);
25230815c53SDimitry Andric
2534b4fe385SDimitry Andric bool isTriviallyReMaterializable(const MachineInstr &MI) const;
254c0981da4SDimitry Andric
25563faed5bSDimitry Andric void EnterScope(MachineBasicBlock *MBB);
25663faed5bSDimitry Andric
25763faed5bSDimitry Andric void ExitScope(MachineBasicBlock *MBB);
25863faed5bSDimitry Andric
259dd58ef01SDimitry Andric void ExitScopeIfDone(
260dd58ef01SDimitry Andric MachineDomTreeNode *Node,
26163faed5bSDimitry Andric DenseMap<MachineDomTreeNode *, unsigned> &OpenChildren,
262145449b1SDimitry Andric const DenseMap<MachineDomTreeNode *, MachineDomTreeNode *> &ParentMap);
26363faed5bSDimitry Andric
264b1c73532SDimitry Andric void HoistOutOfLoop(MachineDomTreeNode *HeaderN, MachineLoop *CurLoop,
265b1c73532SDimitry Andric MachineBasicBlock *CurPreheader);
266dd58ef01SDimitry Andric
267cf099d11SDimitry Andric void InitRegPressure(MachineBasicBlock *BB);
268cf099d11SDimitry Andric
2695a5ac124SDimitry Andric DenseMap<unsigned, int> calcRegisterCost(const MachineInstr *MI,
2705a5ac124SDimitry Andric bool ConsiderSeen,
2715a5ac124SDimitry Andric bool ConsiderUnseenAsDef);
2725a5ac124SDimitry Andric
2735a5ac124SDimitry Andric void UpdateRegPressure(const MachineInstr *MI,
2745a5ac124SDimitry Andric bool ConsiderUnseenAsDef = false);
27506f9d401SRoman Divacky
276b1c73532SDimitry Andric MachineInstr *ExtractHoistableLoad(MachineInstr *MI, MachineLoop *CurLoop);
27736bf506aSRoman Divacky
278b60736ecSDimitry Andric MachineInstr *LookForDuplicate(const MachineInstr *MI,
279b60736ecSDimitry Andric std::vector<MachineInstr *> &PrevMIs);
280907da171SRoman Divacky
281b60736ecSDimitry Andric bool
282b60736ecSDimitry Andric EliminateCSE(MachineInstr *MI,
283b60736ecSDimitry Andric DenseMap<unsigned, std::vector<MachineInstr *>>::iterator &CI);
28472cc5085SRoman Divacky
28530815c53SDimitry Andric bool MayCSE(MachineInstr *MI);
28630815c53SDimitry Andric
287b1c73532SDimitry Andric unsigned Hoist(MachineInstr *MI, MachineBasicBlock *Preheader,
288b1c73532SDimitry Andric MachineLoop *CurLoop);
28936bf506aSRoman Divacky
29036bf506aSRoman Divacky void InitCSEMap(MachineBasicBlock *BB);
29166e41e3cSRoman Divacky
292b1c73532SDimitry Andric void InitializeLoadsHoistableLoops();
293b1c73532SDimitry Andric
294706b4fc4SDimitry Andric bool isTgtHotterThanSrc(MachineBasicBlock *SrcBlock,
295706b4fc4SDimitry Andric MachineBasicBlock *TgtBlock);
296b1c73532SDimitry Andric MachineBasicBlock *getCurPreheader(MachineLoop *CurLoop,
297b1c73532SDimitry Andric MachineBasicBlock *CurPreheader);
298009b1c42SEd Schouten };
299044eb2f6SDimitry Andric
300eb11fae6SDimitry Andric class MachineLICM : public MachineLICMBase {
301eb11fae6SDimitry Andric public:
302eb11fae6SDimitry Andric static char ID;
MachineLICM()303eb11fae6SDimitry Andric MachineLICM() : MachineLICMBase(ID, false) {
304eb11fae6SDimitry Andric initializeMachineLICMPass(*PassRegistry::getPassRegistry());
305eb11fae6SDimitry Andric }
306eb11fae6SDimitry Andric };
307eb11fae6SDimitry Andric
308eb11fae6SDimitry Andric class EarlyMachineLICM : public MachineLICMBase {
309eb11fae6SDimitry Andric public:
310eb11fae6SDimitry Andric static char ID;
EarlyMachineLICM()311eb11fae6SDimitry Andric EarlyMachineLICM() : MachineLICMBase(ID, true) {
312eb11fae6SDimitry Andric initializeEarlyMachineLICMPass(*PassRegistry::getPassRegistry());
313eb11fae6SDimitry Andric }
314eb11fae6SDimitry Andric };
315eb11fae6SDimitry Andric
316009b1c42SEd Schouten } // end anonymous namespace
317009b1c42SEd Schouten
318eb11fae6SDimitry Andric char MachineLICM::ID;
319eb11fae6SDimitry Andric char EarlyMachineLICM::ID;
320044eb2f6SDimitry Andric
32163faed5bSDimitry Andric char &llvm::MachineLICMID = MachineLICM::ID;
322eb11fae6SDimitry Andric char &llvm::EarlyMachineLICMID = EarlyMachineLICM::ID;
323044eb2f6SDimitry Andric
324ab44ce3dSDimitry Andric INITIALIZE_PASS_BEGIN(MachineLICM, DEBUG_TYPE,
325cf099d11SDimitry Andric "Machine Loop Invariant Code Motion", false, false)
INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass)326ac9a064cSDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass)
327ac9a064cSDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineBlockFrequencyInfoWrapperPass)
328ac9a064cSDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
329dd58ef01SDimitry Andric INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
330ab44ce3dSDimitry Andric INITIALIZE_PASS_END(MachineLICM, DEBUG_TYPE,
331cf099d11SDimitry Andric "Machine Loop Invariant Code Motion", false, false)
332009b1c42SEd Schouten
333eb11fae6SDimitry Andric INITIALIZE_PASS_BEGIN(EarlyMachineLICM, "early-machinelicm",
334eb11fae6SDimitry Andric "Early Machine Loop Invariant Code Motion", false, false)
335ac9a064cSDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass)
336ac9a064cSDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineBlockFrequencyInfoWrapperPass)
337ac9a064cSDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
338eb11fae6SDimitry Andric INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
339eb11fae6SDimitry Andric INITIALIZE_PASS_END(EarlyMachineLICM, "early-machinelicm",
340eb11fae6SDimitry Andric "Early Machine Loop Invariant Code Motion", false, false)
341eb11fae6SDimitry Andric
342eb11fae6SDimitry Andric bool MachineLICMBase::runOnMachineFunction(MachineFunction &MF) {
343044eb2f6SDimitry Andric if (skipFunction(MF.getFunction()))
3445ca98fd9SDimitry Andric return false;
3455ca98fd9SDimitry Andric
34666e41e3cSRoman Divacky Changed = FirstInLoop = false;
3473a0822f0SDimitry Andric const TargetSubtargetInfo &ST = MF.getSubtarget();
3483a0822f0SDimitry Andric TII = ST.getInstrInfo();
3493a0822f0SDimitry Andric TLI = ST.getTargetLowering();
3503a0822f0SDimitry Andric TRI = ST.getRegisterInfo();
351b915e9e0SDimitry Andric MFI = &MF.getFrameInfo();
352cf099d11SDimitry Andric MRI = &MF.getRegInfo();
353eb11fae6SDimitry Andric SchedModel.init(&ST);
35463faed5bSDimitry Andric
35563faed5bSDimitry Andric PreRegAlloc = MRI->isSSA();
356706b4fc4SDimitry Andric HasProfileData = MF.getFunction().hasProfileData();
35763faed5bSDimitry Andric
35863faed5bSDimitry Andric if (PreRegAlloc)
359eb11fae6SDimitry Andric LLVM_DEBUG(dbgs() << "******** Pre-regalloc Machine LICM: ");
36063faed5bSDimitry Andric else
361eb11fae6SDimitry Andric LLVM_DEBUG(dbgs() << "******** Post-regalloc Machine LICM: ");
362eb11fae6SDimitry Andric LLVM_DEBUG(dbgs() << MF.getName() << " ********\n");
363009b1c42SEd Schouten
364cf099d11SDimitry Andric if (PreRegAlloc) {
365cf099d11SDimitry Andric // Estimate register pressure during pre-regalloc pass.
3665a5ac124SDimitry Andric unsigned NumRPS = TRI->getNumRegPressureSets();
3675a5ac124SDimitry Andric RegPressure.resize(NumRPS);
368cf099d11SDimitry Andric std::fill(RegPressure.begin(), RegPressure.end(), 0);
3695a5ac124SDimitry Andric RegLimit.resize(NumRPS);
3705a5ac124SDimitry Andric for (unsigned i = 0, e = NumRPS; i != e; ++i)
3715a5ac124SDimitry Andric RegLimit[i] = TRI->getRegPressureSetLimit(MF, i);
372cf099d11SDimitry Andric }
373cf099d11SDimitry Andric
374009b1c42SEd Schouten // Get our Loop information...
375706b4fc4SDimitry Andric if (DisableHoistingToHotterBlocks != UseBFI::None)
376ac9a064cSDimitry Andric MBFI = &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
377ac9a064cSDimitry Andric MLI = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
378ac9a064cSDimitry Andric DT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
379dd58ef01SDimitry Andric AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
380009b1c42SEd Schouten
381b1c73532SDimitry Andric if (HoistConstLoads)
382b1c73532SDimitry Andric InitializeLoadsHoistableLoops();
383b1c73532SDimitry Andric
38466e41e3cSRoman Divacky SmallVector<MachineLoop *, 8> Worklist(MLI->begin(), MLI->end());
38566e41e3cSRoman Divacky while (!Worklist.empty()) {
386b1c73532SDimitry Andric MachineLoop *CurLoop = Worklist.pop_back_val();
387b1c73532SDimitry Andric MachineBasicBlock *CurPreheader = nullptr;
38863faed5bSDimitry Andric
389d7f7719eSRoman Divacky if (!PreRegAlloc)
390b1c73532SDimitry Andric HoistRegionPostRA(CurLoop, CurPreheader);
391d7f7719eSRoman Divacky else {
39236bf506aSRoman Divacky // CSEMap is initialized for loop header when the first instruction is
39336bf506aSRoman Divacky // being hoisted.
394d7f7719eSRoman Divacky MachineDomTreeNode *N = DT->getNode(CurLoop->getHeader());
39566e41e3cSRoman Divacky FirstInLoop = true;
396b1c73532SDimitry Andric HoistOutOfLoop(N, CurLoop, CurPreheader);
39736bf506aSRoman Divacky CSEMap.clear();
398009b1c42SEd Schouten }
399d7f7719eSRoman Divacky }
400009b1c42SEd Schouten
401009b1c42SEd Schouten return Changed;
402009b1c42SEd Schouten }
403009b1c42SEd Schouten
404dd58ef01SDimitry Andric /// Return true if instruction stores to the specified frame.
InstructionStoresToFI(const MachineInstr * MI,int FI)405d7f7719eSRoman Divacky static bool InstructionStoresToFI(const MachineInstr *MI, int FI) {
406eb11fae6SDimitry Andric // Check mayStore before memory operands so that e.g. DBG_VALUEs will return
407eb11fae6SDimitry Andric // true since they have no memory operands.
408eb11fae6SDimitry Andric if (!MI->mayStore())
409eb11fae6SDimitry Andric return false;
410dd58ef01SDimitry Andric // If we lost memory operands, conservatively assume that the instruction
411dd58ef01SDimitry Andric // writes to all slots.
412dd58ef01SDimitry Andric if (MI->memoperands_empty())
413dd58ef01SDimitry Andric return true;
414050e163aSDimitry Andric for (const MachineMemOperand *MemOp : MI->memoperands()) {
415050e163aSDimitry Andric if (!MemOp->isStore() || !MemOp->getPseudoValue())
416d7f7719eSRoman Divacky continue;
417d7f7719eSRoman Divacky if (const FixedStackPseudoSourceValue *Value =
418050e163aSDimitry Andric dyn_cast<FixedStackPseudoSourceValue>(MemOp->getPseudoValue())) {
419d7f7719eSRoman Divacky if (Value->getFrameIndex() == FI)
420d7f7719eSRoman Divacky return true;
421d7f7719eSRoman Divacky }
422d7f7719eSRoman Divacky }
423d7f7719eSRoman Divacky return false;
424d7f7719eSRoman Divacky }
425d7f7719eSRoman Divacky
applyBitsNotInRegMaskToRegUnitsMask(const TargetRegisterInfo & TRI,BitVector & RUs,const uint32_t * Mask)426ac9a064cSDimitry Andric static void applyBitsNotInRegMaskToRegUnitsMask(const TargetRegisterInfo &TRI,
427ac9a064cSDimitry Andric BitVector &RUs,
428ac9a064cSDimitry Andric const uint32_t *Mask) {
429ac9a064cSDimitry Andric // FIXME: This intentionally works in reverse due to some issues with the
430ac9a064cSDimitry Andric // Register Units infrastructure.
431ac9a064cSDimitry Andric //
432ac9a064cSDimitry Andric // This is used to apply callee-saved-register masks to the clobbered regunits
433ac9a064cSDimitry Andric // mask.
434ac9a064cSDimitry Andric //
435ac9a064cSDimitry Andric // The right way to approach this is to start with a BitVector full of ones,
436ac9a064cSDimitry Andric // then reset all the bits of the regunits of each register that is set in the
437ac9a064cSDimitry Andric // mask (registers preserved), then OR the resulting bits with the Clobbers
438ac9a064cSDimitry Andric // mask. This correctly prioritizes the saved registers, so if a RU is shared
439ac9a064cSDimitry Andric // between a register that is preserved, and one that is NOT preserved, that
440ac9a064cSDimitry Andric // RU will not be set in the output vector (the clobbers).
441ac9a064cSDimitry Andric //
442ac9a064cSDimitry Andric // What we have to do for now is the opposite: we have to assume that the
443ac9a064cSDimitry Andric // regunits of all registers that are NOT preserved are clobbered, even if
444ac9a064cSDimitry Andric // those regunits are preserved by another register. So if a RU is shared
445ac9a064cSDimitry Andric // like described previously, that RU will be set.
446ac9a064cSDimitry Andric //
447ac9a064cSDimitry Andric // This is to work around an issue which appears in AArch64, but isn't
448ac9a064cSDimitry Andric // exclusive to that target: AArch64's Qn registers (128 bits) have Dn
449ac9a064cSDimitry Andric // register (lower 64 bits). A few Dn registers are preserved by some calling
450ac9a064cSDimitry Andric // conventions, but Qn and Dn share exactly the same reg units.
451ac9a064cSDimitry Andric //
452ac9a064cSDimitry Andric // If we do this the right way, Qn will be marked as NOT clobbered even though
453ac9a064cSDimitry Andric // its upper 64 bits are NOT preserved. The conservative approach handles this
454ac9a064cSDimitry Andric // correctly at the cost of some missed optimizations on other targets.
455ac9a064cSDimitry Andric //
456ac9a064cSDimitry Andric // This is caused by how RegUnits are handled within TableGen. Ideally, Qn
457ac9a064cSDimitry Andric // should have an extra RegUnit to model the "unknown" bits not covered by the
458ac9a064cSDimitry Andric // subregs.
459ac9a064cSDimitry Andric BitVector RUsFromRegsNotInMask(TRI.getNumRegUnits());
460ac9a064cSDimitry Andric const unsigned NumRegs = TRI.getNumRegs();
461ac9a064cSDimitry Andric const unsigned MaskWords = (NumRegs + 31) / 32;
462ac9a064cSDimitry Andric for (unsigned K = 0; K < MaskWords; ++K) {
463ac9a064cSDimitry Andric const uint32_t Word = Mask[K];
464ac9a064cSDimitry Andric for (unsigned Bit = 0; Bit < 32; ++Bit) {
465ac9a064cSDimitry Andric const unsigned PhysReg = (K * 32) + Bit;
466ac9a064cSDimitry Andric if (PhysReg == NumRegs)
467ac9a064cSDimitry Andric break;
468ac9a064cSDimitry Andric
469ac9a064cSDimitry Andric if (PhysReg && !((Word >> Bit) & 1)) {
470ac9a064cSDimitry Andric for (MCRegUnitIterator RUI(PhysReg, &TRI); RUI.isValid(); ++RUI)
471ac9a064cSDimitry Andric RUsFromRegsNotInMask.set(*RUI);
472ac9a064cSDimitry Andric }
473ac9a064cSDimitry Andric }
474ac9a064cSDimitry Andric }
475ac9a064cSDimitry Andric
476ac9a064cSDimitry Andric RUs |= RUsFromRegsNotInMask;
477ac9a064cSDimitry Andric }
478ac9a064cSDimitry Andric
479dd58ef01SDimitry Andric /// Examine the instruction for potentai LICM candidate. Also
480d7f7719eSRoman Divacky /// gather register def and frame object update information.
ProcessMI(MachineInstr * MI,BitVector & RUDefs,BitVector & RUClobbers,SmallDenseSet<int> & StoredFIs,SmallVectorImpl<CandidateInfo> & Candidates,MachineLoop * CurLoop)481ac9a064cSDimitry Andric void MachineLICMBase::ProcessMI(MachineInstr *MI, BitVector &RUDefs,
482ac9a064cSDimitry Andric BitVector &RUClobbers,
483ac9a064cSDimitry Andric SmallDenseSet<int> &StoredFIs,
484b1c73532SDimitry Andric SmallVectorImpl<CandidateInfo> &Candidates,
485b1c73532SDimitry Andric MachineLoop *CurLoop) {
486d7f7719eSRoman Divacky bool RuledOut = false;
487d7f7719eSRoman Divacky bool HasNonInvariantUse = false;
488d7f7719eSRoman Divacky unsigned Def = 0;
489050e163aSDimitry Andric for (const MachineOperand &MO : MI->operands()) {
490d7f7719eSRoman Divacky if (MO.isFI()) {
491d7f7719eSRoman Divacky // Remember if the instruction stores to the frame index.
492d7f7719eSRoman Divacky int FI = MO.getIndex();
493d7f7719eSRoman Divacky if (!StoredFIs.count(FI) &&
494d7f7719eSRoman Divacky MFI->isSpillSlotObjectIndex(FI) &&
495d7f7719eSRoman Divacky InstructionStoresToFI(MI, FI))
496d7f7719eSRoman Divacky StoredFIs.insert(FI);
497d7f7719eSRoman Divacky HasNonInvariantUse = true;
498d7f7719eSRoman Divacky continue;
499d7f7719eSRoman Divacky }
500d7f7719eSRoman Divacky
50163faed5bSDimitry Andric // We can't hoist an instruction defining a physreg that is clobbered in
50263faed5bSDimitry Andric // the loop.
50363faed5bSDimitry Andric if (MO.isRegMask()) {
504ac9a064cSDimitry Andric applyBitsNotInRegMaskToRegUnitsMask(*TRI, RUClobbers, MO.getRegMask());
50563faed5bSDimitry Andric continue;
50663faed5bSDimitry Andric }
50763faed5bSDimitry Andric
508d7f7719eSRoman Divacky if (!MO.isReg())
509d7f7719eSRoman Divacky continue;
5101d5ae102SDimitry Andric Register Reg = MO.getReg();
511d7f7719eSRoman Divacky if (!Reg)
512d7f7719eSRoman Divacky continue;
513e3b55780SDimitry Andric assert(Reg.isPhysical() && "Not expecting virtual register!");
514d7f7719eSRoman Divacky
515d7f7719eSRoman Divacky if (!MO.isDef()) {
516ac9a064cSDimitry Andric if (!HasNonInvariantUse) {
517ac9a064cSDimitry Andric for (MCRegUnitIterator RUI(Reg, TRI); RUI.isValid(); ++RUI) {
518ac9a064cSDimitry Andric // If it's using a non-loop-invariant register, then it's obviously
519ac9a064cSDimitry Andric // not safe to hoist.
520ac9a064cSDimitry Andric if (RUDefs.test(*RUI) || RUClobbers.test(*RUI)) {
521d7f7719eSRoman Divacky HasNonInvariantUse = true;
522ac9a064cSDimitry Andric break;
523ac9a064cSDimitry Andric }
524ac9a064cSDimitry Andric }
525ac9a064cSDimitry Andric }
526d7f7719eSRoman Divacky continue;
527d7f7719eSRoman Divacky }
528d7f7719eSRoman Divacky
529d7f7719eSRoman Divacky if (MO.isImplicit()) {
530ac9a064cSDimitry Andric for (MCRegUnitIterator RUI(Reg, TRI); RUI.isValid(); ++RUI)
531ac9a064cSDimitry Andric RUClobbers.set(*RUI);
532d7f7719eSRoman Divacky if (!MO.isDead())
533d7f7719eSRoman Divacky // Non-dead implicit def? This cannot be hoisted.
534d7f7719eSRoman Divacky RuledOut = true;
535d7f7719eSRoman Divacky // No need to check if a dead implicit def is also defined by
536d7f7719eSRoman Divacky // another instruction.
537d7f7719eSRoman Divacky continue;
538d7f7719eSRoman Divacky }
539d7f7719eSRoman Divacky
540d7f7719eSRoman Divacky // FIXME: For now, avoid instructions with multiple defs, unless
541d7f7719eSRoman Divacky // it's a dead implicit def.
542d7f7719eSRoman Divacky if (Def)
543d7f7719eSRoman Divacky RuledOut = true;
544d7f7719eSRoman Divacky else
545d7f7719eSRoman Divacky Def = Reg;
546d7f7719eSRoman Divacky
547d7f7719eSRoman Divacky // If we have already seen another instruction that defines the same
54863faed5bSDimitry Andric // register, then this is not safe. Two defs is indicated by setting a
54963faed5bSDimitry Andric // PhysRegClobbers bit.
550ac9a064cSDimitry Andric for (MCRegUnitIterator RUI(Reg, TRI); RUI.isValid(); ++RUI) {
551ac9a064cSDimitry Andric if (RUDefs.test(*RUI)) {
552ac9a064cSDimitry Andric RUClobbers.set(*RUI);
553ac9a064cSDimitry Andric RuledOut = true;
554ac9a064cSDimitry Andric } else if (RUClobbers.test(*RUI)) {
555d7f7719eSRoman Divacky // MI defined register is seen defined by another instruction in
556d7f7719eSRoman Divacky // the loop, it cannot be a LICM candidate.
557d7f7719eSRoman Divacky RuledOut = true;
558d7f7719eSRoman Divacky }
559d7f7719eSRoman Divacky
560ac9a064cSDimitry Andric RUDefs.set(*RUI);
561ac9a064cSDimitry Andric }
562ac9a064cSDimitry Andric }
563ac9a064cSDimitry Andric
564d7f7719eSRoman Divacky // Only consider reloads for now and remats which do not have register
565d7f7719eSRoman Divacky // operands. FIXME: Consider unfold load folding instructions.
566d7f7719eSRoman Divacky if (Def && !RuledOut) {
567044eb2f6SDimitry Andric int FI = std::numeric_limits<int>::min();
568b1c73532SDimitry Andric if ((!HasNonInvariantUse && IsLICMCandidate(*MI, CurLoop)) ||
56901095a5dSDimitry Andric (TII->isLoadFromStackSlot(*MI, FI) && MFI->isSpillSlotObjectIndex(FI)))
570d7f7719eSRoman Divacky Candidates.push_back(CandidateInfo(MI, Def, FI));
571d7f7719eSRoman Divacky }
572d7f7719eSRoman Divacky }
573d7f7719eSRoman Divacky
574dd58ef01SDimitry Andric /// Walk the specified region of the CFG and hoist loop invariants out to the
575dd58ef01SDimitry Andric /// preheader.
HoistRegionPostRA(MachineLoop * CurLoop,MachineBasicBlock * CurPreheader)576b1c73532SDimitry Andric void MachineLICMBase::HoistRegionPostRA(MachineLoop *CurLoop,
577b1c73532SDimitry Andric MachineBasicBlock *CurPreheader) {
578b1c73532SDimitry Andric MachineBasicBlock *Preheader = getCurPreheader(CurLoop, CurPreheader);
57963faed5bSDimitry Andric if (!Preheader)
58063faed5bSDimitry Andric return;
58163faed5bSDimitry Andric
582ac9a064cSDimitry Andric unsigned NumRegUnits = TRI->getNumRegUnits();
583ac9a064cSDimitry Andric BitVector RUDefs(NumRegUnits); // RUs defined once in the loop.
584ac9a064cSDimitry Andric BitVector RUClobbers(NumRegUnits); // RUs defined more than once.
585d7f7719eSRoman Divacky
586d7f7719eSRoman Divacky SmallVector<CandidateInfo, 32> Candidates;
587ac9a064cSDimitry Andric SmallDenseSet<int> StoredFIs;
588d7f7719eSRoman Divacky
589d7f7719eSRoman Divacky // Walk the entire region, count number of defs for each register, and
590d7f7719eSRoman Divacky // collect potential LICM candidates.
591d8e91e46SDimitry Andric for (MachineBasicBlock *BB : CurLoop->getBlocks()) {
59230815c53SDimitry Andric // If the header of the loop containing this basic block is a landing pad,
59330815c53SDimitry Andric // then don't try to hoist instructions out of this loop.
59430815c53SDimitry Andric const MachineLoop *ML = MLI->getLoopFor(BB);
595dd58ef01SDimitry Andric if (ML && ML->getHeader()->isEHPad()) continue;
59630815c53SDimitry Andric
597d7f7719eSRoman Divacky // Conservatively treat live-in's as an external def.
598d7f7719eSRoman Divacky // FIXME: That means a reload that're reused in successor block(s) will not
599d7f7719eSRoman Divacky // be LICM'ed.
600dd58ef01SDimitry Andric for (const auto &LI : BB->liveins()) {
601ac9a064cSDimitry Andric for (MCRegUnitIterator RUI(LI.PhysReg, TRI); RUI.isValid(); ++RUI)
602ac9a064cSDimitry Andric RUDefs.set(*RUI);
603d7f7719eSRoman Divacky }
604d7f7719eSRoman Divacky
605b1c73532SDimitry Andric // Funclet entry blocks will clobber all registers
606b1c73532SDimitry Andric if (const uint32_t *Mask = BB->getBeginClobberMask(TRI))
607ac9a064cSDimitry Andric applyBitsNotInRegMaskToRegUnitsMask(*TRI, RUClobbers, Mask);
608b1c73532SDimitry Andric
60930815c53SDimitry Andric SpeculationState = SpeculateUnknown;
610050e163aSDimitry Andric for (MachineInstr &MI : *BB)
611ac9a064cSDimitry Andric ProcessMI(&MI, RUDefs, RUClobbers, StoredFIs, Candidates, CurLoop);
61263faed5bSDimitry Andric }
61363faed5bSDimitry Andric
61463faed5bSDimitry Andric // Gather the registers read / clobbered by the terminator.
615ac9a064cSDimitry Andric BitVector TermRUs(NumRegUnits);
61663faed5bSDimitry Andric MachineBasicBlock::iterator TI = Preheader->getFirstTerminator();
61763faed5bSDimitry Andric if (TI != Preheader->end()) {
618050e163aSDimitry Andric for (const MachineOperand &MO : TI->operands()) {
61963faed5bSDimitry Andric if (!MO.isReg())
62063faed5bSDimitry Andric continue;
6211d5ae102SDimitry Andric Register Reg = MO.getReg();
62263faed5bSDimitry Andric if (!Reg)
62363faed5bSDimitry Andric continue;
624ac9a064cSDimitry Andric for (MCRegUnitIterator RUI(Reg, TRI); RUI.isValid(); ++RUI)
625ac9a064cSDimitry Andric TermRUs.set(*RUI);
626d7f7719eSRoman Divacky }
627d7f7719eSRoman Divacky }
628d7f7719eSRoman Divacky
629d7f7719eSRoman Divacky // Now evaluate whether the potential candidates qualify.
630d7f7719eSRoman Divacky // 1. Check if the candidate defined register is defined by another
631d7f7719eSRoman Divacky // instruction in the loop.
632d7f7719eSRoman Divacky // 2. If the candidate is a load from stack slot (always true for now),
633d7f7719eSRoman Divacky // check if the slot is stored anywhere in the loop.
63463faed5bSDimitry Andric // 3. Make sure candidate def should not clobber
63563faed5bSDimitry Andric // registers read by the terminator. Similarly its def should not be
63663faed5bSDimitry Andric // clobbered by the terminator.
637050e163aSDimitry Andric for (CandidateInfo &Candidate : Candidates) {
638044eb2f6SDimitry Andric if (Candidate.FI != std::numeric_limits<int>::min() &&
639050e163aSDimitry Andric StoredFIs.count(Candidate.FI))
640d7f7719eSRoman Divacky continue;
641d7f7719eSRoman Divacky
642050e163aSDimitry Andric unsigned Def = Candidate.Def;
643d7f7719eSRoman Divacky bool Safe = true;
644ac9a064cSDimitry Andric for (MCRegUnitIterator RUI(Def, TRI); RUI.isValid(); ++RUI) {
645ac9a064cSDimitry Andric if (RUClobbers.test(*RUI) || TermRUs.test(*RUI)) {
646ac9a064cSDimitry Andric Safe = false;
647ac9a064cSDimitry Andric break;
648ac9a064cSDimitry Andric }
649ac9a064cSDimitry Andric }
650ac9a064cSDimitry Andric
651ac9a064cSDimitry Andric if (!Safe)
652ac9a064cSDimitry Andric continue;
653ac9a064cSDimitry Andric
654050e163aSDimitry Andric MachineInstr *MI = Candidate.MI;
6557fa27ce4SDimitry Andric for (const MachineOperand &MO : MI->all_uses()) {
6567fa27ce4SDimitry Andric if (!MO.getReg())
657d7f7719eSRoman Divacky continue;
658ac9a064cSDimitry Andric for (MCRegUnitIterator RUI(MO.getReg(), TRI); RUI.isValid(); ++RUI) {
659ac9a064cSDimitry Andric if (RUDefs.test(*RUI) || RUClobbers.test(*RUI)) {
660d7f7719eSRoman Divacky // If it's using a non-loop-invariant register, then it's obviously
661d7f7719eSRoman Divacky // not safe to hoist.
662d7f7719eSRoman Divacky Safe = false;
663d7f7719eSRoman Divacky break;
664d7f7719eSRoman Divacky }
665d7f7719eSRoman Divacky }
666ac9a064cSDimitry Andric
667ac9a064cSDimitry Andric if (!Safe)
668ac9a064cSDimitry Andric break;
669ac9a064cSDimitry Andric }
670ac9a064cSDimitry Andric
671d7f7719eSRoman Divacky if (Safe)
672b1c73532SDimitry Andric HoistPostRA(MI, Candidate.Def, CurLoop, CurPreheader);
673d7f7719eSRoman Divacky }
674d7f7719eSRoman Divacky }
675d7f7719eSRoman Divacky
676dd58ef01SDimitry Andric /// Add register 'Reg' to the livein sets of BBs in the current loop, and make
677dd58ef01SDimitry Andric /// sure it is not killed by any instructions in the loop.
AddToLiveIns(MCRegister Reg,MachineLoop * CurLoop)678b1c73532SDimitry Andric void MachineLICMBase::AddToLiveIns(MCRegister Reg, MachineLoop *CurLoop) {
679d8e91e46SDimitry Andric for (MachineBasicBlock *BB : CurLoop->getBlocks()) {
680d7f7719eSRoman Divacky if (!BB->isLiveIn(Reg))
681d7f7719eSRoman Divacky BB->addLiveIn(Reg);
682050e163aSDimitry Andric for (MachineInstr &MI : *BB) {
6837fa27ce4SDimitry Andric for (MachineOperand &MO : MI.all_uses()) {
6847fa27ce4SDimitry Andric if (!MO.getReg())
6857fa27ce4SDimitry Andric continue;
686b1c73532SDimitry Andric if (TRI->regsOverlap(Reg, MO.getReg()))
687d7f7719eSRoman Divacky MO.setIsKill(false);
688d7f7719eSRoman Divacky }
689d7f7719eSRoman Divacky }
690d7f7719eSRoman Divacky }
691d7f7719eSRoman Divacky }
692d7f7719eSRoman Divacky
693dd58ef01SDimitry Andric /// When an instruction is found to only use loop invariant operands that is
694dd58ef01SDimitry Andric /// safe to hoist, this instruction is called to do the dirty work.
HoistPostRA(MachineInstr * MI,unsigned Def,MachineLoop * CurLoop,MachineBasicBlock * CurPreheader)695b1c73532SDimitry Andric void MachineLICMBase::HoistPostRA(MachineInstr *MI, unsigned Def,
696b1c73532SDimitry Andric MachineLoop *CurLoop,
697b1c73532SDimitry Andric MachineBasicBlock *CurPreheader) {
698b1c73532SDimitry Andric MachineBasicBlock *Preheader = getCurPreheader(CurLoop, CurPreheader);
69966e41e3cSRoman Divacky
700d7f7719eSRoman Divacky // Now move the instructions to the predecessor, inserting it before any
701d7f7719eSRoman Divacky // terminator instructions.
702eb11fae6SDimitry Andric LLVM_DEBUG(dbgs() << "Hoisting to " << printMBBReference(*Preheader)
703eb11fae6SDimitry Andric << " from " << printMBBReference(*MI->getParent()) << ": "
704eb11fae6SDimitry Andric << *MI);
705d7f7719eSRoman Divacky
706d7f7719eSRoman Divacky // Splice the instruction to the preheader.
707d7f7719eSRoman Divacky MachineBasicBlock *MBB = MI->getParent();
70866e41e3cSRoman Divacky Preheader->splice(Preheader->getFirstTerminator(), MBB, MI);
709d7f7719eSRoman Divacky
710cfca06d7SDimitry Andric // Since we are moving the instruction out of its basic block, we do not
711cfca06d7SDimitry Andric // retain its debug location. Doing so would degrade the debugging
712cfca06d7SDimitry Andric // experience and adversely affect the accuracy of profiling information.
713cfca06d7SDimitry Andric assert(!MI->isDebugInstr() && "Should not hoist debug inst");
714cfca06d7SDimitry Andric MI->setDebugLoc(DebugLoc());
715cfca06d7SDimitry Andric
716d7f7719eSRoman Divacky // Add register to livein list to all the BBs in the current loop since a
717d7f7719eSRoman Divacky // loop invariant must be kept live throughout the whole loop. This is
718d7f7719eSRoman Divacky // important to ensure later passes do not scavenge the def register.
719b1c73532SDimitry Andric AddToLiveIns(Def, CurLoop);
720d7f7719eSRoman Divacky
721d7f7719eSRoman Divacky ++NumPostRAHoisted;
722d7f7719eSRoman Divacky Changed = true;
723d7f7719eSRoman Divacky }
724d7f7719eSRoman Divacky
725dd58ef01SDimitry Andric /// Check if this mbb is guaranteed to execute. If not then a load from this mbb
726dd58ef01SDimitry Andric /// may not be safe to hoist.
IsGuaranteedToExecute(MachineBasicBlock * BB,MachineLoop * CurLoop)727b1c73532SDimitry Andric bool MachineLICMBase::IsGuaranteedToExecute(MachineBasicBlock *BB,
728b1c73532SDimitry Andric MachineLoop *CurLoop) {
72930815c53SDimitry Andric if (SpeculationState != SpeculateUnknown)
73030815c53SDimitry Andric return SpeculationState == SpeculateFalse;
73130815c53SDimitry Andric
73230815c53SDimitry Andric if (BB != CurLoop->getHeader()) {
73330815c53SDimitry Andric // Check loop exiting blocks.
73430815c53SDimitry Andric SmallVector<MachineBasicBlock*, 8> CurrentLoopExitingBlocks;
73530815c53SDimitry Andric CurLoop->getExitingBlocks(CurrentLoopExitingBlocks);
736050e163aSDimitry Andric for (MachineBasicBlock *CurrentLoopExitingBlock : CurrentLoopExitingBlocks)
737050e163aSDimitry Andric if (!DT->dominates(BB, CurrentLoopExitingBlock)) {
73830815c53SDimitry Andric SpeculationState = SpeculateTrue;
73930815c53SDimitry Andric return false;
74030815c53SDimitry Andric }
74130815c53SDimitry Andric }
74230815c53SDimitry Andric
74330815c53SDimitry Andric SpeculationState = SpeculateFalse;
74430815c53SDimitry Andric return true;
74530815c53SDimitry Andric }
74630815c53SDimitry Andric
747c0981da4SDimitry Andric /// Check if \p MI is trivially remateralizable and if it does not have any
748c0981da4SDimitry Andric /// virtual register uses. Even though rematerializable RA might not actually
749c0981da4SDimitry Andric /// rematerialize it in this scenario. In that case we do not want to hoist such
750c0981da4SDimitry Andric /// instruction out of the loop in a belief RA will sink it back if needed.
isTriviallyReMaterializable(const MachineInstr & MI) const7514b4fe385SDimitry Andric bool MachineLICMBase::isTriviallyReMaterializable(
7524b4fe385SDimitry Andric const MachineInstr &MI) const {
7534b4fe385SDimitry Andric if (!TII->isTriviallyReMaterializable(MI))
754c0981da4SDimitry Andric return false;
755c0981da4SDimitry Andric
7567fa27ce4SDimitry Andric for (const MachineOperand &MO : MI.all_uses()) {
7577fa27ce4SDimitry Andric if (MO.getReg().isVirtual())
758c0981da4SDimitry Andric return false;
759c0981da4SDimitry Andric }
760c0981da4SDimitry Andric
761c0981da4SDimitry Andric return true;
762c0981da4SDimitry Andric }
763c0981da4SDimitry Andric
EnterScope(MachineBasicBlock * MBB)764eb11fae6SDimitry Andric void MachineLICMBase::EnterScope(MachineBasicBlock *MBB) {
765eb11fae6SDimitry Andric LLVM_DEBUG(dbgs() << "Entering " << printMBBReference(*MBB) << '\n');
76663faed5bSDimitry Andric
76763faed5bSDimitry Andric // Remember livein register pressure.
76863faed5bSDimitry Andric BackTrace.push_back(RegPressure);
76963faed5bSDimitry Andric }
77063faed5bSDimitry Andric
ExitScope(MachineBasicBlock * MBB)771eb11fae6SDimitry Andric void MachineLICMBase::ExitScope(MachineBasicBlock *MBB) {
772eb11fae6SDimitry Andric LLVM_DEBUG(dbgs() << "Exiting " << printMBBReference(*MBB) << '\n');
77363faed5bSDimitry Andric BackTrace.pop_back();
77463faed5bSDimitry Andric }
77563faed5bSDimitry Andric
776dd58ef01SDimitry Andric /// Destroy scope for the MBB that corresponds to the given dominator tree node
777dd58ef01SDimitry Andric /// if its a leaf or all of its children are done. Walk up the dominator tree to
778dd58ef01SDimitry Andric /// destroy ancestors which are now done.
ExitScopeIfDone(MachineDomTreeNode * Node,DenseMap<MachineDomTreeNode *,unsigned> & OpenChildren,const DenseMap<MachineDomTreeNode *,MachineDomTreeNode * > & ParentMap)779eb11fae6SDimitry Andric void MachineLICMBase::ExitScopeIfDone(MachineDomTreeNode *Node,
78063faed5bSDimitry Andric DenseMap<MachineDomTreeNode*, unsigned> &OpenChildren,
781145449b1SDimitry Andric const DenseMap<MachineDomTreeNode*, MachineDomTreeNode*> &ParentMap) {
78263faed5bSDimitry Andric if (OpenChildren[Node])
78363faed5bSDimitry Andric return;
78463faed5bSDimitry Andric
785145449b1SDimitry Andric for(;;) {
78663faed5bSDimitry Andric ExitScope(Node->getBlock());
78763faed5bSDimitry Andric // Now traverse upwards to pop ancestors whose offsprings are all done.
788145449b1SDimitry Andric MachineDomTreeNode *Parent = ParentMap.lookup(Node);
789145449b1SDimitry Andric if (!Parent || --OpenChildren[Parent] != 0)
79063faed5bSDimitry Andric break;
79163faed5bSDimitry Andric Node = Parent;
79263faed5bSDimitry Andric }
79363faed5bSDimitry Andric }
79463faed5bSDimitry Andric
795dd58ef01SDimitry Andric /// Walk the specified loop in the CFG (defined by all blocks dominated by the
796dd58ef01SDimitry Andric /// specified header block, and that are in the current loop) in depth first
797dd58ef01SDimitry Andric /// order w.r.t the DominatorTree. This allows us to visit definitions before
798dd58ef01SDimitry Andric /// uses, allowing us to hoist a loop body in one pass without iteration.
HoistOutOfLoop(MachineDomTreeNode * HeaderN,MachineLoop * CurLoop,MachineBasicBlock * CurPreheader)799b1c73532SDimitry Andric void MachineLICMBase::HoistOutOfLoop(MachineDomTreeNode *HeaderN,
800b1c73532SDimitry Andric MachineLoop *CurLoop,
801b1c73532SDimitry Andric MachineBasicBlock *CurPreheader) {
802b1c73532SDimitry Andric MachineBasicBlock *Preheader = getCurPreheader(CurLoop, CurPreheader);
8035a5ac124SDimitry Andric if (!Preheader)
8045a5ac124SDimitry Andric return;
8055a5ac124SDimitry Andric
80663faed5bSDimitry Andric SmallVector<MachineDomTreeNode*, 32> Scopes;
80763faed5bSDimitry Andric SmallVector<MachineDomTreeNode*, 8> WorkList;
80863faed5bSDimitry Andric DenseMap<MachineDomTreeNode*, MachineDomTreeNode*> ParentMap;
80963faed5bSDimitry Andric DenseMap<MachineDomTreeNode*, unsigned> OpenChildren;
81063faed5bSDimitry Andric
81163faed5bSDimitry Andric // Perform a DFS walk to determine the order of visit.
81263faed5bSDimitry Andric WorkList.push_back(HeaderN);
8135a5ac124SDimitry Andric while (!WorkList.empty()) {
81463faed5bSDimitry Andric MachineDomTreeNode *Node = WorkList.pop_back_val();
8155ca98fd9SDimitry Andric assert(Node && "Null dominator tree node?");
81663faed5bSDimitry Andric MachineBasicBlock *BB = Node->getBlock();
817009b1c42SEd Schouten
81830815c53SDimitry Andric // If the header of the loop containing this basic block is a landing pad,
81930815c53SDimitry Andric // then don't try to hoist instructions out of this loop.
82030815c53SDimitry Andric const MachineLoop *ML = MLI->getLoopFor(BB);
821dd58ef01SDimitry Andric if (ML && ML->getHeader()->isEHPad())
82263faed5bSDimitry Andric continue;
82330815c53SDimitry Andric
824009b1c42SEd Schouten // If this subregion is not in the top level loop at all, exit.
82563faed5bSDimitry Andric if (!CurLoop->contains(BB))
82663faed5bSDimitry Andric continue;
827009b1c42SEd Schouten
82863faed5bSDimitry Andric Scopes.push_back(Node);
829cfca06d7SDimitry Andric unsigned NumChildren = Node->getNumChildren();
83063faed5bSDimitry Andric
83163faed5bSDimitry Andric // Don't hoist things out of a large switch statement. This often causes
83263faed5bSDimitry Andric // code to be hoisted that wasn't going to be executed, and increases
83363faed5bSDimitry Andric // register pressure in a situation where it's likely to matter.
83463faed5bSDimitry Andric if (BB->succ_size() >= 25)
83563faed5bSDimitry Andric NumChildren = 0;
83663faed5bSDimitry Andric
83763faed5bSDimitry Andric OpenChildren[Node] = NumChildren;
838cfca06d7SDimitry Andric if (NumChildren) {
83963faed5bSDimitry Andric // Add children in reverse order as then the next popped worklist node is
84063faed5bSDimitry Andric // the first child of this node. This means we ultimately traverse the
84163faed5bSDimitry Andric // DOM tree in exactly the same order as if we'd recursed.
842cfca06d7SDimitry Andric for (MachineDomTreeNode *Child : reverse(Node->children())) {
84363faed5bSDimitry Andric ParentMap[Child] = Node;
84463faed5bSDimitry Andric WorkList.push_back(Child);
84563faed5bSDimitry Andric }
8465a5ac124SDimitry Andric }
847cfca06d7SDimitry Andric }
84863faed5bSDimitry Andric
8495a5ac124SDimitry Andric if (Scopes.size() == 0)
850cf099d11SDimitry Andric return;
851cf099d11SDimitry Andric
852cf099d11SDimitry Andric // Compute registers which are livein into the loop headers.
853cf099d11SDimitry Andric RegSeen.clear();
854cf099d11SDimitry Andric BackTrace.clear();
855cf099d11SDimitry Andric InitRegPressure(Preheader);
856cf099d11SDimitry Andric
85763faed5bSDimitry Andric // Now perform LICM.
858050e163aSDimitry Andric for (MachineDomTreeNode *Node : Scopes) {
85963faed5bSDimitry Andric MachineBasicBlock *MBB = Node->getBlock();
860cf099d11SDimitry Andric
86163faed5bSDimitry Andric EnterScope(MBB);
86263faed5bSDimitry Andric
86363faed5bSDimitry Andric // Process the block
86430815c53SDimitry Andric SpeculationState = SpeculateUnknown;
865c0981da4SDimitry Andric for (MachineInstr &MI : llvm::make_early_inc_range(*MBB)) {
866b1c73532SDimitry Andric unsigned HoistRes = HoistResult::NotHoisted;
867b1c73532SDimitry Andric HoistRes = Hoist(&MI, Preheader, CurLoop);
868b1c73532SDimitry Andric if (HoistRes & HoistResult::NotHoisted) {
869b1c73532SDimitry Andric // We have failed to hoist MI to outermost loop's preheader. If MI is in
870b1c73532SDimitry Andric // a subloop, try to hoist it to subloop's preheader.
871b1c73532SDimitry Andric SmallVector<MachineLoop *> InnerLoopWorkList;
872b1c73532SDimitry Andric for (MachineLoop *L = MLI->getLoopFor(MI.getParent()); L != CurLoop;
873b1c73532SDimitry Andric L = L->getParentLoop())
874b1c73532SDimitry Andric InnerLoopWorkList.push_back(L);
875b1c73532SDimitry Andric
876b1c73532SDimitry Andric while (!InnerLoopWorkList.empty()) {
877b1c73532SDimitry Andric MachineLoop *InnerLoop = InnerLoopWorkList.pop_back_val();
878b1c73532SDimitry Andric MachineBasicBlock *InnerLoopPreheader = InnerLoop->getLoopPreheader();
879b1c73532SDimitry Andric if (InnerLoopPreheader) {
880b1c73532SDimitry Andric HoistRes = Hoist(&MI, InnerLoopPreheader, InnerLoop);
881b1c73532SDimitry Andric if (HoistRes & HoistResult::Hoisted)
882b1c73532SDimitry Andric break;
883b1c73532SDimitry Andric }
884b1c73532SDimitry Andric }
885b1c73532SDimitry Andric }
886b1c73532SDimitry Andric
887b1c73532SDimitry Andric if (HoistRes & HoistResult::ErasedMI)
888b1c73532SDimitry Andric continue;
889b1c73532SDimitry Andric
890c0981da4SDimitry Andric UpdateRegPressure(&MI);
891009b1c42SEd Schouten }
892009b1c42SEd Schouten
89363faed5bSDimitry Andric // If it's a leaf node, it's done. Traverse upwards to pop ancestors.
89463faed5bSDimitry Andric ExitScopeIfDone(Node, OpenChildren, ParentMap);
895009b1c42SEd Schouten }
896cf099d11SDimitry Andric }
897cf099d11SDimitry Andric
isOperandKill(const MachineOperand & MO,MachineRegisterInfo * MRI)8985a5ac124SDimitry Andric static bool isOperandKill(const MachineOperand &MO, MachineRegisterInfo *MRI) {
8995a5ac124SDimitry Andric return MO.isKill() || MRI->hasOneNonDBGUse(MO.getReg());
90030815c53SDimitry Andric }
90130815c53SDimitry Andric
902dd58ef01SDimitry Andric /// Find all virtual register references that are liveout of the preheader to
903dd58ef01SDimitry Andric /// initialize the starting "register pressure". Note this does not count live
904dd58ef01SDimitry Andric /// through (livein but not used) registers.
InitRegPressure(MachineBasicBlock * BB)905eb11fae6SDimitry Andric void MachineLICMBase::InitRegPressure(MachineBasicBlock *BB) {
906cf099d11SDimitry Andric std::fill(RegPressure.begin(), RegPressure.end(), 0);
907cf099d11SDimitry Andric
908cf099d11SDimitry Andric // If the preheader has only a single predecessor and it ends with a
909cf099d11SDimitry Andric // fallthrough or an unconditional branch, then scan its predecessor for live
910cf099d11SDimitry Andric // defs as well. This happens whenever the preheader is created by splitting
911cf099d11SDimitry Andric // the critical edge from the loop predecessor to the loop header.
912cf099d11SDimitry Andric if (BB->pred_size() == 1) {
9135ca98fd9SDimitry Andric MachineBasicBlock *TBB = nullptr, *FBB = nullptr;
914cf099d11SDimitry Andric SmallVector<MachineOperand, 4> Cond;
91501095a5dSDimitry Andric if (!TII->analyzeBranch(*BB, TBB, FBB, Cond, false) && Cond.empty())
916cf099d11SDimitry Andric InitRegPressure(*BB->pred_begin());
917cf099d11SDimitry Andric }
918cf099d11SDimitry Andric
9195a5ac124SDimitry Andric for (const MachineInstr &MI : *BB)
9205a5ac124SDimitry Andric UpdateRegPressure(&MI, /*ConsiderUnseenAsDef=*/true);
921cf099d11SDimitry Andric }
922cf099d11SDimitry Andric
923dd58ef01SDimitry Andric /// Update estimate of register pressure after the specified instruction.
UpdateRegPressure(const MachineInstr * MI,bool ConsiderUnseenAsDef)924eb11fae6SDimitry Andric void MachineLICMBase::UpdateRegPressure(const MachineInstr *MI,
9255a5ac124SDimitry Andric bool ConsiderUnseenAsDef) {
9265a5ac124SDimitry Andric auto Cost = calcRegisterCost(MI, /*ConsiderSeen=*/true, ConsiderUnseenAsDef);
9275a5ac124SDimitry Andric for (const auto &RPIdAndCost : Cost) {
9285a5ac124SDimitry Andric unsigned Class = RPIdAndCost.first;
9295a5ac124SDimitry Andric if (static_cast<int>(RegPressure[Class]) < -RPIdAndCost.second)
9305a5ac124SDimitry Andric RegPressure[Class] = 0;
9315a5ac124SDimitry Andric else
9325a5ac124SDimitry Andric RegPressure[Class] += RPIdAndCost.second;
9335a5ac124SDimitry Andric }
9345a5ac124SDimitry Andric }
935cf099d11SDimitry Andric
936dd58ef01SDimitry Andric /// Calculate the additional register pressure that the registers used in MI
937dd58ef01SDimitry Andric /// cause.
938dd58ef01SDimitry Andric ///
939dd58ef01SDimitry Andric /// If 'ConsiderSeen' is true, updates 'RegSeen' and uses the information to
940dd58ef01SDimitry Andric /// figure out which usages are live-ins.
941dd58ef01SDimitry Andric /// FIXME: Figure out a way to consider 'RegSeen' from all code paths.
9425a5ac124SDimitry Andric DenseMap<unsigned, int>
calcRegisterCost(const MachineInstr * MI,bool ConsiderSeen,bool ConsiderUnseenAsDef)943eb11fae6SDimitry Andric MachineLICMBase::calcRegisterCost(const MachineInstr *MI, bool ConsiderSeen,
9445a5ac124SDimitry Andric bool ConsiderUnseenAsDef) {
9455a5ac124SDimitry Andric DenseMap<unsigned, int> Cost;
9465a5ac124SDimitry Andric if (MI->isImplicitDef())
9475a5ac124SDimitry Andric return Cost;
948cf099d11SDimitry Andric for (unsigned i = 0, e = MI->getDesc().getNumOperands(); i != e; ++i) {
949cf099d11SDimitry Andric const MachineOperand &MO = MI->getOperand(i);
950cf099d11SDimitry Andric if (!MO.isReg() || MO.isImplicit())
951cf099d11SDimitry Andric continue;
9521d5ae102SDimitry Andric Register Reg = MO.getReg();
953e3b55780SDimitry Andric if (!Reg.isVirtual())
954cf099d11SDimitry Andric continue;
955cf099d11SDimitry Andric
9565a5ac124SDimitry Andric // FIXME: It seems bad to use RegSeen only for some of these calculations.
9575a5ac124SDimitry Andric bool isNew = ConsiderSeen ? RegSeen.insert(Reg).second : false;
9585a5ac124SDimitry Andric const TargetRegisterClass *RC = MRI->getRegClass(Reg);
959cf099d11SDimitry Andric
9605a5ac124SDimitry Andric RegClassWeight W = TRI->getRegClassWeight(RC);
9615a5ac124SDimitry Andric int RCCost = 0;
9625a5ac124SDimitry Andric if (MO.isDef())
9635a5ac124SDimitry Andric RCCost = W.RegWeight;
9645a5ac124SDimitry Andric else {
9655a5ac124SDimitry Andric bool isKill = isOperandKill(MO, MRI);
9665a5ac124SDimitry Andric if (isNew && !isKill && ConsiderUnseenAsDef)
9675a5ac124SDimitry Andric // Haven't seen this, it must be a livein.
9685a5ac124SDimitry Andric RCCost = W.RegWeight;
9695a5ac124SDimitry Andric else if (!isNew && isKill)
9705a5ac124SDimitry Andric RCCost = -W.RegWeight;
971cf099d11SDimitry Andric }
9725a5ac124SDimitry Andric if (RCCost == 0)
9735a5ac124SDimitry Andric continue;
9745a5ac124SDimitry Andric const int *PS = TRI->getRegClassPressureSets(RC);
9755a5ac124SDimitry Andric for (; *PS != -1; ++PS) {
9767fa27ce4SDimitry Andric if (!Cost.contains(*PS))
9775a5ac124SDimitry Andric Cost[*PS] = RCCost;
9785a5ac124SDimitry Andric else
9795a5ac124SDimitry Andric Cost[*PS] += RCCost;
9805a5ac124SDimitry Andric }
9815a5ac124SDimitry Andric }
9825a5ac124SDimitry Andric return Cost;
983d39c594dSDimitry Andric }
984009b1c42SEd Schouten
985dd58ef01SDimitry Andric /// Return true if this machine instruction loads from global offset table or
986dd58ef01SDimitry Andric /// constant pool.
mayLoadFromGOTOrConstantPool(MachineInstr & MI)987dd58ef01SDimitry Andric static bool mayLoadFromGOTOrConstantPool(MachineInstr &MI) {
98863faed5bSDimitry Andric assert(MI.mayLoad() && "Expected MI that loads!");
989dd58ef01SDimitry Andric
990dd58ef01SDimitry Andric // If we lost memory operands, conservatively assume that the instruction
991dd58ef01SDimitry Andric // reads from everything..
992dd58ef01SDimitry Andric if (MI.memoperands_empty())
993dd58ef01SDimitry Andric return true;
994dd58ef01SDimitry Andric
995050e163aSDimitry Andric for (MachineMemOperand *MemOp : MI.memoperands())
996050e163aSDimitry Andric if (const PseudoSourceValue *PSV = MemOp->getPseudoValue())
997dd58ef01SDimitry Andric if (PSV->isGOT() || PSV->isConstantPool())
99863faed5bSDimitry Andric return true;
999050e163aSDimitry Andric
100063faed5bSDimitry Andric return false;
100163faed5bSDimitry Andric }
100263faed5bSDimitry Andric
1003eb11fae6SDimitry Andric // This function iterates through all the operands of the input store MI and
1004eb11fae6SDimitry Andric // checks that each register operand statisfies isCallerPreservedPhysReg.
1005eb11fae6SDimitry Andric // This means, the value being stored and the address where it is being stored
1006eb11fae6SDimitry Andric // is constant throughout the body of the function (not including prologue and
1007eb11fae6SDimitry Andric // epilogue). When called with an MI that isn't a store, it returns false.
1008eb11fae6SDimitry Andric // A future improvement can be to check if the store registers are constant
1009eb11fae6SDimitry Andric // throughout the loop rather than throughout the funtion.
isInvariantStore(const MachineInstr & MI,const TargetRegisterInfo * TRI,const MachineRegisterInfo * MRI)1010eb11fae6SDimitry Andric static bool isInvariantStore(const MachineInstr &MI,
1011eb11fae6SDimitry Andric const TargetRegisterInfo *TRI,
1012eb11fae6SDimitry Andric const MachineRegisterInfo *MRI) {
1013eb11fae6SDimitry Andric
1014eb11fae6SDimitry Andric bool FoundCallerPresReg = false;
1015eb11fae6SDimitry Andric if (!MI.mayStore() || MI.hasUnmodeledSideEffects() ||
1016eb11fae6SDimitry Andric (MI.getNumOperands() == 0))
1017eb11fae6SDimitry Andric return false;
1018eb11fae6SDimitry Andric
1019eb11fae6SDimitry Andric // Check that all register operands are caller-preserved physical registers.
1020eb11fae6SDimitry Andric for (const MachineOperand &MO : MI.operands()) {
1021eb11fae6SDimitry Andric if (MO.isReg()) {
10221d5ae102SDimitry Andric Register Reg = MO.getReg();
1023eb11fae6SDimitry Andric // If operand is a virtual register, check if it comes from a copy of a
1024eb11fae6SDimitry Andric // physical register.
1025e3b55780SDimitry Andric if (Reg.isVirtual())
1026eb11fae6SDimitry Andric Reg = TRI->lookThruCopyLike(MO.getReg(), MRI);
1027e3b55780SDimitry Andric if (Reg.isVirtual())
1028eb11fae6SDimitry Andric return false;
1029b60736ecSDimitry Andric if (!TRI->isCallerPreservedPhysReg(Reg.asMCReg(), *MI.getMF()))
1030eb11fae6SDimitry Andric return false;
1031eb11fae6SDimitry Andric else
1032eb11fae6SDimitry Andric FoundCallerPresReg = true;
1033eb11fae6SDimitry Andric } else if (!MO.isImm()) {
1034eb11fae6SDimitry Andric return false;
1035eb11fae6SDimitry Andric }
1036eb11fae6SDimitry Andric }
1037eb11fae6SDimitry Andric return FoundCallerPresReg;
1038eb11fae6SDimitry Andric }
1039eb11fae6SDimitry Andric
1040eb11fae6SDimitry Andric // Return true if the input MI is a copy instruction that feeds an invariant
1041eb11fae6SDimitry Andric // store instruction. This means that the src of the copy has to satisfy
1042eb11fae6SDimitry Andric // isCallerPreservedPhysReg and atleast one of it's users should satisfy
1043eb11fae6SDimitry Andric // isInvariantStore.
isCopyFeedingInvariantStore(const MachineInstr & MI,const MachineRegisterInfo * MRI,const TargetRegisterInfo * TRI)1044eb11fae6SDimitry Andric static bool isCopyFeedingInvariantStore(const MachineInstr &MI,
1045eb11fae6SDimitry Andric const MachineRegisterInfo *MRI,
1046eb11fae6SDimitry Andric const TargetRegisterInfo *TRI) {
1047eb11fae6SDimitry Andric
1048eb11fae6SDimitry Andric // FIXME: If targets would like to look through instructions that aren't
1049eb11fae6SDimitry Andric // pure copies, this can be updated to a query.
1050eb11fae6SDimitry Andric if (!MI.isCopy())
1051eb11fae6SDimitry Andric return false;
1052eb11fae6SDimitry Andric
1053eb11fae6SDimitry Andric const MachineFunction *MF = MI.getMF();
1054eb11fae6SDimitry Andric // Check that we are copying a constant physical register.
10551d5ae102SDimitry Andric Register CopySrcReg = MI.getOperand(1).getReg();
1056e3b55780SDimitry Andric if (CopySrcReg.isVirtual())
1057eb11fae6SDimitry Andric return false;
1058eb11fae6SDimitry Andric
1059b60736ecSDimitry Andric if (!TRI->isCallerPreservedPhysReg(CopySrcReg.asMCReg(), *MF))
1060eb11fae6SDimitry Andric return false;
1061eb11fae6SDimitry Andric
10621d5ae102SDimitry Andric Register CopyDstReg = MI.getOperand(0).getReg();
1063eb11fae6SDimitry Andric // Check if any of the uses of the copy are invariant stores.
1064e3b55780SDimitry Andric assert(CopyDstReg.isVirtual() && "copy dst is not a virtual reg");
1065eb11fae6SDimitry Andric
1066eb11fae6SDimitry Andric for (MachineInstr &UseMI : MRI->use_instructions(CopyDstReg)) {
1067eb11fae6SDimitry Andric if (UseMI.mayStore() && isInvariantStore(UseMI, TRI, MRI))
1068eb11fae6SDimitry Andric return true;
1069eb11fae6SDimitry Andric }
1070eb11fae6SDimitry Andric return false;
1071eb11fae6SDimitry Andric }
1072eb11fae6SDimitry Andric
1073dd58ef01SDimitry Andric /// Returns true if the instruction may be a suitable candidate for LICM.
1074dd58ef01SDimitry Andric /// e.g. If the instruction is a call, then it's obviously not safe to hoist it.
IsLICMCandidate(MachineInstr & I,MachineLoop * CurLoop)1075b1c73532SDimitry Andric bool MachineLICMBase::IsLICMCandidate(MachineInstr &I, MachineLoop *CurLoop) {
107666e41e3cSRoman Divacky // Check if it's safe to move the instruction.
1077b1c73532SDimitry Andric bool DontMoveAcrossStore = !HoistConstLoads || !AllowedToHoistLoads[CurLoop];
1078eb11fae6SDimitry Andric if ((!I.isSafeToMove(AA, DontMoveAcrossStore)) &&
1079eb11fae6SDimitry Andric !(HoistConstStores && isInvariantStore(I, TRI, MRI))) {
1080b60736ecSDimitry Andric LLVM_DEBUG(dbgs() << "LICM: Instruction not safe to move.\n");
1081009b1c42SEd Schouten return false;
1082eb11fae6SDimitry Andric }
1083009b1c42SEd Schouten
1084344a3780SDimitry Andric // If it is a load then check if it is guaranteed to execute by making sure
1085344a3780SDimitry Andric // that it dominates all exiting blocks. If it doesn't, then there is a path
1086344a3780SDimitry Andric // out of the loop which does not execute this load, so we can't hoist it.
1087344a3780SDimitry Andric // Loads from constant memory are safe to speculate, for example indexed load
1088344a3780SDimitry Andric // from a jump table.
108930815c53SDimitry Andric // Stores and side effects are already checked by isSafeToMove.
1090dd58ef01SDimitry Andric if (I.mayLoad() && !mayLoadFromGOTOrConstantPool(I) &&
1091b1c73532SDimitry Andric !IsGuaranteedToExecute(I.getParent(), CurLoop)) {
1092b60736ecSDimitry Andric LLVM_DEBUG(dbgs() << "LICM: Load not guaranteed to execute.\n");
1093b60736ecSDimitry Andric return false;
1094b60736ecSDimitry Andric }
1095b60736ecSDimitry Andric
1096b60736ecSDimitry Andric // Convergent attribute has been used on operations that involve inter-thread
1097b60736ecSDimitry Andric // communication which results are implicitly affected by the enclosing
1098b60736ecSDimitry Andric // control flows. It is not safe to hoist or sink such operations across
1099b60736ecSDimitry Andric // control flow.
1100b60736ecSDimitry Andric if (I.isConvergent())
110130815c53SDimitry Andric return false;
110230815c53SDimitry Andric
1103145449b1SDimitry Andric if (!TII->shouldHoist(I, CurLoop))
1104145449b1SDimitry Andric return false;
1105145449b1SDimitry Andric
1106d7f7719eSRoman Divacky return true;
1107d7f7719eSRoman Divacky }
1108d7f7719eSRoman Divacky
1109dd58ef01SDimitry Andric /// Returns true if the instruction is loop invariant.
IsLoopInvariantInst(MachineInstr & I,MachineLoop * CurLoop)1110b1c73532SDimitry Andric bool MachineLICMBase::IsLoopInvariantInst(MachineInstr &I,
1111b1c73532SDimitry Andric MachineLoop *CurLoop) {
1112b1c73532SDimitry Andric if (!IsLICMCandidate(I, CurLoop)) {
1113b60736ecSDimitry Andric LLVM_DEBUG(dbgs() << "LICM: Instruction not a LICM candidate\n");
111467a71b31SRoman Divacky return false;
111559850d08SRoman Divacky }
1116b60736ecSDimitry Andric return CurLoop->isLoopInvariant(I);
1117009b1c42SEd Schouten }
1118009b1c42SEd Schouten
1119dd58ef01SDimitry Andric /// Return true if the specified instruction is used by a phi node and hoisting
1120dd58ef01SDimitry Andric /// it could cause a copy to be inserted.
HasLoopPHIUse(const MachineInstr * MI,MachineLoop * CurLoop)1121b1c73532SDimitry Andric bool MachineLICMBase::HasLoopPHIUse(const MachineInstr *MI,
1122b1c73532SDimitry Andric MachineLoop *CurLoop) {
112363faed5bSDimitry Andric SmallVector<const MachineInstr *, 8> Work(1, MI);
112463faed5bSDimitry Andric do {
112563faed5bSDimitry Andric MI = Work.pop_back_val();
11267fa27ce4SDimitry Andric for (const MachineOperand &MO : MI->all_defs()) {
11271d5ae102SDimitry Andric Register Reg = MO.getReg();
1128e3b55780SDimitry Andric if (!Reg.isVirtual())
112963faed5bSDimitry Andric continue;
11305ca98fd9SDimitry Andric for (MachineInstr &UseMI : MRI->use_instructions(Reg)) {
113163faed5bSDimitry Andric // A PHI may cause a copy to be inserted.
11325ca98fd9SDimitry Andric if (UseMI.isPHI()) {
113363faed5bSDimitry Andric // A PHI inside the loop causes a copy because the live range of Reg is
113463faed5bSDimitry Andric // extended across the PHI.
11355ca98fd9SDimitry Andric if (CurLoop->contains(&UseMI))
1136009b1c42SEd Schouten return true;
113763faed5bSDimitry Andric // A PHI in an exit block can cause a copy to be inserted if the PHI
113863faed5bSDimitry Andric // has multiple predecessors in the loop with different values.
113963faed5bSDimitry Andric // For now, approximate by rejecting all exit blocks.
1140b1c73532SDimitry Andric if (isExitBlock(CurLoop, UseMI.getParent()))
11416b943ff3SDimitry Andric return true;
114263faed5bSDimitry Andric continue;
114363faed5bSDimitry Andric }
114463faed5bSDimitry Andric // Look past copies as well.
11455ca98fd9SDimitry Andric if (UseMI.isCopy() && CurLoop->contains(&UseMI))
11465ca98fd9SDimitry Andric Work.push_back(&UseMI);
11476b943ff3SDimitry Andric }
1148009b1c42SEd Schouten }
114963faed5bSDimitry Andric } while (!Work.empty());
1150009b1c42SEd Schouten return false;
1151009b1c42SEd Schouten }
1152009b1c42SEd Schouten
1153dd58ef01SDimitry Andric /// Compute operand latency between a def of 'Reg' and an use in the current
1154dd58ef01SDimitry Andric /// loop, return true if the target considered it high.
HasHighOperandLatency(MachineInstr & MI,unsigned DefIdx,Register Reg,MachineLoop * CurLoop) const1155b60736ecSDimitry Andric bool MachineLICMBase::HasHighOperandLatency(MachineInstr &MI, unsigned DefIdx,
1156b1c73532SDimitry Andric Register Reg,
1157b1c73532SDimitry Andric MachineLoop *CurLoop) const {
11583a0822f0SDimitry Andric if (MRI->use_nodbg_empty(Reg))
1159cf099d11SDimitry Andric return false;
1160cf099d11SDimitry Andric
11615ca98fd9SDimitry Andric for (MachineInstr &UseMI : MRI->use_nodbg_instructions(Reg)) {
11625ca98fd9SDimitry Andric if (UseMI.isCopyLike())
1163cf099d11SDimitry Andric continue;
11645ca98fd9SDimitry Andric if (!CurLoop->contains(UseMI.getParent()))
1165cf099d11SDimitry Andric continue;
11665ca98fd9SDimitry Andric for (unsigned i = 0, e = UseMI.getNumOperands(); i != e; ++i) {
11675ca98fd9SDimitry Andric const MachineOperand &MO = UseMI.getOperand(i);
1168cf099d11SDimitry Andric if (!MO.isReg() || !MO.isUse())
1169cf099d11SDimitry Andric continue;
11701d5ae102SDimitry Andric Register MOReg = MO.getReg();
1171cf099d11SDimitry Andric if (MOReg != Reg)
1172cf099d11SDimitry Andric continue;
1173cf099d11SDimitry Andric
117401095a5dSDimitry Andric if (TII->hasHighOperandLatency(SchedModel, MRI, MI, DefIdx, UseMI, i))
1175cf099d11SDimitry Andric return true;
1176cf099d11SDimitry Andric }
1177cf099d11SDimitry Andric
1178cf099d11SDimitry Andric // Only look at the first in loop use.
1179cf099d11SDimitry Andric break;
1180cf099d11SDimitry Andric }
1181cf099d11SDimitry Andric
1182cf099d11SDimitry Andric return false;
1183cf099d11SDimitry Andric }
1184cf099d11SDimitry Andric
1185dd58ef01SDimitry Andric /// Return true if the instruction is marked "cheap" or the operand latency
1186dd58ef01SDimitry Andric /// between its def and a use is one or less.
IsCheapInstruction(MachineInstr & MI) const1187eb11fae6SDimitry Andric bool MachineLICMBase::IsCheapInstruction(MachineInstr &MI) const {
118801095a5dSDimitry Andric if (TII->isAsCheapAsAMove(MI) || MI.isCopyLike())
1189cf099d11SDimitry Andric return true;
1190cf099d11SDimitry Andric
1191cf099d11SDimitry Andric bool isCheap = false;
1192cf099d11SDimitry Andric unsigned NumDefs = MI.getDesc().getNumDefs();
1193cf099d11SDimitry Andric for (unsigned i = 0, e = MI.getNumOperands(); NumDefs && i != e; ++i) {
1194cf099d11SDimitry Andric MachineOperand &DefMO = MI.getOperand(i);
1195cf099d11SDimitry Andric if (!DefMO.isReg() || !DefMO.isDef())
1196cf099d11SDimitry Andric continue;
1197cf099d11SDimitry Andric --NumDefs;
11981d5ae102SDimitry Andric Register Reg = DefMO.getReg();
1199e3b55780SDimitry Andric if (Reg.isPhysical())
1200cf099d11SDimitry Andric continue;
1201cf099d11SDimitry Andric
120201095a5dSDimitry Andric if (!TII->hasLowDefLatency(SchedModel, MI, i))
1203cf099d11SDimitry Andric return false;
1204cf099d11SDimitry Andric isCheap = true;
1205cf099d11SDimitry Andric }
1206cf099d11SDimitry Andric
1207cf099d11SDimitry Andric return isCheap;
1208cf099d11SDimitry Andric }
1209cf099d11SDimitry Andric
1210dd58ef01SDimitry Andric /// Visit BBs from header to current BB, check if hoisting an instruction of the
1211dd58ef01SDimitry Andric /// given cost matrix can cause high register pressure.
1212eb11fae6SDimitry Andric bool
CanCauseHighRegPressure(const DenseMap<unsigned,int> & Cost,bool CheapInstr)1213eb11fae6SDimitry Andric MachineLICMBase::CanCauseHighRegPressure(const DenseMap<unsigned, int>& Cost,
121463faed5bSDimitry Andric bool CheapInstr) {
12155a5ac124SDimitry Andric for (const auto &RPIdAndCost : Cost) {
12165a5ac124SDimitry Andric if (RPIdAndCost.second <= 0)
1217cf099d11SDimitry Andric continue;
1218cf099d11SDimitry Andric
12195a5ac124SDimitry Andric unsigned Class = RPIdAndCost.first;
12205a5ac124SDimitry Andric int Limit = RegLimit[Class];
122163faed5bSDimitry Andric
122263faed5bSDimitry Andric // Don't hoist cheap instructions if they would increase register pressure,
122363faed5bSDimitry Andric // even if we're under the limit.
122467c32a98SDimitry Andric if (CheapInstr && !HoistCheapInsts)
122563faed5bSDimitry Andric return true;
122663faed5bSDimitry Andric
12275a5ac124SDimitry Andric for (const auto &RP : BackTrace)
12285a5ac124SDimitry Andric if (static_cast<int>(RP[Class]) + RPIdAndCost.second >= Limit)
1229cf099d11SDimitry Andric return true;
1230cf099d11SDimitry Andric }
1231cf099d11SDimitry Andric
1232cf099d11SDimitry Andric return false;
1233cf099d11SDimitry Andric }
1234cf099d11SDimitry Andric
1235dd58ef01SDimitry Andric /// Traverse the back trace from header to the current block and update their
1236dd58ef01SDimitry Andric /// register pressures to reflect the effect of hoisting MI from the current
1237dd58ef01SDimitry Andric /// block to the preheader.
UpdateBackTraceRegPressure(const MachineInstr * MI)1238eb11fae6SDimitry Andric void MachineLICMBase::UpdateBackTraceRegPressure(const MachineInstr *MI) {
1239cf099d11SDimitry Andric // First compute the 'cost' of the instruction, i.e. its contribution
1240cf099d11SDimitry Andric // to register pressure.
12415a5ac124SDimitry Andric auto Cost = calcRegisterCost(MI, /*ConsiderSeen=*/false,
12425a5ac124SDimitry Andric /*ConsiderUnseenAsDef=*/false);
1243cf099d11SDimitry Andric
1244cf099d11SDimitry Andric // Update register pressure of blocks from loop header to current block.
12455a5ac124SDimitry Andric for (auto &RP : BackTrace)
12465a5ac124SDimitry Andric for (const auto &RPIdAndCost : Cost)
12475a5ac124SDimitry Andric RP[RPIdAndCost.first] += RPIdAndCost.second;
124806f9d401SRoman Divacky }
124906f9d401SRoman Divacky
1250dd58ef01SDimitry Andric /// Return true if it is potentially profitable to hoist the given loop
1251dd58ef01SDimitry Andric /// invariant.
IsProfitableToHoist(MachineInstr & MI,MachineLoop * CurLoop)1252b1c73532SDimitry Andric bool MachineLICMBase::IsProfitableToHoist(MachineInstr &MI,
1253b1c73532SDimitry Andric MachineLoop *CurLoop) {
1254cf099d11SDimitry Andric if (MI.isImplicitDef())
1255cf099d11SDimitry Andric return true;
1256cf099d11SDimitry Andric
125763faed5bSDimitry Andric // Besides removing computation from the loop, hoisting an instruction has
125863faed5bSDimitry Andric // these effects:
125963faed5bSDimitry Andric //
126063faed5bSDimitry Andric // - The value defined by the instruction becomes live across the entire
126163faed5bSDimitry Andric // loop. This increases register pressure in the loop.
126263faed5bSDimitry Andric //
126363faed5bSDimitry Andric // - If the value is used by a PHI in the loop, a copy will be required for
126463faed5bSDimitry Andric // lowering the PHI after extending the live range.
126563faed5bSDimitry Andric //
126663faed5bSDimitry Andric // - When hoisting the last use of a value in the loop, that value no longer
126763faed5bSDimitry Andric // needs to be live in the loop. This lowers register pressure in the loop.
126863faed5bSDimitry Andric
1269eb11fae6SDimitry Andric if (HoistConstStores && isCopyFeedingInvariantStore(MI, MRI, TRI))
1270eb11fae6SDimitry Andric return true;
1271eb11fae6SDimitry Andric
127263faed5bSDimitry Andric bool CheapInstr = IsCheapInstruction(MI);
1273b1c73532SDimitry Andric bool CreatesCopy = HasLoopPHIUse(&MI, CurLoop);
127463faed5bSDimitry Andric
127563faed5bSDimitry Andric // Don't hoist a cheap instruction if it would create a copy in the loop.
127663faed5bSDimitry Andric if (CheapInstr && CreatesCopy) {
1277eb11fae6SDimitry Andric LLVM_DEBUG(dbgs() << "Won't hoist cheap instr with loop PHI use: " << MI);
1278cf099d11SDimitry Andric return false;
127963faed5bSDimitry Andric }
128063faed5bSDimitry Andric
1281c0981da4SDimitry Andric // Rematerializable instructions should always be hoisted providing the
1282c0981da4SDimitry Andric // register allocator can just pull them down again when needed.
12834b4fe385SDimitry Andric if (isTriviallyReMaterializable(MI))
128463faed5bSDimitry Andric return true;
128563faed5bSDimitry Andric
1286cf099d11SDimitry Andric // FIXME: If there are long latency loop-invariant instructions inside the
1287cf099d11SDimitry Andric // loop at this point, why didn't the optimizer's LICM hoist them?
1288cf099d11SDimitry Andric for (unsigned i = 0, e = MI.getDesc().getNumOperands(); i != e; ++i) {
1289cf099d11SDimitry Andric const MachineOperand &MO = MI.getOperand(i);
1290cf099d11SDimitry Andric if (!MO.isReg() || MO.isImplicit())
1291cf099d11SDimitry Andric continue;
12921d5ae102SDimitry Andric Register Reg = MO.getReg();
1293e3b55780SDimitry Andric if (!Reg.isVirtual())
1294cf099d11SDimitry Andric continue;
1295b1c73532SDimitry Andric if (MO.isDef() && HasHighOperandLatency(MI, i, Reg, CurLoop)) {
1296eb11fae6SDimitry Andric LLVM_DEBUG(dbgs() << "Hoist High Latency: " << MI);
1297cf099d11SDimitry Andric ++NumHighLatency;
1298cf099d11SDimitry Andric return true;
1299cf099d11SDimitry Andric }
1300cf099d11SDimitry Andric }
13015a5ac124SDimitry Andric
13025a5ac124SDimitry Andric // Estimate register pressure to determine whether to LICM the instruction.
13035a5ac124SDimitry Andric // In low register pressure situation, we can be more aggressive about
13045a5ac124SDimitry Andric // hoisting. Also, favors hoisting long latency instructions even in
13055a5ac124SDimitry Andric // moderately high pressure situation.
13065a5ac124SDimitry Andric // Cheap instructions will only be hoisted if they don't increase register
13075a5ac124SDimitry Andric // pressure at all.
13085a5ac124SDimitry Andric auto Cost = calcRegisterCost(&MI, /*ConsiderSeen=*/false,
13095a5ac124SDimitry Andric /*ConsiderUnseenAsDef=*/false);
1310cf099d11SDimitry Andric
1311cf099d11SDimitry Andric // Visit BBs from header to current BB, if hoisting this doesn't cause
1312cf099d11SDimitry Andric // high register pressure, then it's safe to proceed.
131363faed5bSDimitry Andric if (!CanCauseHighRegPressure(Cost, CheapInstr)) {
1314eb11fae6SDimitry Andric LLVM_DEBUG(dbgs() << "Hoist non-reg-pressure: " << MI);
1315cf099d11SDimitry Andric ++NumLowRP;
1316cf099d11SDimitry Andric return true;
1317cf099d11SDimitry Andric }
1318cf099d11SDimitry Andric
131963faed5bSDimitry Andric // Don't risk increasing register pressure if it would create copies.
132063faed5bSDimitry Andric if (CreatesCopy) {
1321eb11fae6SDimitry Andric LLVM_DEBUG(dbgs() << "Won't hoist instr with loop PHI use: " << MI);
132263faed5bSDimitry Andric return false;
132363faed5bSDimitry Andric }
132463faed5bSDimitry Andric
132530815c53SDimitry Andric // Do not "speculate" in high register pressure situation. If an
132630815c53SDimitry Andric // instruction is not guaranteed to be executed in the loop, it's best to be
132730815c53SDimitry Andric // conservative.
132830815c53SDimitry Andric if (AvoidSpeculation &&
1329b1c73532SDimitry Andric (!IsGuaranteedToExecute(MI.getParent(), CurLoop) && !MayCSE(&MI))) {
1330eb11fae6SDimitry Andric LLVM_DEBUG(dbgs() << "Won't speculate: " << MI);
1331009b1c42SEd Schouten return false;
133206f9d401SRoman Divacky }
1333009b1c42SEd Schouten
1334b1c73532SDimitry Andric // If we have a COPY with other uses in the loop, hoist to allow the users to
1335b1c73532SDimitry Andric // also be hoisted.
1336ac9a064cSDimitry Andric // TODO: Handle all isCopyLike?
1337ac9a064cSDimitry Andric if (MI.isCopy() || MI.isRegSequence()) {
1338ac9a064cSDimitry Andric Register DefReg = MI.getOperand(0).getReg();
1339ac9a064cSDimitry Andric if (DefReg.isVirtual() &&
1340ac9a064cSDimitry Andric all_of(MI.uses(),
1341ac9a064cSDimitry Andric [this](const MachineOperand &UseOp) {
1342ac9a064cSDimitry Andric return !UseOp.isReg() || UseOp.getReg().isVirtual() ||
1343ac9a064cSDimitry Andric MRI->isConstantPhysReg(UseOp.getReg());
1344ac9a064cSDimitry Andric }) &&
1345b1c73532SDimitry Andric IsLoopInvariantInst(MI, CurLoop) &&
1346ac9a064cSDimitry Andric any_of(MRI->use_nodbg_instructions(DefReg),
1347ac9a064cSDimitry Andric [&CurLoop, this, DefReg, Cost](MachineInstr &UseMI) {
1348ac9a064cSDimitry Andric if (!CurLoop->contains(&UseMI))
1349ac9a064cSDimitry Andric return false;
1350ac9a064cSDimitry Andric
1351ac9a064cSDimitry Andric // COPY is a cheap instruction, but if moving it won't cause
1352ac9a064cSDimitry Andric // high RP we're fine to hoist it even if the user can't be
1353ac9a064cSDimitry Andric // hoisted later Otherwise we want to check the user if it's
1354ac9a064cSDimitry Andric // hoistable
1355ac9a064cSDimitry Andric if (CanCauseHighRegPressure(Cost, false) &&
1356ac9a064cSDimitry Andric !CurLoop->isLoopInvariant(UseMI, DefReg))
1357ac9a064cSDimitry Andric return false;
1358ac9a064cSDimitry Andric
1359ac9a064cSDimitry Andric return true;
1360b1c73532SDimitry Andric }))
1361b1c73532SDimitry Andric return true;
1362ac9a064cSDimitry Andric }
1363b1c73532SDimitry Andric
136463faed5bSDimitry Andric // High register pressure situation, only hoist if the instruction is going
136563faed5bSDimitry Andric // to be remat'ed.
13664b4fe385SDimitry Andric if (!isTriviallyReMaterializable(MI) &&
13674b4fe385SDimitry Andric !MI.isDereferenceableInvariantLoad()) {
1368eb11fae6SDimitry Andric LLVM_DEBUG(dbgs() << "Can't remat / high reg-pressure: " << MI);
1369009b1c42SEd Schouten return false;
1370009b1c42SEd Schouten }
1371009b1c42SEd Schouten
1372009b1c42SEd Schouten return true;
1373009b1c42SEd Schouten }
1374009b1c42SEd Schouten
1375dd58ef01SDimitry Andric /// Unfold a load from the given machineinstr if the load itself could be
1376dd58ef01SDimitry Andric /// hoisted. Return the unfolded and hoistable load, or null if the load
1377dd58ef01SDimitry Andric /// couldn't be unfolded or if it wouldn't be hoistable.
ExtractHoistableLoad(MachineInstr * MI,MachineLoop * CurLoop)1378b1c73532SDimitry Andric MachineInstr *MachineLICMBase::ExtractHoistableLoad(MachineInstr *MI,
1379b1c73532SDimitry Andric MachineLoop *CurLoop) {
1380cf099d11SDimitry Andric // Don't unfold simple loads.
138163faed5bSDimitry Andric if (MI->canFoldAsLoad())
13825ca98fd9SDimitry Andric return nullptr;
1383cf099d11SDimitry Andric
138436bf506aSRoman Divacky // If not, we may be able to unfold a load and hoist that.
138536bf506aSRoman Divacky // First test whether the instruction is loading from an amenable
138636bf506aSRoman Divacky // memory location.
13874b4fe385SDimitry Andric if (!MI->isDereferenceableInvariantLoad())
13885ca98fd9SDimitry Andric return nullptr;
138906f9d401SRoman Divacky
139036bf506aSRoman Divacky // Next determine the register class for a temporary register.
139136bf506aSRoman Divacky unsigned LoadRegIndex;
139236bf506aSRoman Divacky unsigned NewOpc =
139336bf506aSRoman Divacky TII->getOpcodeAfterMemoryUnfold(MI->getOpcode(),
139436bf506aSRoman Divacky /*UnfoldLoad=*/true,
139536bf506aSRoman Divacky /*UnfoldStore=*/false,
139636bf506aSRoman Divacky &LoadRegIndex);
13975ca98fd9SDimitry Andric if (NewOpc == 0) return nullptr;
1398411bd29eSDimitry Andric const MCInstrDesc &MID = TII->get(NewOpc);
1399044eb2f6SDimitry Andric MachineFunction &MF = *MI->getMF();
140058b69754SDimitry Andric const TargetRegisterClass *RC = TII->getRegClass(MID, LoadRegIndex, TRI, MF);
140136bf506aSRoman Divacky // Ok, we're unfolding. Create a temporary register and do the unfold.
14021d5ae102SDimitry Andric Register Reg = MRI->createVirtualRegister(RC);
140306f9d401SRoman Divacky
140436bf506aSRoman Divacky SmallVector<MachineInstr *, 2> NewMIs;
140501095a5dSDimitry Andric bool Success = TII->unfoldMemoryOperand(MF, *MI, Reg,
140601095a5dSDimitry Andric /*UnfoldLoad=*/true,
140701095a5dSDimitry Andric /*UnfoldStore=*/false, NewMIs);
140836bf506aSRoman Divacky (void)Success;
140936bf506aSRoman Divacky assert(Success &&
141036bf506aSRoman Divacky "unfoldMemoryOperand failed when getOpcodeAfterMemoryUnfold "
141136bf506aSRoman Divacky "succeeded!");
141236bf506aSRoman Divacky assert(NewMIs.size() == 2 &&
141336bf506aSRoman Divacky "Unfolded a load into multiple instructions!");
141436bf506aSRoman Divacky MachineBasicBlock *MBB = MI->getParent();
141563faed5bSDimitry Andric MachineBasicBlock::iterator Pos = MI;
141663faed5bSDimitry Andric MBB->insert(Pos, NewMIs[0]);
141763faed5bSDimitry Andric MBB->insert(Pos, NewMIs[1]);
141836bf506aSRoman Divacky // If unfolding produced a load that wasn't loop-invariant or profitable to
141936bf506aSRoman Divacky // hoist, discard the new instructions and bail.
1420b1c73532SDimitry Andric if (!IsLoopInvariantInst(*NewMIs[0], CurLoop) ||
1421b1c73532SDimitry Andric !IsProfitableToHoist(*NewMIs[0], CurLoop)) {
142236bf506aSRoman Divacky NewMIs[0]->eraseFromParent();
142336bf506aSRoman Divacky NewMIs[1]->eraseFromParent();
14245ca98fd9SDimitry Andric return nullptr;
142536bf506aSRoman Divacky }
1426cf099d11SDimitry Andric
1427cf099d11SDimitry Andric // Update register pressure for the unfolded instruction.
1428cf099d11SDimitry Andric UpdateRegPressure(NewMIs[1]);
1429cf099d11SDimitry Andric
143036bf506aSRoman Divacky // Otherwise we successfully unfolded a load that we can hoist.
1431cfca06d7SDimitry Andric
1432cfca06d7SDimitry Andric // Update the call site info.
1433cfca06d7SDimitry Andric if (MI->shouldUpdateCallSiteInfo())
1434cfca06d7SDimitry Andric MF.eraseCallSiteInfo(MI);
1435cfca06d7SDimitry Andric
143636bf506aSRoman Divacky MI->eraseFromParent();
143736bf506aSRoman Divacky return NewMIs[0];
143836bf506aSRoman Divacky }
143936bf506aSRoman Divacky
1440dd58ef01SDimitry Andric /// Initialize the CSE map with instructions that are in the current loop
1441dd58ef01SDimitry Andric /// preheader that may become duplicates of instructions that are hoisted
1442dd58ef01SDimitry Andric /// out of the loop.
InitCSEMap(MachineBasicBlock * BB)1443eb11fae6SDimitry Andric void MachineLICMBase::InitCSEMap(MachineBasicBlock *BB) {
1444050e163aSDimitry Andric for (MachineInstr &MI : *BB)
1445b1c73532SDimitry Andric CSEMap[BB][MI.getOpcode()].push_back(&MI);
1446b1c73532SDimitry Andric }
1447b1c73532SDimitry Andric
1448b1c73532SDimitry Andric /// Initialize AllowedToHoistLoads with information about whether invariant
1449b1c73532SDimitry Andric /// loads can be moved outside a given loop
InitializeLoadsHoistableLoops()1450b1c73532SDimitry Andric void MachineLICMBase::InitializeLoadsHoistableLoops() {
1451b1c73532SDimitry Andric SmallVector<MachineLoop *, 8> Worklist(MLI->begin(), MLI->end());
1452b1c73532SDimitry Andric SmallVector<MachineLoop *, 8> LoopsInPreOrder;
1453b1c73532SDimitry Andric
1454b1c73532SDimitry Andric // Mark all loops as hoistable initially and prepare a list of loops in
1455b1c73532SDimitry Andric // pre-order DFS.
1456b1c73532SDimitry Andric while (!Worklist.empty()) {
1457b1c73532SDimitry Andric auto *L = Worklist.pop_back_val();
1458b1c73532SDimitry Andric AllowedToHoistLoads[L] = true;
1459b1c73532SDimitry Andric LoopsInPreOrder.push_back(L);
1460b1c73532SDimitry Andric Worklist.insert(Worklist.end(), L->getSubLoops().begin(),
1461b1c73532SDimitry Andric L->getSubLoops().end());
1462b1c73532SDimitry Andric }
1463b1c73532SDimitry Andric
1464b1c73532SDimitry Andric // Going from the innermost to outermost loops, check if a loop has
1465b1c73532SDimitry Andric // instructions preventing invariant load hoisting. If such instruction is
1466b1c73532SDimitry Andric // found, mark this loop and its parent as non-hoistable and continue
1467b1c73532SDimitry Andric // investigating the next loop.
1468b1c73532SDimitry Andric // Visiting in a reversed pre-ordered DFS manner
1469b1c73532SDimitry Andric // allows us to not process all the instructions of the outer loop if the
1470b1c73532SDimitry Andric // inner loop is proved to be non-load-hoistable.
1471b1c73532SDimitry Andric for (auto *Loop : reverse(LoopsInPreOrder)) {
1472b1c73532SDimitry Andric for (auto *MBB : Loop->blocks()) {
1473b1c73532SDimitry Andric // If this loop has already been marked as non-hoistable, skip it.
1474b1c73532SDimitry Andric if (!AllowedToHoistLoads[Loop])
1475b1c73532SDimitry Andric continue;
1476b1c73532SDimitry Andric for (auto &MI : *MBB) {
1477f56b67c4SDimitry Andric if (!MI.isLoadFoldBarrier() && !MI.mayStore() && !MI.isCall() &&
1478b1c73532SDimitry Andric !(MI.mayLoad() && MI.hasOrderedMemoryRef()))
1479b1c73532SDimitry Andric continue;
1480b1c73532SDimitry Andric for (MachineLoop *L = Loop; L != nullptr; L = L->getParentLoop())
1481b1c73532SDimitry Andric AllowedToHoistLoads[L] = false;
1482b1c73532SDimitry Andric break;
1483b1c73532SDimitry Andric }
1484b1c73532SDimitry Andric }
1485b1c73532SDimitry Andric }
148636bf506aSRoman Divacky }
148736bf506aSRoman Divacky
1488dd58ef01SDimitry Andric /// Find an instruction amount PrevMIs that is a duplicate of MI.
1489dd58ef01SDimitry Andric /// Return this instruction if it's found.
1490b60736ecSDimitry Andric MachineInstr *
LookForDuplicate(const MachineInstr * MI,std::vector<MachineInstr * > & PrevMIs)1491eb11fae6SDimitry Andric MachineLICMBase::LookForDuplicate(const MachineInstr *MI,
1492b60736ecSDimitry Andric std::vector<MachineInstr *> &PrevMIs) {
1493b60736ecSDimitry Andric for (MachineInstr *PrevMI : PrevMIs)
149401095a5dSDimitry Andric if (TII->produceSameValue(*MI, *PrevMI, (PreRegAlloc ? MRI : nullptr)))
149572cc5085SRoman Divacky return PrevMI;
1496050e163aSDimitry Andric
14975ca98fd9SDimitry Andric return nullptr;
149872cc5085SRoman Divacky }
149972cc5085SRoman Divacky
1500dd58ef01SDimitry Andric /// Given a LICM'ed instruction, look for an instruction on the preheader that
1501dd58ef01SDimitry Andric /// computes the same value. If it's found, do a RAU on with the definition of
1502dd58ef01SDimitry Andric /// the existing instruction rather than hoisting the instruction to the
1503dd58ef01SDimitry Andric /// preheader.
EliminateCSE(MachineInstr * MI,DenseMap<unsigned,std::vector<MachineInstr * >>::iterator & CI)1504b60736ecSDimitry Andric bool MachineLICMBase::EliminateCSE(
1505b60736ecSDimitry Andric MachineInstr *MI,
1506b60736ecSDimitry Andric DenseMap<unsigned, std::vector<MachineInstr *>>::iterator &CI) {
1507f3d15b0bSRoman Divacky // Do not CSE implicit_def so ProcessImplicitDefs can properly propagate
1508f3d15b0bSRoman Divacky // the undef property onto uses.
1509b1c73532SDimitry Andric if (MI->isImplicitDef())
1510b1c73532SDimitry Andric return false;
1511b1c73532SDimitry Andric
1512b1c73532SDimitry Andric // Do not CSE normal loads because between them could be store instructions
1513b1c73532SDimitry Andric // that change the loaded value
1514b1c73532SDimitry Andric if (MI->mayLoad() && !MI->isDereferenceableInvariantLoad())
1515907da171SRoman Divacky return false;
1516907da171SRoman Divacky
1517b60736ecSDimitry Andric if (MachineInstr *Dup = LookForDuplicate(MI, CI->second)) {
1518eb11fae6SDimitry Andric LLVM_DEBUG(dbgs() << "CSEing " << *MI << " with " << *Dup);
151967a71b31SRoman Divacky
152067a71b31SRoman Divacky // Replace virtual registers defined by MI by their counterparts defined
152167a71b31SRoman Divacky // by Dup.
152263faed5bSDimitry Andric SmallVector<unsigned, 2> Defs;
152372cc5085SRoman Divacky for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
152472cc5085SRoman Divacky const MachineOperand &MO = MI->getOperand(i);
152567a71b31SRoman Divacky
152667a71b31SRoman Divacky // Physical registers may not differ here.
1527e3b55780SDimitry Andric assert((!MO.isReg() || MO.getReg() == 0 || !MO.getReg().isPhysical() ||
152867a71b31SRoman Divacky MO.getReg() == Dup->getOperand(i).getReg()) &&
152967a71b31SRoman Divacky "Instructions with different phys regs are not identical!");
153067a71b31SRoman Divacky
1531e3b55780SDimitry Andric if (MO.isReg() && MO.isDef() && !MO.getReg().isPhysical())
153263faed5bSDimitry Andric Defs.push_back(i);
153363faed5bSDimitry Andric }
153463faed5bSDimitry Andric
153563faed5bSDimitry Andric SmallVector<const TargetRegisterClass*, 2> OrigRCs;
153663faed5bSDimitry Andric for (unsigned i = 0, e = Defs.size(); i != e; ++i) {
153763faed5bSDimitry Andric unsigned Idx = Defs[i];
15381d5ae102SDimitry Andric Register Reg = MI->getOperand(Idx).getReg();
15391d5ae102SDimitry Andric Register DupReg = Dup->getOperand(Idx).getReg();
154063faed5bSDimitry Andric OrigRCs.push_back(MRI->getRegClass(DupReg));
154163faed5bSDimitry Andric
154263faed5bSDimitry Andric if (!MRI->constrainRegClass(DupReg, MRI->getRegClass(Reg))) {
154363faed5bSDimitry Andric // Restore old RCs if more than one defs.
154463faed5bSDimitry Andric for (unsigned j = 0; j != i; ++j)
154563faed5bSDimitry Andric MRI->setRegClass(Dup->getOperand(Defs[j]).getReg(), OrigRCs[j]);
154663faed5bSDimitry Andric return false;
1547abdf259dSRoman Divacky }
154872cc5085SRoman Divacky }
154963faed5bSDimitry Andric
1550050e163aSDimitry Andric for (unsigned Idx : Defs) {
15511d5ae102SDimitry Andric Register Reg = MI->getOperand(Idx).getReg();
15521d5ae102SDimitry Andric Register DupReg = Dup->getOperand(Idx).getReg();
155363faed5bSDimitry Andric MRI->replaceRegWith(Reg, DupReg);
155463faed5bSDimitry Andric MRI->clearKillFlags(DupReg);
1555b60736ecSDimitry Andric // Clear Dup dead flag if any, we reuse it for Reg.
1556b60736ecSDimitry Andric if (!MRI->use_nodbg_empty(DupReg))
1557b60736ecSDimitry Andric Dup->getOperand(Idx).setIsDead(false);
155863faed5bSDimitry Andric }
155963faed5bSDimitry Andric
156072cc5085SRoman Divacky MI->eraseFromParent();
156172cc5085SRoman Divacky ++NumCSEed;
156272cc5085SRoman Divacky return true;
156372cc5085SRoman Divacky }
156472cc5085SRoman Divacky return false;
156572cc5085SRoman Divacky }
156672cc5085SRoman Divacky
1567dd58ef01SDimitry Andric /// Return true if the given instruction will be CSE'd if it's hoisted out of
1568dd58ef01SDimitry Andric /// the loop.
MayCSE(MachineInstr * MI)1569eb11fae6SDimitry Andric bool MachineLICMBase::MayCSE(MachineInstr *MI) {
1570b1c73532SDimitry Andric if (MI->mayLoad() && !MI->isDereferenceableInvariantLoad())
157130815c53SDimitry Andric return false;
157230815c53SDimitry Andric
1573b1c73532SDimitry Andric unsigned Opcode = MI->getOpcode();
1574b1c73532SDimitry Andric for (auto &Map : CSEMap) {
1575b1c73532SDimitry Andric // Check this CSEMap's preheader dominates MI's basic block.
1576b1c73532SDimitry Andric if (DT->dominates(Map.first, MI->getParent())) {
1577b1c73532SDimitry Andric DenseMap<unsigned, std::vector<MachineInstr *>>::iterator CI =
1578b1c73532SDimitry Andric Map.second.find(Opcode);
1579b1c73532SDimitry Andric // Do not CSE implicit_def so ProcessImplicitDefs can properly propagate
1580b1c73532SDimitry Andric // the undef property onto uses.
1581b1c73532SDimitry Andric if (CI == Map.second.end() || MI->isImplicitDef())
1582b1c73532SDimitry Andric continue;
1583b1c73532SDimitry Andric if (LookForDuplicate(MI, CI->second) != nullptr)
1584b1c73532SDimitry Andric return true;
1585b1c73532SDimitry Andric }
1586b1c73532SDimitry Andric }
1587b1c73532SDimitry Andric
1588b1c73532SDimitry Andric return false;
158930815c53SDimitry Andric }
159030815c53SDimitry Andric
1591dd58ef01SDimitry Andric /// When an instruction is found to use only loop invariant operands
1592009b1c42SEd Schouten /// that are safe to hoist, this instruction is called to do the dirty work.
1593dd58ef01SDimitry Andric /// It returns true if the instruction is hoisted.
Hoist(MachineInstr * MI,MachineBasicBlock * Preheader,MachineLoop * CurLoop)1594b1c73532SDimitry Andric unsigned MachineLICMBase::Hoist(MachineInstr *MI, MachineBasicBlock *Preheader,
1595b1c73532SDimitry Andric MachineLoop *CurLoop) {
1596706b4fc4SDimitry Andric MachineBasicBlock *SrcBlock = MI->getParent();
1597706b4fc4SDimitry Andric
1598706b4fc4SDimitry Andric // Disable the instruction hoisting due to block hotness
1599706b4fc4SDimitry Andric if ((DisableHoistingToHotterBlocks == UseBFI::All ||
1600706b4fc4SDimitry Andric (DisableHoistingToHotterBlocks == UseBFI::PGO && HasProfileData)) &&
1601706b4fc4SDimitry Andric isTgtHotterThanSrc(SrcBlock, Preheader)) {
1602706b4fc4SDimitry Andric ++NumNotHoistedDueToHotness;
1603b1c73532SDimitry Andric return HoistResult::NotHoisted;
1604706b4fc4SDimitry Andric }
160536bf506aSRoman Divacky // First check whether we should hoist this instruction.
1606b1c73532SDimitry Andric bool HasExtractHoistableLoad = false;
1607b1c73532SDimitry Andric if (!IsLoopInvariantInst(*MI, CurLoop) ||
1608b1c73532SDimitry Andric !IsProfitableToHoist(*MI, CurLoop)) {
160936bf506aSRoman Divacky // If not, try unfolding a hoistable load.
1610b1c73532SDimitry Andric MI = ExtractHoistableLoad(MI, CurLoop);
1611b1c73532SDimitry Andric if (!MI)
1612b1c73532SDimitry Andric return HoistResult::NotHoisted;
1613b1c73532SDimitry Andric HasExtractHoistableLoad = true;
161436bf506aSRoman Divacky }
1615009b1c42SEd Schouten
1616eb11fae6SDimitry Andric // If we have hoisted an instruction that may store, it can only be a constant
1617eb11fae6SDimitry Andric // store.
1618eb11fae6SDimitry Andric if (MI->mayStore())
1619eb11fae6SDimitry Andric NumStoreConst++;
1620eb11fae6SDimitry Andric
1621009b1c42SEd Schouten // Now move the instructions to the predecessor, inserting it before any
1622009b1c42SEd Schouten // terminator instructions.
1623eb11fae6SDimitry Andric LLVM_DEBUG({
1624829000e0SRoman Divacky dbgs() << "Hoisting " << *MI;
162536bf506aSRoman Divacky if (MI->getParent()->getBasicBlock())
1626044eb2f6SDimitry Andric dbgs() << " from " << printMBBReference(*MI->getParent());
162701095a5dSDimitry Andric if (Preheader->getBasicBlock())
1628044eb2f6SDimitry Andric dbgs() << " to " << printMBBReference(*Preheader);
1629829000e0SRoman Divacky dbgs() << "\n";
1630009b1c42SEd Schouten });
1631009b1c42SEd Schouten
163236bf506aSRoman Divacky // If this is the first instruction being hoisted to the preheader,
163336bf506aSRoman Divacky // initialize the CSE map with potential common expressions.
163466e41e3cSRoman Divacky if (FirstInLoop) {
163566e41e3cSRoman Divacky InitCSEMap(Preheader);
163666e41e3cSRoman Divacky FirstInLoop = false;
163766e41e3cSRoman Divacky }
163836bf506aSRoman Divacky
1639009b1c42SEd Schouten // Look for opportunity to CSE the hoisted instruction.
164036bf506aSRoman Divacky unsigned Opcode = MI->getOpcode();
1641b1c73532SDimitry Andric bool HasCSEDone = false;
1642b1c73532SDimitry Andric for (auto &Map : CSEMap) {
1643b1c73532SDimitry Andric // Check this CSEMap's preheader dominates MI's basic block.
1644b1c73532SDimitry Andric if (DT->dominates(Map.first, MI->getParent())) {
1645b60736ecSDimitry Andric DenseMap<unsigned, std::vector<MachineInstr *>>::iterator CI =
1646b1c73532SDimitry Andric Map.second.find(Opcode);
1647b1c73532SDimitry Andric if (CI != Map.second.end()) {
1648b1c73532SDimitry Andric if (EliminateCSE(MI, CI)) {
1649b1c73532SDimitry Andric HasCSEDone = true;
1650b1c73532SDimitry Andric break;
1651b1c73532SDimitry Andric }
1652b1c73532SDimitry Andric }
1653b1c73532SDimitry Andric }
1654b1c73532SDimitry Andric }
1655b1c73532SDimitry Andric
1656b1c73532SDimitry Andric if (!HasCSEDone) {
1657009b1c42SEd Schouten // Otherwise, splice the instruction to the preheader.
165866e41e3cSRoman Divacky Preheader->splice(Preheader->getFirstTerminator(),MI->getParent(),MI);
165936bf506aSRoman Divacky
1660b915e9e0SDimitry Andric // Since we are moving the instruction out of its basic block, we do not
1661b915e9e0SDimitry Andric // retain its debug location. Doing so would degrade the debugging
1662b915e9e0SDimitry Andric // experience and adversely affect the accuracy of profiling information.
1663cfca06d7SDimitry Andric assert(!MI->isDebugInstr() && "Should not hoist debug inst");
1664b915e9e0SDimitry Andric MI->setDebugLoc(DebugLoc());
1665b915e9e0SDimitry Andric
1666cf099d11SDimitry Andric // Update register pressure for BBs from header to this block.
1667cf099d11SDimitry Andric UpdateBackTraceRegPressure(MI);
1668cf099d11SDimitry Andric
1669abdf259dSRoman Divacky // Clear the kill flags of any register this instruction defines,
1670abdf259dSRoman Divacky // since they may need to be live throughout the entire loop
1671abdf259dSRoman Divacky // rather than just live for part of it.
16727fa27ce4SDimitry Andric for (MachineOperand &MO : MI->all_defs())
16737fa27ce4SDimitry Andric if (!MO.isDead())
1674cf099d11SDimitry Andric MRI->clearKillFlags(MO.getReg());
1675abdf259dSRoman Divacky
1676b1c73532SDimitry Andric CSEMap[Preheader][Opcode].push_back(MI);
1677009b1c42SEd Schouten }
1678009b1c42SEd Schouten
1679009b1c42SEd Schouten ++NumHoisted;
1680009b1c42SEd Schouten Changed = true;
1681cf099d11SDimitry Andric
1682b1c73532SDimitry Andric if (HasCSEDone || HasExtractHoistableLoad)
1683b1c73532SDimitry Andric return HoistResult::Hoisted | HoistResult::ErasedMI;
1684b1c73532SDimitry Andric return HoistResult::Hoisted;
1685009b1c42SEd Schouten }
168666e41e3cSRoman Divacky
1687dd58ef01SDimitry Andric /// Get the preheader for the current loop, splitting a critical edge if needed.
1688b1c73532SDimitry Andric MachineBasicBlock *
getCurPreheader(MachineLoop * CurLoop,MachineBasicBlock * CurPreheader)1689b1c73532SDimitry Andric MachineLICMBase::getCurPreheader(MachineLoop *CurLoop,
1690b1c73532SDimitry Andric MachineBasicBlock *CurPreheader) {
169166e41e3cSRoman Divacky // Determine the block to which to hoist instructions. If we can't find a
169266e41e3cSRoman Divacky // suitable loop predecessor, we can't do any hoisting.
169366e41e3cSRoman Divacky
169466e41e3cSRoman Divacky // If we've tried to get a preheader and failed, don't try again.
169566e41e3cSRoman Divacky if (CurPreheader == reinterpret_cast<MachineBasicBlock *>(-1))
16965ca98fd9SDimitry Andric return nullptr;
169766e41e3cSRoman Divacky
169866e41e3cSRoman Divacky if (!CurPreheader) {
169966e41e3cSRoman Divacky CurPreheader = CurLoop->getLoopPreheader();
170066e41e3cSRoman Divacky if (!CurPreheader) {
170166e41e3cSRoman Divacky MachineBasicBlock *Pred = CurLoop->getLoopPredecessor();
170266e41e3cSRoman Divacky if (!Pred) {
170366e41e3cSRoman Divacky CurPreheader = reinterpret_cast<MachineBasicBlock *>(-1);
17045ca98fd9SDimitry Andric return nullptr;
170566e41e3cSRoman Divacky }
170666e41e3cSRoman Divacky
170701095a5dSDimitry Andric CurPreheader = Pred->SplitCriticalEdge(CurLoop->getHeader(), *this);
170866e41e3cSRoman Divacky if (!CurPreheader) {
170966e41e3cSRoman Divacky CurPreheader = reinterpret_cast<MachineBasicBlock *>(-1);
17105ca98fd9SDimitry Andric return nullptr;
171166e41e3cSRoman Divacky }
171266e41e3cSRoman Divacky }
171366e41e3cSRoman Divacky }
171466e41e3cSRoman Divacky return CurPreheader;
171566e41e3cSRoman Divacky }
1716706b4fc4SDimitry Andric
1717706b4fc4SDimitry Andric /// Is the target basic block at least "BlockFrequencyRatioThreshold"
1718706b4fc4SDimitry Andric /// times hotter than the source basic block.
isTgtHotterThanSrc(MachineBasicBlock * SrcBlock,MachineBasicBlock * TgtBlock)1719706b4fc4SDimitry Andric bool MachineLICMBase::isTgtHotterThanSrc(MachineBasicBlock *SrcBlock,
1720706b4fc4SDimitry Andric MachineBasicBlock *TgtBlock) {
1721706b4fc4SDimitry Andric // Parse source and target basic block frequency from MBFI
1722706b4fc4SDimitry Andric uint64_t SrcBF = MBFI->getBlockFreq(SrcBlock).getFrequency();
1723706b4fc4SDimitry Andric uint64_t DstBF = MBFI->getBlockFreq(TgtBlock).getFrequency();
1724706b4fc4SDimitry Andric
1725706b4fc4SDimitry Andric // Disable the hoisting if source block frequency is zero
1726706b4fc4SDimitry Andric if (!SrcBF)
1727706b4fc4SDimitry Andric return true;
1728706b4fc4SDimitry Andric
1729706b4fc4SDimitry Andric double Ratio = (double)DstBF / SrcBF;
1730706b4fc4SDimitry Andric
1731706b4fc4SDimitry Andric // Compare the block frequency ratio with the threshold
1732706b4fc4SDimitry Andric return Ratio > BlockFrequencyRatioThreshold;
1733706b4fc4SDimitry Andric }
1734