xref: /src/contrib/llvm-project/llvm/lib/CodeGen/MachineLICM.cpp (revision 71ac745d76c3ba442e753daff1870893f272b29d)
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