10b57cec5SDimitry Andric //===- MachineLICM.cpp - Machine Loop Invariant Code Motion Pass ----------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This pass performs loop invariant code motion on machine instructions. We 100b57cec5SDimitry Andric // attempt to remove as much code from the body of a loop as possible. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric // This pass is not intended to be a replacement or a complete alternative 130b57cec5SDimitry Andric // for the LLVM-IR-level LICM pass. It is only designed to hoist simple 140b57cec5SDimitry Andric // constructs that are not exposed before lowering and instruction selection. 150b57cec5SDimitry Andric // 160b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric #include "llvm/ADT/BitVector.h" 190b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 200b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 210b57cec5SDimitry Andric #include "llvm/ADT/SmallSet.h" 220b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 230b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h" 240b57cec5SDimitry Andric #include "llvm/Analysis/AliasAnalysis.h" 250b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h" 26480093f4SDimitry Andric #include "llvm/CodeGen/MachineBlockFrequencyInfo.h" 270b57cec5SDimitry Andric #include "llvm/CodeGen/MachineDominators.h" 280b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h" 290b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 300b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h" 310b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h" 320b57cec5SDimitry Andric #include "llvm/CodeGen/MachineLoopInfo.h" 330b57cec5SDimitry Andric #include "llvm/CodeGen/MachineMemOperand.h" 340b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h" 350b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 360b57cec5SDimitry Andric #include "llvm/CodeGen/PseudoSourceValue.h" 370b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h" 380b57cec5SDimitry Andric #include "llvm/CodeGen/TargetLowering.h" 390b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h" 400b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSchedule.h" 410b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h" 420b57cec5SDimitry Andric #include "llvm/IR/DebugLoc.h" 43480093f4SDimitry Andric #include "llvm/InitializePasses.h" 440b57cec5SDimitry Andric #include "llvm/MC/MCInstrDesc.h" 45e8d8bef9SDimitry Andric #include "llvm/MC/MCRegister.h" 460b57cec5SDimitry Andric #include "llvm/MC/MCRegisterInfo.h" 470b57cec5SDimitry Andric #include "llvm/Pass.h" 480b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 490b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h" 500b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 510b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 520b57cec5SDimitry Andric #include <algorithm> 530b57cec5SDimitry Andric #include <cassert> 540b57cec5SDimitry Andric #include <limits> 550b57cec5SDimitry Andric #include <vector> 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric using namespace llvm; 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric #define DEBUG_TYPE "machinelicm" 600b57cec5SDimitry Andric 610b57cec5SDimitry Andric static cl::opt<bool> 620b57cec5SDimitry Andric AvoidSpeculation("avoid-speculation", 630b57cec5SDimitry Andric cl::desc("MachineLICM should avoid speculation"), 640b57cec5SDimitry Andric cl::init(true), cl::Hidden); 650b57cec5SDimitry Andric 660b57cec5SDimitry Andric static cl::opt<bool> 670b57cec5SDimitry Andric HoistCheapInsts("hoist-cheap-insts", 680b57cec5SDimitry Andric cl::desc("MachineLICM should hoist even cheap instructions"), 690b57cec5SDimitry Andric cl::init(false), cl::Hidden); 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric static cl::opt<bool> 720b57cec5SDimitry Andric HoistConstStores("hoist-const-stores", 730b57cec5SDimitry Andric cl::desc("Hoist invariant stores"), 740b57cec5SDimitry Andric cl::init(true), cl::Hidden); 755f757f3fSDimitry Andric 765f757f3fSDimitry Andric static cl::opt<bool> HoistConstLoads("hoist-const-loads", 775f757f3fSDimitry Andric cl::desc("Hoist invariant loads"), 785f757f3fSDimitry Andric cl::init(true), cl::Hidden); 795f757f3fSDimitry Andric 80480093f4SDimitry Andric // The default threshold of 100 (i.e. if target block is 100 times hotter) 81480093f4SDimitry Andric // is based on empirical data on a single target and is subject to tuning. 82480093f4SDimitry Andric static cl::opt<unsigned> 83480093f4SDimitry Andric BlockFrequencyRatioThreshold("block-freq-ratio-threshold", 84480093f4SDimitry Andric cl::desc("Do not hoist instructions if target" 85480093f4SDimitry Andric "block is N times hotter than the source."), 86480093f4SDimitry Andric cl::init(100), cl::Hidden); 87480093f4SDimitry Andric 88480093f4SDimitry Andric enum class UseBFI { None, PGO, All }; 89480093f4SDimitry Andric 90480093f4SDimitry Andric static cl::opt<UseBFI> 91480093f4SDimitry Andric DisableHoistingToHotterBlocks("disable-hoisting-to-hotter-blocks", 92480093f4SDimitry Andric cl::desc("Disable hoisting instructions to" 93480093f4SDimitry Andric " hotter blocks"), 94e8d8bef9SDimitry Andric cl::init(UseBFI::PGO), cl::Hidden, 95480093f4SDimitry Andric cl::values(clEnumValN(UseBFI::None, "none", 96480093f4SDimitry Andric "disable the feature"), 97480093f4SDimitry Andric clEnumValN(UseBFI::PGO, "pgo", 98480093f4SDimitry Andric "enable the feature when using profile data"), 99480093f4SDimitry Andric clEnumValN(UseBFI::All, "all", 100480093f4SDimitry Andric "enable the feature with/wo profile data"))); 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric STATISTIC(NumHoisted, 1030b57cec5SDimitry Andric "Number of machine instructions hoisted out of loops"); 1040b57cec5SDimitry Andric STATISTIC(NumLowRP, 1050b57cec5SDimitry Andric "Number of instructions hoisted in low reg pressure situation"); 1060b57cec5SDimitry Andric STATISTIC(NumHighLatency, 1070b57cec5SDimitry Andric "Number of high latency instructions hoisted"); 1080b57cec5SDimitry Andric STATISTIC(NumCSEed, 1090b57cec5SDimitry Andric "Number of hoisted machine instructions CSEed"); 1100b57cec5SDimitry Andric STATISTIC(NumPostRAHoisted, 1110b57cec5SDimitry Andric "Number of machine instructions hoisted out of loops post regalloc"); 1120b57cec5SDimitry Andric STATISTIC(NumStoreConst, 1130b57cec5SDimitry Andric "Number of stores of const phys reg hoisted out of loops"); 114480093f4SDimitry Andric STATISTIC(NumNotHoistedDueToHotness, 115480093f4SDimitry Andric "Number of instructions not hoisted due to block frequency"); 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric namespace { 1185f757f3fSDimitry Andric enum HoistResult { NotHoisted = 1, Hoisted = 2, ErasedMI = 4 }; 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric class MachineLICMBase : public MachineFunctionPass { 12106c3fb27SDimitry Andric const TargetInstrInfo *TII = nullptr; 12206c3fb27SDimitry Andric const TargetLoweringBase *TLI = nullptr; 12306c3fb27SDimitry Andric const TargetRegisterInfo *TRI = nullptr; 12406c3fb27SDimitry Andric const MachineFrameInfo *MFI = nullptr; 12506c3fb27SDimitry Andric MachineRegisterInfo *MRI = nullptr; 1260b57cec5SDimitry Andric TargetSchedModel SchedModel; 12706c3fb27SDimitry Andric bool PreRegAlloc = false; 12806c3fb27SDimitry Andric bool HasProfileData = false; 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric // Various analyses that we use... 13106c3fb27SDimitry Andric AliasAnalysis *AA = nullptr; // Alias analysis info. 13206c3fb27SDimitry Andric MachineBlockFrequencyInfo *MBFI = nullptr; // Machine block frequncy info 13306c3fb27SDimitry Andric MachineLoopInfo *MLI = nullptr; // Current MachineLoopInfo 13406c3fb27SDimitry Andric MachineDominatorTree *DT = nullptr; // Machine dominator tree for the cur loop 1350b57cec5SDimitry Andric 1360b57cec5SDimitry Andric // State that is updated as we process loops 13706c3fb27SDimitry Andric bool Changed = false; // True if a loop is changed. 13806c3fb27SDimitry Andric bool FirstInLoop = false; // True if it's the first LICM in the loop. 1390b57cec5SDimitry Andric 1405f757f3fSDimitry Andric // Holds information about whether it is allowed to move load instructions 1415f757f3fSDimitry Andric // out of the loop 1425f757f3fSDimitry Andric SmallDenseMap<MachineLoop *, bool> AllowedToHoistLoads; 1435f757f3fSDimitry Andric 1445f757f3fSDimitry Andric // Exit blocks of each Loop. 1455f757f3fSDimitry Andric DenseMap<MachineLoop *, SmallVector<MachineBasicBlock *, 8>> ExitBlockMap; 1465f757f3fSDimitry Andric 1475f757f3fSDimitry Andric bool isExitBlock(MachineLoop *CurLoop, const MachineBasicBlock *MBB) { 1485f757f3fSDimitry Andric if (ExitBlockMap.contains(CurLoop)) 1495f757f3fSDimitry Andric return is_contained(ExitBlockMap[CurLoop], MBB); 1505f757f3fSDimitry Andric 1510b57cec5SDimitry Andric SmallVector<MachineBasicBlock *, 8> ExitBlocks; 1525f757f3fSDimitry Andric CurLoop->getExitBlocks(ExitBlocks); 1535f757f3fSDimitry Andric ExitBlockMap[CurLoop] = ExitBlocks; 1540b57cec5SDimitry Andric return is_contained(ExitBlocks, MBB); 1550b57cec5SDimitry Andric } 1560b57cec5SDimitry Andric 1570b57cec5SDimitry Andric // Track 'estimated' register pressure. 1580fca6ea1SDimitry Andric SmallDenseSet<Register> RegSeen; 1590b57cec5SDimitry Andric SmallVector<unsigned, 8> RegPressure; 1600b57cec5SDimitry Andric 1610b57cec5SDimitry Andric // Register pressure "limit" per register pressure set. If the pressure 1620b57cec5SDimitry Andric // is higher than the limit, then it's considered high. 1630b57cec5SDimitry Andric SmallVector<unsigned, 8> RegLimit; 1640b57cec5SDimitry Andric 1650b57cec5SDimitry Andric // Register pressure on path leading from loop preheader to current BB. 1660b57cec5SDimitry Andric SmallVector<SmallVector<unsigned, 8>, 16> BackTrace; 1670b57cec5SDimitry Andric 1685f757f3fSDimitry Andric // For each opcode per preheader, keep a list of potential CSE instructions. 1695f757f3fSDimitry Andric DenseMap<MachineBasicBlock *, 1705f757f3fSDimitry Andric DenseMap<unsigned, std::vector<MachineInstr *>>> 1715f757f3fSDimitry Andric CSEMap; 1720b57cec5SDimitry Andric 1730b57cec5SDimitry Andric enum { 1740b57cec5SDimitry Andric SpeculateFalse = 0, 1750b57cec5SDimitry Andric SpeculateTrue = 1, 1760b57cec5SDimitry Andric SpeculateUnknown = 2 1770b57cec5SDimitry Andric }; 1780b57cec5SDimitry Andric 1790b57cec5SDimitry Andric // If a MBB does not dominate loop exiting blocks then it may not safe 1800b57cec5SDimitry Andric // to hoist loads from this block. 1810b57cec5SDimitry Andric // Tri-state: 0 - false, 1 - true, 2 - unknown 18206c3fb27SDimitry Andric unsigned SpeculationState = SpeculateUnknown; 1830b57cec5SDimitry Andric 1840b57cec5SDimitry Andric public: 1850b57cec5SDimitry Andric MachineLICMBase(char &PassID, bool PreRegAlloc) 1860b57cec5SDimitry Andric : MachineFunctionPass(PassID), PreRegAlloc(PreRegAlloc) {} 1870b57cec5SDimitry Andric 1880b57cec5SDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override; 1890b57cec5SDimitry Andric 1900b57cec5SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override { 1910fca6ea1SDimitry Andric AU.addRequired<MachineLoopInfoWrapperPass>(); 192480093f4SDimitry Andric if (DisableHoistingToHotterBlocks != UseBFI::None) 1930fca6ea1SDimitry Andric AU.addRequired<MachineBlockFrequencyInfoWrapperPass>(); 1940fca6ea1SDimitry Andric AU.addRequired<MachineDominatorTreeWrapperPass>(); 1950b57cec5SDimitry Andric AU.addRequired<AAResultsWrapperPass>(); 1960fca6ea1SDimitry Andric AU.addPreserved<MachineLoopInfoWrapperPass>(); 1970b57cec5SDimitry Andric MachineFunctionPass::getAnalysisUsage(AU); 1980b57cec5SDimitry Andric } 1990b57cec5SDimitry Andric 2000b57cec5SDimitry Andric void releaseMemory() override { 2010b57cec5SDimitry Andric RegSeen.clear(); 2020b57cec5SDimitry Andric RegPressure.clear(); 2030b57cec5SDimitry Andric RegLimit.clear(); 2040b57cec5SDimitry Andric BackTrace.clear(); 2050b57cec5SDimitry Andric CSEMap.clear(); 2065f757f3fSDimitry Andric ExitBlockMap.clear(); 2070b57cec5SDimitry Andric } 2080b57cec5SDimitry Andric 2090b57cec5SDimitry Andric private: 2100b57cec5SDimitry Andric /// Keep track of information about hoisting candidates. 2110b57cec5SDimitry Andric struct CandidateInfo { 2120b57cec5SDimitry Andric MachineInstr *MI; 2130b57cec5SDimitry Andric unsigned Def; 2140b57cec5SDimitry Andric int FI; 2150b57cec5SDimitry Andric 2160b57cec5SDimitry Andric CandidateInfo(MachineInstr *mi, unsigned def, int fi) 2170b57cec5SDimitry Andric : MI(mi), Def(def), FI(fi) {} 2180b57cec5SDimitry Andric }; 2190b57cec5SDimitry Andric 2205f757f3fSDimitry Andric void HoistRegionPostRA(MachineLoop *CurLoop, 2215f757f3fSDimitry Andric MachineBasicBlock *CurPreheader); 2220b57cec5SDimitry Andric 2235f757f3fSDimitry Andric void HoistPostRA(MachineInstr *MI, unsigned Def, MachineLoop *CurLoop, 2245f757f3fSDimitry Andric MachineBasicBlock *CurPreheader); 2250b57cec5SDimitry Andric 2260fca6ea1SDimitry Andric void ProcessMI(MachineInstr *MI, BitVector &RUDefs, BitVector &RUClobbers, 2270fca6ea1SDimitry Andric SmallDenseSet<int> &StoredFIs, 2285f757f3fSDimitry Andric SmallVectorImpl<CandidateInfo> &Candidates, 2295f757f3fSDimitry Andric MachineLoop *CurLoop); 2300b57cec5SDimitry Andric 2315f757f3fSDimitry Andric void AddToLiveIns(MCRegister Reg, MachineLoop *CurLoop); 2320b57cec5SDimitry Andric 2335f757f3fSDimitry Andric bool IsLICMCandidate(MachineInstr &I, MachineLoop *CurLoop); 2340b57cec5SDimitry Andric 2355f757f3fSDimitry Andric bool IsLoopInvariantInst(MachineInstr &I, MachineLoop *CurLoop); 2360b57cec5SDimitry Andric 2375f757f3fSDimitry Andric bool HasLoopPHIUse(const MachineInstr *MI, MachineLoop *CurLoop); 2380b57cec5SDimitry Andric 2395f757f3fSDimitry Andric bool HasHighOperandLatency(MachineInstr &MI, unsigned DefIdx, Register Reg, 2405f757f3fSDimitry Andric MachineLoop *CurLoop) const; 2410b57cec5SDimitry Andric 2420b57cec5SDimitry Andric bool IsCheapInstruction(MachineInstr &MI) const; 2430b57cec5SDimitry Andric 2440b57cec5SDimitry Andric bool CanCauseHighRegPressure(const DenseMap<unsigned, int> &Cost, 2450b57cec5SDimitry Andric bool Cheap); 2460b57cec5SDimitry Andric 2470b57cec5SDimitry Andric void UpdateBackTraceRegPressure(const MachineInstr *MI); 2480b57cec5SDimitry Andric 2495f757f3fSDimitry Andric bool IsProfitableToHoist(MachineInstr &MI, MachineLoop *CurLoop); 2500b57cec5SDimitry Andric 2515f757f3fSDimitry Andric bool IsGuaranteedToExecute(MachineBasicBlock *BB, MachineLoop *CurLoop); 2520b57cec5SDimitry Andric 253fcaf7f86SDimitry Andric bool isTriviallyReMaterializable(const MachineInstr &MI) const; 254349cc55cSDimitry Andric 2550b57cec5SDimitry Andric void EnterScope(MachineBasicBlock *MBB); 2560b57cec5SDimitry Andric 2570b57cec5SDimitry Andric void ExitScope(MachineBasicBlock *MBB); 2580b57cec5SDimitry Andric 2590b57cec5SDimitry Andric void ExitScopeIfDone( 2600b57cec5SDimitry Andric MachineDomTreeNode *Node, 2610b57cec5SDimitry Andric DenseMap<MachineDomTreeNode *, unsigned> &OpenChildren, 26281ad6265SDimitry Andric const DenseMap<MachineDomTreeNode *, MachineDomTreeNode *> &ParentMap); 2630b57cec5SDimitry Andric 2645f757f3fSDimitry Andric void HoistOutOfLoop(MachineDomTreeNode *HeaderN, MachineLoop *CurLoop, 2655f757f3fSDimitry Andric MachineBasicBlock *CurPreheader); 2660b57cec5SDimitry Andric 2670b57cec5SDimitry Andric void InitRegPressure(MachineBasicBlock *BB); 2680b57cec5SDimitry Andric 2690b57cec5SDimitry Andric DenseMap<unsigned, int> calcRegisterCost(const MachineInstr *MI, 2700b57cec5SDimitry Andric bool ConsiderSeen, 2710b57cec5SDimitry Andric bool ConsiderUnseenAsDef); 2720b57cec5SDimitry Andric 2730b57cec5SDimitry Andric void UpdateRegPressure(const MachineInstr *MI, 2740b57cec5SDimitry Andric bool ConsiderUnseenAsDef = false); 2750b57cec5SDimitry Andric 2765f757f3fSDimitry Andric MachineInstr *ExtractHoistableLoad(MachineInstr *MI, MachineLoop *CurLoop); 2770b57cec5SDimitry Andric 278e8d8bef9SDimitry Andric MachineInstr *LookForDuplicate(const MachineInstr *MI, 279e8d8bef9SDimitry Andric std::vector<MachineInstr *> &PrevMIs); 2800b57cec5SDimitry Andric 281e8d8bef9SDimitry Andric bool 282e8d8bef9SDimitry Andric EliminateCSE(MachineInstr *MI, 283e8d8bef9SDimitry Andric DenseMap<unsigned, std::vector<MachineInstr *>>::iterator &CI); 2840b57cec5SDimitry Andric 2850b57cec5SDimitry Andric bool MayCSE(MachineInstr *MI); 2860b57cec5SDimitry Andric 2875f757f3fSDimitry Andric unsigned Hoist(MachineInstr *MI, MachineBasicBlock *Preheader, 2885f757f3fSDimitry Andric MachineLoop *CurLoop); 2890b57cec5SDimitry Andric 2900b57cec5SDimitry Andric void InitCSEMap(MachineBasicBlock *BB); 2910b57cec5SDimitry Andric 2925f757f3fSDimitry Andric void InitializeLoadsHoistableLoops(); 2935f757f3fSDimitry Andric 294480093f4SDimitry Andric bool isTgtHotterThanSrc(MachineBasicBlock *SrcBlock, 295480093f4SDimitry Andric MachineBasicBlock *TgtBlock); 2965f757f3fSDimitry Andric MachineBasicBlock *getCurPreheader(MachineLoop *CurLoop, 2975f757f3fSDimitry Andric MachineBasicBlock *CurPreheader); 2980b57cec5SDimitry Andric }; 2990b57cec5SDimitry Andric 3000b57cec5SDimitry Andric class MachineLICM : public MachineLICMBase { 3010b57cec5SDimitry Andric public: 3020b57cec5SDimitry Andric static char ID; 3030b57cec5SDimitry Andric MachineLICM() : MachineLICMBase(ID, false) { 3040b57cec5SDimitry Andric initializeMachineLICMPass(*PassRegistry::getPassRegistry()); 3050b57cec5SDimitry Andric } 3060b57cec5SDimitry Andric }; 3070b57cec5SDimitry Andric 3080b57cec5SDimitry Andric class EarlyMachineLICM : public MachineLICMBase { 3090b57cec5SDimitry Andric public: 3100b57cec5SDimitry Andric static char ID; 3110b57cec5SDimitry Andric EarlyMachineLICM() : MachineLICMBase(ID, true) { 3120b57cec5SDimitry Andric initializeEarlyMachineLICMPass(*PassRegistry::getPassRegistry()); 3130b57cec5SDimitry Andric } 3140b57cec5SDimitry Andric }; 3150b57cec5SDimitry Andric 3160b57cec5SDimitry Andric } // end anonymous namespace 3170b57cec5SDimitry Andric 3180b57cec5SDimitry Andric char MachineLICM::ID; 3190b57cec5SDimitry Andric char EarlyMachineLICM::ID; 3200b57cec5SDimitry Andric 3210b57cec5SDimitry Andric char &llvm::MachineLICMID = MachineLICM::ID; 3220b57cec5SDimitry Andric char &llvm::EarlyMachineLICMID = EarlyMachineLICM::ID; 3230b57cec5SDimitry Andric 3240b57cec5SDimitry Andric INITIALIZE_PASS_BEGIN(MachineLICM, DEBUG_TYPE, 3250b57cec5SDimitry Andric "Machine Loop Invariant Code Motion", false, false) 3260fca6ea1SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass) 3270fca6ea1SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineBlockFrequencyInfoWrapperPass) 3280fca6ea1SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass) 3290b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) 3300b57cec5SDimitry Andric INITIALIZE_PASS_END(MachineLICM, DEBUG_TYPE, 3310b57cec5SDimitry Andric "Machine Loop Invariant Code Motion", false, false) 3320b57cec5SDimitry Andric 3330b57cec5SDimitry Andric INITIALIZE_PASS_BEGIN(EarlyMachineLICM, "early-machinelicm", 3340b57cec5SDimitry Andric "Early Machine Loop Invariant Code Motion", false, false) 3350fca6ea1SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass) 3360fca6ea1SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineBlockFrequencyInfoWrapperPass) 3370fca6ea1SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass) 3380b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) 3390b57cec5SDimitry Andric INITIALIZE_PASS_END(EarlyMachineLICM, "early-machinelicm", 3400b57cec5SDimitry Andric "Early Machine Loop Invariant Code Motion", false, false) 3410b57cec5SDimitry Andric 3420b57cec5SDimitry Andric bool MachineLICMBase::runOnMachineFunction(MachineFunction &MF) { 3430b57cec5SDimitry Andric if (skipFunction(MF.getFunction())) 3440b57cec5SDimitry Andric return false; 3450b57cec5SDimitry Andric 3460b57cec5SDimitry Andric Changed = FirstInLoop = false; 3470b57cec5SDimitry Andric const TargetSubtargetInfo &ST = MF.getSubtarget(); 3480b57cec5SDimitry Andric TII = ST.getInstrInfo(); 3490b57cec5SDimitry Andric TLI = ST.getTargetLowering(); 3500b57cec5SDimitry Andric TRI = ST.getRegisterInfo(); 3510b57cec5SDimitry Andric MFI = &MF.getFrameInfo(); 3520b57cec5SDimitry Andric MRI = &MF.getRegInfo(); 3530b57cec5SDimitry Andric SchedModel.init(&ST); 3540b57cec5SDimitry Andric 3550b57cec5SDimitry Andric PreRegAlloc = MRI->isSSA(); 356480093f4SDimitry Andric HasProfileData = MF.getFunction().hasProfileData(); 3570b57cec5SDimitry Andric 3580b57cec5SDimitry Andric if (PreRegAlloc) 3590b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "******** Pre-regalloc Machine LICM: "); 3600b57cec5SDimitry Andric else 3610b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "******** Post-regalloc Machine LICM: "); 3620b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << MF.getName() << " ********\n"); 3630b57cec5SDimitry Andric 3640b57cec5SDimitry Andric if (PreRegAlloc) { 3650b57cec5SDimitry Andric // Estimate register pressure during pre-regalloc pass. 3660b57cec5SDimitry Andric unsigned NumRPS = TRI->getNumRegPressureSets(); 3670b57cec5SDimitry Andric RegPressure.resize(NumRPS); 3680b57cec5SDimitry Andric std::fill(RegPressure.begin(), RegPressure.end(), 0); 3690b57cec5SDimitry Andric RegLimit.resize(NumRPS); 3700b57cec5SDimitry Andric for (unsigned i = 0, e = NumRPS; i != e; ++i) 3710b57cec5SDimitry Andric RegLimit[i] = TRI->getRegPressureSetLimit(MF, i); 3720b57cec5SDimitry Andric } 3730b57cec5SDimitry Andric 3740b57cec5SDimitry Andric // Get our Loop information... 375480093f4SDimitry Andric if (DisableHoistingToHotterBlocks != UseBFI::None) 3760fca6ea1SDimitry Andric MBFI = &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI(); 3770fca6ea1SDimitry Andric MLI = &getAnalysis<MachineLoopInfoWrapperPass>().getLI(); 3780fca6ea1SDimitry Andric DT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree(); 3790b57cec5SDimitry Andric AA = &getAnalysis<AAResultsWrapperPass>().getAAResults(); 3800b57cec5SDimitry Andric 3815f757f3fSDimitry Andric if (HoistConstLoads) 3825f757f3fSDimitry Andric InitializeLoadsHoistableLoops(); 3835f757f3fSDimitry Andric 3840b57cec5SDimitry Andric SmallVector<MachineLoop *, 8> Worklist(MLI->begin(), MLI->end()); 3850b57cec5SDimitry Andric while (!Worklist.empty()) { 3865f757f3fSDimitry Andric MachineLoop *CurLoop = Worklist.pop_back_val(); 3875f757f3fSDimitry Andric MachineBasicBlock *CurPreheader = nullptr; 3880b57cec5SDimitry Andric 3890b57cec5SDimitry Andric if (!PreRegAlloc) 3905f757f3fSDimitry Andric HoistRegionPostRA(CurLoop, CurPreheader); 3910b57cec5SDimitry Andric else { 3920b57cec5SDimitry Andric // CSEMap is initialized for loop header when the first instruction is 3930b57cec5SDimitry Andric // being hoisted. 3940b57cec5SDimitry Andric MachineDomTreeNode *N = DT->getNode(CurLoop->getHeader()); 3950b57cec5SDimitry Andric FirstInLoop = true; 3965f757f3fSDimitry Andric HoistOutOfLoop(N, CurLoop, CurPreheader); 3970b57cec5SDimitry Andric CSEMap.clear(); 3980b57cec5SDimitry Andric } 3990b57cec5SDimitry Andric } 4000b57cec5SDimitry Andric 4010b57cec5SDimitry Andric return Changed; 4020b57cec5SDimitry Andric } 4030b57cec5SDimitry Andric 4040b57cec5SDimitry Andric /// Return true if instruction stores to the specified frame. 4050b57cec5SDimitry Andric static bool InstructionStoresToFI(const MachineInstr *MI, int FI) { 4060b57cec5SDimitry Andric // Check mayStore before memory operands so that e.g. DBG_VALUEs will return 4070b57cec5SDimitry Andric // true since they have no memory operands. 4080b57cec5SDimitry Andric if (!MI->mayStore()) 4090b57cec5SDimitry Andric return false; 4100b57cec5SDimitry Andric // If we lost memory operands, conservatively assume that the instruction 4110b57cec5SDimitry Andric // writes to all slots. 4120b57cec5SDimitry Andric if (MI->memoperands_empty()) 4130b57cec5SDimitry Andric return true; 4140b57cec5SDimitry Andric for (const MachineMemOperand *MemOp : MI->memoperands()) { 4150b57cec5SDimitry Andric if (!MemOp->isStore() || !MemOp->getPseudoValue()) 4160b57cec5SDimitry Andric continue; 4170b57cec5SDimitry Andric if (const FixedStackPseudoSourceValue *Value = 4180b57cec5SDimitry Andric dyn_cast<FixedStackPseudoSourceValue>(MemOp->getPseudoValue())) { 4190b57cec5SDimitry Andric if (Value->getFrameIndex() == FI) 4200b57cec5SDimitry Andric return true; 4210b57cec5SDimitry Andric } 4220b57cec5SDimitry Andric } 4230b57cec5SDimitry Andric return false; 4240b57cec5SDimitry Andric } 4250b57cec5SDimitry Andric 4260fca6ea1SDimitry Andric static void applyBitsNotInRegMaskToRegUnitsMask(const TargetRegisterInfo &TRI, 4270fca6ea1SDimitry Andric BitVector &RUs, 4280fca6ea1SDimitry Andric const uint32_t *Mask) { 4290fca6ea1SDimitry Andric // FIXME: This intentionally works in reverse due to some issues with the 4300fca6ea1SDimitry Andric // Register Units infrastructure. 4310fca6ea1SDimitry Andric // 4320fca6ea1SDimitry Andric // This is used to apply callee-saved-register masks to the clobbered regunits 4330fca6ea1SDimitry Andric // mask. 4340fca6ea1SDimitry Andric // 4350fca6ea1SDimitry Andric // The right way to approach this is to start with a BitVector full of ones, 4360fca6ea1SDimitry Andric // then reset all the bits of the regunits of each register that is set in the 4370fca6ea1SDimitry Andric // mask (registers preserved), then OR the resulting bits with the Clobbers 4380fca6ea1SDimitry Andric // mask. This correctly prioritizes the saved registers, so if a RU is shared 4390fca6ea1SDimitry Andric // between a register that is preserved, and one that is NOT preserved, that 4400fca6ea1SDimitry Andric // RU will not be set in the output vector (the clobbers). 4410fca6ea1SDimitry Andric // 4420fca6ea1SDimitry Andric // What we have to do for now is the opposite: we have to assume that the 4430fca6ea1SDimitry Andric // regunits of all registers that are NOT preserved are clobbered, even if 4440fca6ea1SDimitry Andric // those regunits are preserved by another register. So if a RU is shared 4450fca6ea1SDimitry Andric // like described previously, that RU will be set. 4460fca6ea1SDimitry Andric // 4470fca6ea1SDimitry Andric // This is to work around an issue which appears in AArch64, but isn't 4480fca6ea1SDimitry Andric // exclusive to that target: AArch64's Qn registers (128 bits) have Dn 4490fca6ea1SDimitry Andric // register (lower 64 bits). A few Dn registers are preserved by some calling 4500fca6ea1SDimitry Andric // conventions, but Qn and Dn share exactly the same reg units. 4510fca6ea1SDimitry Andric // 4520fca6ea1SDimitry Andric // If we do this the right way, Qn will be marked as NOT clobbered even though 4530fca6ea1SDimitry Andric // its upper 64 bits are NOT preserved. The conservative approach handles this 4540fca6ea1SDimitry Andric // correctly at the cost of some missed optimizations on other targets. 4550fca6ea1SDimitry Andric // 4560fca6ea1SDimitry Andric // This is caused by how RegUnits are handled within TableGen. Ideally, Qn 4570fca6ea1SDimitry Andric // should have an extra RegUnit to model the "unknown" bits not covered by the 4580fca6ea1SDimitry Andric // subregs. 4590fca6ea1SDimitry Andric BitVector RUsFromRegsNotInMask(TRI.getNumRegUnits()); 4600fca6ea1SDimitry Andric const unsigned NumRegs = TRI.getNumRegs(); 4610fca6ea1SDimitry Andric const unsigned MaskWords = (NumRegs + 31) / 32; 4620fca6ea1SDimitry Andric for (unsigned K = 0; K < MaskWords; ++K) { 4630fca6ea1SDimitry Andric const uint32_t Word = Mask[K]; 4640fca6ea1SDimitry Andric for (unsigned Bit = 0; Bit < 32; ++Bit) { 4650fca6ea1SDimitry Andric const unsigned PhysReg = (K * 32) + Bit; 4660fca6ea1SDimitry Andric if (PhysReg == NumRegs) 4670fca6ea1SDimitry Andric break; 4680fca6ea1SDimitry Andric 4690fca6ea1SDimitry Andric if (PhysReg && !((Word >> Bit) & 1)) { 4700fca6ea1SDimitry Andric for (MCRegUnitIterator RUI(PhysReg, &TRI); RUI.isValid(); ++RUI) 4710fca6ea1SDimitry Andric RUsFromRegsNotInMask.set(*RUI); 4720fca6ea1SDimitry Andric } 4730fca6ea1SDimitry Andric } 4740fca6ea1SDimitry Andric } 4750fca6ea1SDimitry Andric 4760fca6ea1SDimitry Andric RUs |= RUsFromRegsNotInMask; 4770fca6ea1SDimitry Andric } 4780fca6ea1SDimitry Andric 4790b57cec5SDimitry Andric /// Examine the instruction for potentai LICM candidate. Also 4800b57cec5SDimitry Andric /// gather register def and frame object update information. 4810fca6ea1SDimitry Andric void MachineLICMBase::ProcessMI(MachineInstr *MI, BitVector &RUDefs, 4820fca6ea1SDimitry Andric BitVector &RUClobbers, 4830fca6ea1SDimitry Andric SmallDenseSet<int> &StoredFIs, 4845f757f3fSDimitry Andric SmallVectorImpl<CandidateInfo> &Candidates, 4855f757f3fSDimitry Andric MachineLoop *CurLoop) { 4860b57cec5SDimitry Andric bool RuledOut = false; 4870b57cec5SDimitry Andric bool HasNonInvariantUse = false; 4880b57cec5SDimitry Andric unsigned Def = 0; 4890b57cec5SDimitry Andric for (const MachineOperand &MO : MI->operands()) { 4900b57cec5SDimitry Andric if (MO.isFI()) { 4910b57cec5SDimitry Andric // Remember if the instruction stores to the frame index. 4920b57cec5SDimitry Andric int FI = MO.getIndex(); 4930b57cec5SDimitry Andric if (!StoredFIs.count(FI) && 4940b57cec5SDimitry Andric MFI->isSpillSlotObjectIndex(FI) && 4950b57cec5SDimitry Andric InstructionStoresToFI(MI, FI)) 4960b57cec5SDimitry Andric StoredFIs.insert(FI); 4970b57cec5SDimitry Andric HasNonInvariantUse = true; 4980b57cec5SDimitry Andric continue; 4990b57cec5SDimitry Andric } 5000b57cec5SDimitry Andric 5010b57cec5SDimitry Andric // We can't hoist an instruction defining a physreg that is clobbered in 5020b57cec5SDimitry Andric // the loop. 5030b57cec5SDimitry Andric if (MO.isRegMask()) { 5040fca6ea1SDimitry Andric applyBitsNotInRegMaskToRegUnitsMask(*TRI, RUClobbers, MO.getRegMask()); 5050b57cec5SDimitry Andric continue; 5060b57cec5SDimitry Andric } 5070b57cec5SDimitry Andric 5080b57cec5SDimitry Andric if (!MO.isReg()) 5090b57cec5SDimitry Andric continue; 5108bcb0991SDimitry Andric Register Reg = MO.getReg(); 5110b57cec5SDimitry Andric if (!Reg) 5120b57cec5SDimitry Andric continue; 513bdd1243dSDimitry Andric assert(Reg.isPhysical() && "Not expecting virtual register!"); 5140b57cec5SDimitry Andric 5150b57cec5SDimitry Andric if (!MO.isDef()) { 5160fca6ea1SDimitry Andric if (!HasNonInvariantUse) { 5170fca6ea1SDimitry Andric for (MCRegUnitIterator RUI(Reg, TRI); RUI.isValid(); ++RUI) { 5180fca6ea1SDimitry Andric // If it's using a non-loop-invariant register, then it's obviously 5190fca6ea1SDimitry Andric // not safe to hoist. 5200fca6ea1SDimitry Andric if (RUDefs.test(*RUI) || RUClobbers.test(*RUI)) { 5210b57cec5SDimitry Andric HasNonInvariantUse = true; 5220fca6ea1SDimitry Andric break; 5230fca6ea1SDimitry Andric } 5240fca6ea1SDimitry Andric } 5250fca6ea1SDimitry Andric } 5260b57cec5SDimitry Andric continue; 5270b57cec5SDimitry Andric } 5280b57cec5SDimitry Andric 5290b57cec5SDimitry Andric if (MO.isImplicit()) { 5300fca6ea1SDimitry Andric for (MCRegUnitIterator RUI(Reg, TRI); RUI.isValid(); ++RUI) 5310fca6ea1SDimitry Andric RUClobbers.set(*RUI); 5320b57cec5SDimitry Andric if (!MO.isDead()) 5330b57cec5SDimitry Andric // Non-dead implicit def? This cannot be hoisted. 5340b57cec5SDimitry Andric RuledOut = true; 5350b57cec5SDimitry Andric // No need to check if a dead implicit def is also defined by 5360b57cec5SDimitry Andric // another instruction. 5370b57cec5SDimitry Andric continue; 5380b57cec5SDimitry Andric } 5390b57cec5SDimitry Andric 5400b57cec5SDimitry Andric // FIXME: For now, avoid instructions with multiple defs, unless 5410b57cec5SDimitry Andric // it's a dead implicit def. 5420b57cec5SDimitry Andric if (Def) 5430b57cec5SDimitry Andric RuledOut = true; 5440b57cec5SDimitry Andric else 5450b57cec5SDimitry Andric Def = Reg; 5460b57cec5SDimitry Andric 5470b57cec5SDimitry Andric // If we have already seen another instruction that defines the same 5480b57cec5SDimitry Andric // register, then this is not safe. Two defs is indicated by setting a 5490b57cec5SDimitry Andric // PhysRegClobbers bit. 5500fca6ea1SDimitry Andric for (MCRegUnitIterator RUI(Reg, TRI); RUI.isValid(); ++RUI) { 5510fca6ea1SDimitry Andric if (RUDefs.test(*RUI)) { 5520fca6ea1SDimitry Andric RUClobbers.set(*RUI); 5530fca6ea1SDimitry Andric RuledOut = true; 5540fca6ea1SDimitry Andric } else if (RUClobbers.test(*RUI)) { 5550b57cec5SDimitry Andric // MI defined register is seen defined by another instruction in 5560b57cec5SDimitry Andric // the loop, it cannot be a LICM candidate. 5570b57cec5SDimitry Andric RuledOut = true; 5580b57cec5SDimitry Andric } 5590b57cec5SDimitry Andric 5600fca6ea1SDimitry Andric RUDefs.set(*RUI); 5610fca6ea1SDimitry Andric } 5620fca6ea1SDimitry Andric } 5630fca6ea1SDimitry Andric 5640b57cec5SDimitry Andric // Only consider reloads for now and remats which do not have register 5650b57cec5SDimitry Andric // operands. FIXME: Consider unfold load folding instructions. 5660b57cec5SDimitry Andric if (Def && !RuledOut) { 5670b57cec5SDimitry Andric int FI = std::numeric_limits<int>::min(); 5685f757f3fSDimitry Andric if ((!HasNonInvariantUse && IsLICMCandidate(*MI, CurLoop)) || 5690b57cec5SDimitry Andric (TII->isLoadFromStackSlot(*MI, FI) && MFI->isSpillSlotObjectIndex(FI))) 5700b57cec5SDimitry Andric Candidates.push_back(CandidateInfo(MI, Def, FI)); 5710b57cec5SDimitry Andric } 5720b57cec5SDimitry Andric } 5730b57cec5SDimitry Andric 5740b57cec5SDimitry Andric /// Walk the specified region of the CFG and hoist loop invariants out to the 5750b57cec5SDimitry Andric /// preheader. 5765f757f3fSDimitry Andric void MachineLICMBase::HoistRegionPostRA(MachineLoop *CurLoop, 5775f757f3fSDimitry Andric MachineBasicBlock *CurPreheader) { 5785f757f3fSDimitry Andric MachineBasicBlock *Preheader = getCurPreheader(CurLoop, CurPreheader); 5790b57cec5SDimitry Andric if (!Preheader) 5800b57cec5SDimitry Andric return; 5810b57cec5SDimitry Andric 5820fca6ea1SDimitry Andric unsigned NumRegUnits = TRI->getNumRegUnits(); 5830fca6ea1SDimitry Andric BitVector RUDefs(NumRegUnits); // RUs defined once in the loop. 5840fca6ea1SDimitry Andric BitVector RUClobbers(NumRegUnits); // RUs defined more than once. 5850b57cec5SDimitry Andric 5860b57cec5SDimitry Andric SmallVector<CandidateInfo, 32> Candidates; 5870fca6ea1SDimitry Andric SmallDenseSet<int> StoredFIs; 5880b57cec5SDimitry Andric 5890b57cec5SDimitry Andric // Walk the entire region, count number of defs for each register, and 5900b57cec5SDimitry Andric // collect potential LICM candidates. 5910b57cec5SDimitry Andric for (MachineBasicBlock *BB : CurLoop->getBlocks()) { 5920b57cec5SDimitry Andric // If the header of the loop containing this basic block is a landing pad, 5930b57cec5SDimitry Andric // then don't try to hoist instructions out of this loop. 5940b57cec5SDimitry Andric const MachineLoop *ML = MLI->getLoopFor(BB); 5950b57cec5SDimitry Andric if (ML && ML->getHeader()->isEHPad()) continue; 5960b57cec5SDimitry Andric 5970b57cec5SDimitry Andric // Conservatively treat live-in's as an external def. 5980b57cec5SDimitry Andric // FIXME: That means a reload that're reused in successor block(s) will not 5990b57cec5SDimitry Andric // be LICM'ed. 6000b57cec5SDimitry Andric for (const auto &LI : BB->liveins()) { 6010fca6ea1SDimitry Andric for (MCRegUnitIterator RUI(LI.PhysReg, TRI); RUI.isValid(); ++RUI) 6020fca6ea1SDimitry Andric RUDefs.set(*RUI); 6030b57cec5SDimitry Andric } 6040b57cec5SDimitry Andric 6058a4dda33SDimitry Andric // Funclet entry blocks will clobber all registers 6068a4dda33SDimitry Andric if (const uint32_t *Mask = BB->getBeginClobberMask(TRI)) 6070fca6ea1SDimitry Andric applyBitsNotInRegMaskToRegUnitsMask(*TRI, RUClobbers, Mask); 6088a4dda33SDimitry Andric 6090b57cec5SDimitry Andric SpeculationState = SpeculateUnknown; 6100b57cec5SDimitry Andric for (MachineInstr &MI : *BB) 6110fca6ea1SDimitry Andric ProcessMI(&MI, RUDefs, RUClobbers, StoredFIs, Candidates, CurLoop); 6120b57cec5SDimitry Andric } 6130b57cec5SDimitry Andric 6140b57cec5SDimitry Andric // Gather the registers read / clobbered by the terminator. 6150fca6ea1SDimitry Andric BitVector TermRUs(NumRegUnits); 6160b57cec5SDimitry Andric MachineBasicBlock::iterator TI = Preheader->getFirstTerminator(); 6170b57cec5SDimitry Andric if (TI != Preheader->end()) { 6180b57cec5SDimitry Andric for (const MachineOperand &MO : TI->operands()) { 6190b57cec5SDimitry Andric if (!MO.isReg()) 6200b57cec5SDimitry Andric continue; 6218bcb0991SDimitry Andric Register Reg = MO.getReg(); 6220b57cec5SDimitry Andric if (!Reg) 6230b57cec5SDimitry Andric continue; 6240fca6ea1SDimitry Andric for (MCRegUnitIterator RUI(Reg, TRI); RUI.isValid(); ++RUI) 6250fca6ea1SDimitry Andric TermRUs.set(*RUI); 6260b57cec5SDimitry Andric } 6270b57cec5SDimitry Andric } 6280b57cec5SDimitry Andric 6290b57cec5SDimitry Andric // Now evaluate whether the potential candidates qualify. 6300b57cec5SDimitry Andric // 1. Check if the candidate defined register is defined by another 6310b57cec5SDimitry Andric // instruction in the loop. 6320b57cec5SDimitry Andric // 2. If the candidate is a load from stack slot (always true for now), 6330b57cec5SDimitry Andric // check if the slot is stored anywhere in the loop. 6340b57cec5SDimitry Andric // 3. Make sure candidate def should not clobber 6350b57cec5SDimitry Andric // registers read by the terminator. Similarly its def should not be 6360b57cec5SDimitry Andric // clobbered by the terminator. 6370b57cec5SDimitry Andric for (CandidateInfo &Candidate : Candidates) { 6380b57cec5SDimitry Andric if (Candidate.FI != std::numeric_limits<int>::min() && 6390b57cec5SDimitry Andric StoredFIs.count(Candidate.FI)) 6400b57cec5SDimitry Andric continue; 6410b57cec5SDimitry Andric 6420b57cec5SDimitry Andric unsigned Def = Candidate.Def; 6430b57cec5SDimitry Andric bool Safe = true; 6440fca6ea1SDimitry Andric for (MCRegUnitIterator RUI(Def, TRI); RUI.isValid(); ++RUI) { 6450fca6ea1SDimitry Andric if (RUClobbers.test(*RUI) || TermRUs.test(*RUI)) { 6460fca6ea1SDimitry Andric Safe = false; 6470fca6ea1SDimitry Andric break; 6480fca6ea1SDimitry Andric } 6490fca6ea1SDimitry Andric } 6500fca6ea1SDimitry Andric 6510fca6ea1SDimitry Andric if (!Safe) 6520fca6ea1SDimitry Andric continue; 6530fca6ea1SDimitry Andric 6540b57cec5SDimitry Andric MachineInstr *MI = Candidate.MI; 65506c3fb27SDimitry Andric for (const MachineOperand &MO : MI->all_uses()) { 65606c3fb27SDimitry Andric if (!MO.getReg()) 6570b57cec5SDimitry Andric continue; 6580fca6ea1SDimitry Andric for (MCRegUnitIterator RUI(MO.getReg(), TRI); RUI.isValid(); ++RUI) { 6590fca6ea1SDimitry Andric if (RUDefs.test(*RUI) || RUClobbers.test(*RUI)) { 6600b57cec5SDimitry Andric // If it's using a non-loop-invariant register, then it's obviously 6610b57cec5SDimitry Andric // not safe to hoist. 6620b57cec5SDimitry Andric Safe = false; 6630b57cec5SDimitry Andric break; 6640b57cec5SDimitry Andric } 6650b57cec5SDimitry Andric } 6660fca6ea1SDimitry Andric 6670fca6ea1SDimitry Andric if (!Safe) 6680fca6ea1SDimitry Andric break; 6690fca6ea1SDimitry Andric } 6700fca6ea1SDimitry Andric 6710b57cec5SDimitry Andric if (Safe) 6725f757f3fSDimitry Andric HoistPostRA(MI, Candidate.Def, CurLoop, CurPreheader); 6730b57cec5SDimitry Andric } 6740b57cec5SDimitry Andric } 6750b57cec5SDimitry Andric 6760b57cec5SDimitry Andric /// Add register 'Reg' to the livein sets of BBs in the current loop, and make 6770b57cec5SDimitry Andric /// sure it is not killed by any instructions in the loop. 6785f757f3fSDimitry Andric void MachineLICMBase::AddToLiveIns(MCRegister Reg, MachineLoop *CurLoop) { 6790b57cec5SDimitry Andric for (MachineBasicBlock *BB : CurLoop->getBlocks()) { 6800b57cec5SDimitry Andric if (!BB->isLiveIn(Reg)) 6810b57cec5SDimitry Andric BB->addLiveIn(Reg); 6820b57cec5SDimitry Andric for (MachineInstr &MI : *BB) { 68306c3fb27SDimitry Andric for (MachineOperand &MO : MI.all_uses()) { 68406c3fb27SDimitry Andric if (!MO.getReg()) 68506c3fb27SDimitry Andric continue; 6865f757f3fSDimitry Andric if (TRI->regsOverlap(Reg, MO.getReg())) 6870b57cec5SDimitry Andric MO.setIsKill(false); 6880b57cec5SDimitry Andric } 6890b57cec5SDimitry Andric } 6900b57cec5SDimitry Andric } 6910b57cec5SDimitry Andric } 6920b57cec5SDimitry Andric 6930b57cec5SDimitry Andric /// When an instruction is found to only use loop invariant operands that is 6940b57cec5SDimitry Andric /// safe to hoist, this instruction is called to do the dirty work. 6955f757f3fSDimitry Andric void MachineLICMBase::HoistPostRA(MachineInstr *MI, unsigned Def, 6965f757f3fSDimitry Andric MachineLoop *CurLoop, 6975f757f3fSDimitry Andric MachineBasicBlock *CurPreheader) { 6985f757f3fSDimitry Andric MachineBasicBlock *Preheader = getCurPreheader(CurLoop, CurPreheader); 6990b57cec5SDimitry Andric 7000b57cec5SDimitry Andric // Now move the instructions to the predecessor, inserting it before any 7010b57cec5SDimitry Andric // terminator instructions. 7020b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Hoisting to " << printMBBReference(*Preheader) 7030b57cec5SDimitry Andric << " from " << printMBBReference(*MI->getParent()) << ": " 7040b57cec5SDimitry Andric << *MI); 7050b57cec5SDimitry Andric 7060b57cec5SDimitry Andric // Splice the instruction to the preheader. 7070b57cec5SDimitry Andric MachineBasicBlock *MBB = MI->getParent(); 7080b57cec5SDimitry Andric Preheader->splice(Preheader->getFirstTerminator(), MBB, MI); 7090b57cec5SDimitry Andric 7105ffd83dbSDimitry Andric // Since we are moving the instruction out of its basic block, we do not 7115ffd83dbSDimitry Andric // retain its debug location. Doing so would degrade the debugging 7125ffd83dbSDimitry Andric // experience and adversely affect the accuracy of profiling information. 7135ffd83dbSDimitry Andric assert(!MI->isDebugInstr() && "Should not hoist debug inst"); 7145ffd83dbSDimitry Andric MI->setDebugLoc(DebugLoc()); 7155ffd83dbSDimitry Andric 7160b57cec5SDimitry Andric // Add register to livein list to all the BBs in the current loop since a 7170b57cec5SDimitry Andric // loop invariant must be kept live throughout the whole loop. This is 7180b57cec5SDimitry Andric // important to ensure later passes do not scavenge the def register. 7195f757f3fSDimitry Andric AddToLiveIns(Def, CurLoop); 7200b57cec5SDimitry Andric 7210b57cec5SDimitry Andric ++NumPostRAHoisted; 7220b57cec5SDimitry Andric Changed = true; 7230b57cec5SDimitry Andric } 7240b57cec5SDimitry Andric 7250b57cec5SDimitry Andric /// Check if this mbb is guaranteed to execute. If not then a load from this mbb 7260b57cec5SDimitry Andric /// may not be safe to hoist. 7275f757f3fSDimitry Andric bool MachineLICMBase::IsGuaranteedToExecute(MachineBasicBlock *BB, 7285f757f3fSDimitry Andric MachineLoop *CurLoop) { 7290b57cec5SDimitry Andric if (SpeculationState != SpeculateUnknown) 7300b57cec5SDimitry Andric return SpeculationState == SpeculateFalse; 7310b57cec5SDimitry Andric 7320b57cec5SDimitry Andric if (BB != CurLoop->getHeader()) { 7330b57cec5SDimitry Andric // Check loop exiting blocks. 7340b57cec5SDimitry Andric SmallVector<MachineBasicBlock*, 8> CurrentLoopExitingBlocks; 7350b57cec5SDimitry Andric CurLoop->getExitingBlocks(CurrentLoopExitingBlocks); 7360b57cec5SDimitry Andric for (MachineBasicBlock *CurrentLoopExitingBlock : CurrentLoopExitingBlocks) 7370b57cec5SDimitry Andric if (!DT->dominates(BB, CurrentLoopExitingBlock)) { 7380b57cec5SDimitry Andric SpeculationState = SpeculateTrue; 7390b57cec5SDimitry Andric return false; 7400b57cec5SDimitry Andric } 7410b57cec5SDimitry Andric } 7420b57cec5SDimitry Andric 7430b57cec5SDimitry Andric SpeculationState = SpeculateFalse; 7440b57cec5SDimitry Andric return true; 7450b57cec5SDimitry Andric } 7460b57cec5SDimitry Andric 747349cc55cSDimitry Andric /// Check if \p MI is trivially remateralizable and if it does not have any 748349cc55cSDimitry Andric /// virtual register uses. Even though rematerializable RA might not actually 749349cc55cSDimitry Andric /// rematerialize it in this scenario. In that case we do not want to hoist such 750349cc55cSDimitry Andric /// instruction out of the loop in a belief RA will sink it back if needed. 751fcaf7f86SDimitry Andric bool MachineLICMBase::isTriviallyReMaterializable( 752fcaf7f86SDimitry Andric const MachineInstr &MI) const { 753fcaf7f86SDimitry Andric if (!TII->isTriviallyReMaterializable(MI)) 754349cc55cSDimitry Andric return false; 755349cc55cSDimitry Andric 75606c3fb27SDimitry Andric for (const MachineOperand &MO : MI.all_uses()) { 75706c3fb27SDimitry Andric if (MO.getReg().isVirtual()) 758349cc55cSDimitry Andric return false; 759349cc55cSDimitry Andric } 760349cc55cSDimitry Andric 761349cc55cSDimitry Andric return true; 762349cc55cSDimitry Andric } 763349cc55cSDimitry Andric 7640b57cec5SDimitry Andric void MachineLICMBase::EnterScope(MachineBasicBlock *MBB) { 7650b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Entering " << printMBBReference(*MBB) << '\n'); 7660b57cec5SDimitry Andric 7670b57cec5SDimitry Andric // Remember livein register pressure. 7680b57cec5SDimitry Andric BackTrace.push_back(RegPressure); 7690b57cec5SDimitry Andric } 7700b57cec5SDimitry Andric 7710b57cec5SDimitry Andric void MachineLICMBase::ExitScope(MachineBasicBlock *MBB) { 7720b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Exiting " << printMBBReference(*MBB) << '\n'); 7730b57cec5SDimitry Andric BackTrace.pop_back(); 7740b57cec5SDimitry Andric } 7750b57cec5SDimitry Andric 7760b57cec5SDimitry Andric /// Destroy scope for the MBB that corresponds to the given dominator tree node 7770b57cec5SDimitry Andric /// if its a leaf or all of its children are done. Walk up the dominator tree to 7780b57cec5SDimitry Andric /// destroy ancestors which are now done. 7790b57cec5SDimitry Andric void MachineLICMBase::ExitScopeIfDone(MachineDomTreeNode *Node, 7800b57cec5SDimitry Andric DenseMap<MachineDomTreeNode*, unsigned> &OpenChildren, 78181ad6265SDimitry Andric const DenseMap<MachineDomTreeNode*, MachineDomTreeNode*> &ParentMap) { 7820b57cec5SDimitry Andric if (OpenChildren[Node]) 7830b57cec5SDimitry Andric return; 7840b57cec5SDimitry Andric 78581ad6265SDimitry Andric for(;;) { 7860b57cec5SDimitry Andric ExitScope(Node->getBlock()); 7870b57cec5SDimitry Andric // Now traverse upwards to pop ancestors whose offsprings are all done. 78881ad6265SDimitry Andric MachineDomTreeNode *Parent = ParentMap.lookup(Node); 78981ad6265SDimitry Andric if (!Parent || --OpenChildren[Parent] != 0) 7900b57cec5SDimitry Andric break; 7910b57cec5SDimitry Andric Node = Parent; 7920b57cec5SDimitry Andric } 7930b57cec5SDimitry Andric } 7940b57cec5SDimitry Andric 7950b57cec5SDimitry Andric /// Walk the specified loop in the CFG (defined by all blocks dominated by the 7960b57cec5SDimitry Andric /// specified header block, and that are in the current loop) in depth first 7970b57cec5SDimitry Andric /// order w.r.t the DominatorTree. This allows us to visit definitions before 7980b57cec5SDimitry Andric /// uses, allowing us to hoist a loop body in one pass without iteration. 7995f757f3fSDimitry Andric void MachineLICMBase::HoistOutOfLoop(MachineDomTreeNode *HeaderN, 8005f757f3fSDimitry Andric MachineLoop *CurLoop, 8015f757f3fSDimitry Andric MachineBasicBlock *CurPreheader) { 8025f757f3fSDimitry Andric MachineBasicBlock *Preheader = getCurPreheader(CurLoop, CurPreheader); 8030b57cec5SDimitry Andric if (!Preheader) 8040b57cec5SDimitry Andric return; 8050b57cec5SDimitry Andric 8060b57cec5SDimitry Andric SmallVector<MachineDomTreeNode*, 32> Scopes; 8070b57cec5SDimitry Andric SmallVector<MachineDomTreeNode*, 8> WorkList; 8080b57cec5SDimitry Andric DenseMap<MachineDomTreeNode*, MachineDomTreeNode*> ParentMap; 8090b57cec5SDimitry Andric DenseMap<MachineDomTreeNode*, unsigned> OpenChildren; 8100b57cec5SDimitry Andric 8110b57cec5SDimitry Andric // Perform a DFS walk to determine the order of visit. 8120b57cec5SDimitry Andric WorkList.push_back(HeaderN); 8130b57cec5SDimitry Andric while (!WorkList.empty()) { 8140b57cec5SDimitry Andric MachineDomTreeNode *Node = WorkList.pop_back_val(); 8150b57cec5SDimitry Andric assert(Node && "Null dominator tree node?"); 8160b57cec5SDimitry Andric MachineBasicBlock *BB = Node->getBlock(); 8170b57cec5SDimitry Andric 8180b57cec5SDimitry Andric // If the header of the loop containing this basic block is a landing pad, 8190b57cec5SDimitry Andric // then don't try to hoist instructions out of this loop. 8200b57cec5SDimitry Andric const MachineLoop *ML = MLI->getLoopFor(BB); 8210b57cec5SDimitry Andric if (ML && ML->getHeader()->isEHPad()) 8220b57cec5SDimitry Andric continue; 8230b57cec5SDimitry Andric 8240b57cec5SDimitry Andric // If this subregion is not in the top level loop at all, exit. 8250b57cec5SDimitry Andric if (!CurLoop->contains(BB)) 8260b57cec5SDimitry Andric continue; 8270b57cec5SDimitry Andric 8280b57cec5SDimitry Andric Scopes.push_back(Node); 8295ffd83dbSDimitry Andric unsigned NumChildren = Node->getNumChildren(); 8300b57cec5SDimitry Andric 8310b57cec5SDimitry Andric // Don't hoist things out of a large switch statement. This often causes 8320b57cec5SDimitry Andric // code to be hoisted that wasn't going to be executed, and increases 8330b57cec5SDimitry Andric // register pressure in a situation where it's likely to matter. 8340b57cec5SDimitry Andric if (BB->succ_size() >= 25) 8350b57cec5SDimitry Andric NumChildren = 0; 8360b57cec5SDimitry Andric 8370b57cec5SDimitry Andric OpenChildren[Node] = NumChildren; 8385ffd83dbSDimitry Andric if (NumChildren) { 8390b57cec5SDimitry Andric // Add children in reverse order as then the next popped worklist node is 8400b57cec5SDimitry Andric // the first child of this node. This means we ultimately traverse the 8410b57cec5SDimitry Andric // DOM tree in exactly the same order as if we'd recursed. 8425ffd83dbSDimitry Andric for (MachineDomTreeNode *Child : reverse(Node->children())) { 8430b57cec5SDimitry Andric ParentMap[Child] = Node; 8440b57cec5SDimitry Andric WorkList.push_back(Child); 8450b57cec5SDimitry Andric } 8460b57cec5SDimitry Andric } 8475ffd83dbSDimitry Andric } 8480b57cec5SDimitry Andric 8490b57cec5SDimitry Andric if (Scopes.size() == 0) 8500b57cec5SDimitry Andric return; 8510b57cec5SDimitry Andric 8520b57cec5SDimitry Andric // Compute registers which are livein into the loop headers. 8530b57cec5SDimitry Andric RegSeen.clear(); 8540b57cec5SDimitry Andric BackTrace.clear(); 8550b57cec5SDimitry Andric InitRegPressure(Preheader); 8560b57cec5SDimitry Andric 8570b57cec5SDimitry Andric // Now perform LICM. 8580b57cec5SDimitry Andric for (MachineDomTreeNode *Node : Scopes) { 8590b57cec5SDimitry Andric MachineBasicBlock *MBB = Node->getBlock(); 8600b57cec5SDimitry Andric 8610b57cec5SDimitry Andric EnterScope(MBB); 8620b57cec5SDimitry Andric 8630b57cec5SDimitry Andric // Process the block 8640b57cec5SDimitry Andric SpeculationState = SpeculateUnknown; 865349cc55cSDimitry Andric for (MachineInstr &MI : llvm::make_early_inc_range(*MBB)) { 8665f757f3fSDimitry Andric unsigned HoistRes = HoistResult::NotHoisted; 8675f757f3fSDimitry Andric HoistRes = Hoist(&MI, Preheader, CurLoop); 8685f757f3fSDimitry Andric if (HoistRes & HoistResult::NotHoisted) { 8695f757f3fSDimitry Andric // We have failed to hoist MI to outermost loop's preheader. If MI is in 8705f757f3fSDimitry Andric // a subloop, try to hoist it to subloop's preheader. 8715f757f3fSDimitry Andric SmallVector<MachineLoop *> InnerLoopWorkList; 8725f757f3fSDimitry Andric for (MachineLoop *L = MLI->getLoopFor(MI.getParent()); L != CurLoop; 8735f757f3fSDimitry Andric L = L->getParentLoop()) 8745f757f3fSDimitry Andric InnerLoopWorkList.push_back(L); 8755f757f3fSDimitry Andric 8765f757f3fSDimitry Andric while (!InnerLoopWorkList.empty()) { 8775f757f3fSDimitry Andric MachineLoop *InnerLoop = InnerLoopWorkList.pop_back_val(); 8785f757f3fSDimitry Andric MachineBasicBlock *InnerLoopPreheader = InnerLoop->getLoopPreheader(); 8795f757f3fSDimitry Andric if (InnerLoopPreheader) { 8805f757f3fSDimitry Andric HoistRes = Hoist(&MI, InnerLoopPreheader, InnerLoop); 8815f757f3fSDimitry Andric if (HoistRes & HoistResult::Hoisted) 8825f757f3fSDimitry Andric break; 8835f757f3fSDimitry Andric } 8845f757f3fSDimitry Andric } 8855f757f3fSDimitry Andric } 8865f757f3fSDimitry Andric 8875f757f3fSDimitry Andric if (HoistRes & HoistResult::ErasedMI) 8885f757f3fSDimitry Andric continue; 8895f757f3fSDimitry Andric 890349cc55cSDimitry Andric UpdateRegPressure(&MI); 8910b57cec5SDimitry Andric } 8920b57cec5SDimitry Andric 8930b57cec5SDimitry Andric // If it's a leaf node, it's done. Traverse upwards to pop ancestors. 8940b57cec5SDimitry Andric ExitScopeIfDone(Node, OpenChildren, ParentMap); 8950b57cec5SDimitry Andric } 8960b57cec5SDimitry Andric } 8970b57cec5SDimitry Andric 8980b57cec5SDimitry Andric static bool isOperandKill(const MachineOperand &MO, MachineRegisterInfo *MRI) { 8990b57cec5SDimitry Andric return MO.isKill() || MRI->hasOneNonDBGUse(MO.getReg()); 9000b57cec5SDimitry Andric } 9010b57cec5SDimitry Andric 9020b57cec5SDimitry Andric /// Find all virtual register references that are liveout of the preheader to 9030b57cec5SDimitry Andric /// initialize the starting "register pressure". Note this does not count live 9040b57cec5SDimitry Andric /// through (livein but not used) registers. 9050b57cec5SDimitry Andric void MachineLICMBase::InitRegPressure(MachineBasicBlock *BB) { 9060b57cec5SDimitry Andric std::fill(RegPressure.begin(), RegPressure.end(), 0); 9070b57cec5SDimitry Andric 9080b57cec5SDimitry Andric // If the preheader has only a single predecessor and it ends with a 9090b57cec5SDimitry Andric // fallthrough or an unconditional branch, then scan its predecessor for live 9100b57cec5SDimitry Andric // defs as well. This happens whenever the preheader is created by splitting 9110b57cec5SDimitry Andric // the critical edge from the loop predecessor to the loop header. 9120b57cec5SDimitry Andric if (BB->pred_size() == 1) { 9130b57cec5SDimitry Andric MachineBasicBlock *TBB = nullptr, *FBB = nullptr; 9140b57cec5SDimitry Andric SmallVector<MachineOperand, 4> Cond; 9150b57cec5SDimitry Andric if (!TII->analyzeBranch(*BB, TBB, FBB, Cond, false) && Cond.empty()) 9160b57cec5SDimitry Andric InitRegPressure(*BB->pred_begin()); 9170b57cec5SDimitry Andric } 9180b57cec5SDimitry Andric 9190b57cec5SDimitry Andric for (const MachineInstr &MI : *BB) 9200b57cec5SDimitry Andric UpdateRegPressure(&MI, /*ConsiderUnseenAsDef=*/true); 9210b57cec5SDimitry Andric } 9220b57cec5SDimitry Andric 9230b57cec5SDimitry Andric /// Update estimate of register pressure after the specified instruction. 9240b57cec5SDimitry Andric void MachineLICMBase::UpdateRegPressure(const MachineInstr *MI, 9250b57cec5SDimitry Andric bool ConsiderUnseenAsDef) { 9260b57cec5SDimitry Andric auto Cost = calcRegisterCost(MI, /*ConsiderSeen=*/true, ConsiderUnseenAsDef); 9270b57cec5SDimitry Andric for (const auto &RPIdAndCost : Cost) { 9280b57cec5SDimitry Andric unsigned Class = RPIdAndCost.first; 9290b57cec5SDimitry Andric if (static_cast<int>(RegPressure[Class]) < -RPIdAndCost.second) 9300b57cec5SDimitry Andric RegPressure[Class] = 0; 9310b57cec5SDimitry Andric else 9320b57cec5SDimitry Andric RegPressure[Class] += RPIdAndCost.second; 9330b57cec5SDimitry Andric } 9340b57cec5SDimitry Andric } 9350b57cec5SDimitry Andric 9360b57cec5SDimitry Andric /// Calculate the additional register pressure that the registers used in MI 9370b57cec5SDimitry Andric /// cause. 9380b57cec5SDimitry Andric /// 9390b57cec5SDimitry Andric /// If 'ConsiderSeen' is true, updates 'RegSeen' and uses the information to 9400b57cec5SDimitry Andric /// figure out which usages are live-ins. 9410b57cec5SDimitry Andric /// FIXME: Figure out a way to consider 'RegSeen' from all code paths. 9420b57cec5SDimitry Andric DenseMap<unsigned, int> 9430b57cec5SDimitry Andric MachineLICMBase::calcRegisterCost(const MachineInstr *MI, bool ConsiderSeen, 9440b57cec5SDimitry Andric bool ConsiderUnseenAsDef) { 9450b57cec5SDimitry Andric DenseMap<unsigned, int> Cost; 9460b57cec5SDimitry Andric if (MI->isImplicitDef()) 9470b57cec5SDimitry Andric return Cost; 9480b57cec5SDimitry Andric for (unsigned i = 0, e = MI->getDesc().getNumOperands(); i != e; ++i) { 9490b57cec5SDimitry Andric const MachineOperand &MO = MI->getOperand(i); 9500b57cec5SDimitry Andric if (!MO.isReg() || MO.isImplicit()) 9510b57cec5SDimitry Andric continue; 9528bcb0991SDimitry Andric Register Reg = MO.getReg(); 953bdd1243dSDimitry Andric if (!Reg.isVirtual()) 9540b57cec5SDimitry Andric continue; 9550b57cec5SDimitry Andric 9560b57cec5SDimitry Andric // FIXME: It seems bad to use RegSeen only for some of these calculations. 9570b57cec5SDimitry Andric bool isNew = ConsiderSeen ? RegSeen.insert(Reg).second : false; 9580b57cec5SDimitry Andric const TargetRegisterClass *RC = MRI->getRegClass(Reg); 9590b57cec5SDimitry Andric 9600b57cec5SDimitry Andric RegClassWeight W = TRI->getRegClassWeight(RC); 9610b57cec5SDimitry Andric int RCCost = 0; 9620b57cec5SDimitry Andric if (MO.isDef()) 9630b57cec5SDimitry Andric RCCost = W.RegWeight; 9640b57cec5SDimitry Andric else { 9650b57cec5SDimitry Andric bool isKill = isOperandKill(MO, MRI); 9660b57cec5SDimitry Andric if (isNew && !isKill && ConsiderUnseenAsDef) 9670b57cec5SDimitry Andric // Haven't seen this, it must be a livein. 9680b57cec5SDimitry Andric RCCost = W.RegWeight; 9690b57cec5SDimitry Andric else if (!isNew && isKill) 9700b57cec5SDimitry Andric RCCost = -W.RegWeight; 9710b57cec5SDimitry Andric } 9720b57cec5SDimitry Andric if (RCCost == 0) 9730b57cec5SDimitry Andric continue; 9740b57cec5SDimitry Andric const int *PS = TRI->getRegClassPressureSets(RC); 9750b57cec5SDimitry Andric for (; *PS != -1; ++PS) { 97606c3fb27SDimitry Andric if (!Cost.contains(*PS)) 9770b57cec5SDimitry Andric Cost[*PS] = RCCost; 9780b57cec5SDimitry Andric else 9790b57cec5SDimitry Andric Cost[*PS] += RCCost; 9800b57cec5SDimitry Andric } 9810b57cec5SDimitry Andric } 9820b57cec5SDimitry Andric return Cost; 9830b57cec5SDimitry Andric } 9840b57cec5SDimitry Andric 9850b57cec5SDimitry Andric /// Return true if this machine instruction loads from global offset table or 9860b57cec5SDimitry Andric /// constant pool. 9870b57cec5SDimitry Andric static bool mayLoadFromGOTOrConstantPool(MachineInstr &MI) { 9880b57cec5SDimitry Andric assert(MI.mayLoad() && "Expected MI that loads!"); 9890b57cec5SDimitry Andric 9900b57cec5SDimitry Andric // If we lost memory operands, conservatively assume that the instruction 9910b57cec5SDimitry Andric // reads from everything.. 9920b57cec5SDimitry Andric if (MI.memoperands_empty()) 9930b57cec5SDimitry Andric return true; 9940b57cec5SDimitry Andric 9950b57cec5SDimitry Andric for (MachineMemOperand *MemOp : MI.memoperands()) 9960b57cec5SDimitry Andric if (const PseudoSourceValue *PSV = MemOp->getPseudoValue()) 9970b57cec5SDimitry Andric if (PSV->isGOT() || PSV->isConstantPool()) 9980b57cec5SDimitry Andric return true; 9990b57cec5SDimitry Andric 10000b57cec5SDimitry Andric return false; 10010b57cec5SDimitry Andric } 10020b57cec5SDimitry Andric 10030b57cec5SDimitry Andric // This function iterates through all the operands of the input store MI and 10040b57cec5SDimitry Andric // checks that each register operand statisfies isCallerPreservedPhysReg. 10050b57cec5SDimitry Andric // This means, the value being stored and the address where it is being stored 10060b57cec5SDimitry Andric // is constant throughout the body of the function (not including prologue and 10070b57cec5SDimitry Andric // epilogue). When called with an MI that isn't a store, it returns false. 10080b57cec5SDimitry Andric // A future improvement can be to check if the store registers are constant 10090b57cec5SDimitry Andric // throughout the loop rather than throughout the funtion. 10100b57cec5SDimitry Andric static bool isInvariantStore(const MachineInstr &MI, 10110b57cec5SDimitry Andric const TargetRegisterInfo *TRI, 10120b57cec5SDimitry Andric const MachineRegisterInfo *MRI) { 10130b57cec5SDimitry Andric 10140b57cec5SDimitry Andric bool FoundCallerPresReg = false; 10150b57cec5SDimitry Andric if (!MI.mayStore() || MI.hasUnmodeledSideEffects() || 10160b57cec5SDimitry Andric (MI.getNumOperands() == 0)) 10170b57cec5SDimitry Andric return false; 10180b57cec5SDimitry Andric 10190b57cec5SDimitry Andric // Check that all register operands are caller-preserved physical registers. 10200b57cec5SDimitry Andric for (const MachineOperand &MO : MI.operands()) { 10210b57cec5SDimitry Andric if (MO.isReg()) { 10228bcb0991SDimitry Andric Register Reg = MO.getReg(); 10230b57cec5SDimitry Andric // If operand is a virtual register, check if it comes from a copy of a 10240b57cec5SDimitry Andric // physical register. 1025bdd1243dSDimitry Andric if (Reg.isVirtual()) 10260b57cec5SDimitry Andric Reg = TRI->lookThruCopyLike(MO.getReg(), MRI); 1027bdd1243dSDimitry Andric if (Reg.isVirtual()) 10280b57cec5SDimitry Andric return false; 1029e8d8bef9SDimitry Andric if (!TRI->isCallerPreservedPhysReg(Reg.asMCReg(), *MI.getMF())) 10300b57cec5SDimitry Andric return false; 10310b57cec5SDimitry Andric else 10320b57cec5SDimitry Andric FoundCallerPresReg = true; 10330b57cec5SDimitry Andric } else if (!MO.isImm()) { 10340b57cec5SDimitry Andric return false; 10350b57cec5SDimitry Andric } 10360b57cec5SDimitry Andric } 10370b57cec5SDimitry Andric return FoundCallerPresReg; 10380b57cec5SDimitry Andric } 10390b57cec5SDimitry Andric 10400b57cec5SDimitry Andric // Return true if the input MI is a copy instruction that feeds an invariant 10410b57cec5SDimitry Andric // store instruction. This means that the src of the copy has to satisfy 10420b57cec5SDimitry Andric // isCallerPreservedPhysReg and atleast one of it's users should satisfy 10430b57cec5SDimitry Andric // isInvariantStore. 10440b57cec5SDimitry Andric static bool isCopyFeedingInvariantStore(const MachineInstr &MI, 10450b57cec5SDimitry Andric const MachineRegisterInfo *MRI, 10460b57cec5SDimitry Andric const TargetRegisterInfo *TRI) { 10470b57cec5SDimitry Andric 10480b57cec5SDimitry Andric // FIXME: If targets would like to look through instructions that aren't 10490b57cec5SDimitry Andric // pure copies, this can be updated to a query. 10500b57cec5SDimitry Andric if (!MI.isCopy()) 10510b57cec5SDimitry Andric return false; 10520b57cec5SDimitry Andric 10530b57cec5SDimitry Andric const MachineFunction *MF = MI.getMF(); 10540b57cec5SDimitry Andric // Check that we are copying a constant physical register. 10558bcb0991SDimitry Andric Register CopySrcReg = MI.getOperand(1).getReg(); 1056bdd1243dSDimitry Andric if (CopySrcReg.isVirtual()) 10570b57cec5SDimitry Andric return false; 10580b57cec5SDimitry Andric 1059e8d8bef9SDimitry Andric if (!TRI->isCallerPreservedPhysReg(CopySrcReg.asMCReg(), *MF)) 10600b57cec5SDimitry Andric return false; 10610b57cec5SDimitry Andric 10628bcb0991SDimitry Andric Register CopyDstReg = MI.getOperand(0).getReg(); 10630b57cec5SDimitry Andric // Check if any of the uses of the copy are invariant stores. 1064bdd1243dSDimitry Andric assert(CopyDstReg.isVirtual() && "copy dst is not a virtual reg"); 10650b57cec5SDimitry Andric 10660b57cec5SDimitry Andric for (MachineInstr &UseMI : MRI->use_instructions(CopyDstReg)) { 10670b57cec5SDimitry Andric if (UseMI.mayStore() && isInvariantStore(UseMI, TRI, MRI)) 10680b57cec5SDimitry Andric return true; 10690b57cec5SDimitry Andric } 10700b57cec5SDimitry Andric return false; 10710b57cec5SDimitry Andric } 10720b57cec5SDimitry Andric 10730b57cec5SDimitry Andric /// Returns true if the instruction may be a suitable candidate for LICM. 10740b57cec5SDimitry Andric /// e.g. If the instruction is a call, then it's obviously not safe to hoist it. 10755f757f3fSDimitry Andric bool MachineLICMBase::IsLICMCandidate(MachineInstr &I, MachineLoop *CurLoop) { 10760b57cec5SDimitry Andric // Check if it's safe to move the instruction. 10775f757f3fSDimitry Andric bool DontMoveAcrossStore = !HoistConstLoads || !AllowedToHoistLoads[CurLoop]; 10780b57cec5SDimitry Andric if ((!I.isSafeToMove(AA, DontMoveAcrossStore)) && 10790b57cec5SDimitry Andric !(HoistConstStores && isInvariantStore(I, TRI, MRI))) { 1080e8d8bef9SDimitry Andric LLVM_DEBUG(dbgs() << "LICM: Instruction not safe to move.\n"); 10810b57cec5SDimitry Andric return false; 10820b57cec5SDimitry Andric } 10830b57cec5SDimitry Andric 1084fe6060f1SDimitry Andric // If it is a load then check if it is guaranteed to execute by making sure 1085fe6060f1SDimitry Andric // that it dominates all exiting blocks. If it doesn't, then there is a path 1086fe6060f1SDimitry Andric // out of the loop which does not execute this load, so we can't hoist it. 1087fe6060f1SDimitry Andric // Loads from constant memory are safe to speculate, for example indexed load 1088fe6060f1SDimitry Andric // from a jump table. 10890b57cec5SDimitry Andric // Stores and side effects are already checked by isSafeToMove. 10900b57cec5SDimitry Andric if (I.mayLoad() && !mayLoadFromGOTOrConstantPool(I) && 10915f757f3fSDimitry Andric !IsGuaranteedToExecute(I.getParent(), CurLoop)) { 1092e8d8bef9SDimitry Andric LLVM_DEBUG(dbgs() << "LICM: Load not guaranteed to execute.\n"); 1093e8d8bef9SDimitry Andric return false; 1094e8d8bef9SDimitry Andric } 1095e8d8bef9SDimitry Andric 1096e8d8bef9SDimitry Andric // Convergent attribute has been used on operations that involve inter-thread 1097e8d8bef9SDimitry Andric // communication which results are implicitly affected by the enclosing 1098e8d8bef9SDimitry Andric // control flows. It is not safe to hoist or sink such operations across 1099e8d8bef9SDimitry Andric // control flow. 1100e8d8bef9SDimitry Andric if (I.isConvergent()) 11010b57cec5SDimitry Andric return false; 11020b57cec5SDimitry Andric 110381ad6265SDimitry Andric if (!TII->shouldHoist(I, CurLoop)) 110481ad6265SDimitry Andric return false; 110581ad6265SDimitry Andric 11060b57cec5SDimitry Andric return true; 11070b57cec5SDimitry Andric } 11080b57cec5SDimitry Andric 11090b57cec5SDimitry Andric /// Returns true if the instruction is loop invariant. 11105f757f3fSDimitry Andric bool MachineLICMBase::IsLoopInvariantInst(MachineInstr &I, 11115f757f3fSDimitry Andric MachineLoop *CurLoop) { 11125f757f3fSDimitry Andric if (!IsLICMCandidate(I, CurLoop)) { 1113e8d8bef9SDimitry Andric LLVM_DEBUG(dbgs() << "LICM: Instruction not a LICM candidate\n"); 11140b57cec5SDimitry Andric return false; 11150b57cec5SDimitry Andric } 1116e8d8bef9SDimitry Andric return CurLoop->isLoopInvariant(I); 11170b57cec5SDimitry Andric } 11180b57cec5SDimitry Andric 11190b57cec5SDimitry Andric /// Return true if the specified instruction is used by a phi node and hoisting 11200b57cec5SDimitry Andric /// it could cause a copy to be inserted. 11215f757f3fSDimitry Andric bool MachineLICMBase::HasLoopPHIUse(const MachineInstr *MI, 11225f757f3fSDimitry Andric MachineLoop *CurLoop) { 11230b57cec5SDimitry Andric SmallVector<const MachineInstr *, 8> Work(1, MI); 11240b57cec5SDimitry Andric do { 11250b57cec5SDimitry Andric MI = Work.pop_back_val(); 112606c3fb27SDimitry Andric for (const MachineOperand &MO : MI->all_defs()) { 11278bcb0991SDimitry Andric Register Reg = MO.getReg(); 1128bdd1243dSDimitry Andric if (!Reg.isVirtual()) 11290b57cec5SDimitry Andric continue; 11300b57cec5SDimitry Andric for (MachineInstr &UseMI : MRI->use_instructions(Reg)) { 11310b57cec5SDimitry Andric // A PHI may cause a copy to be inserted. 11320b57cec5SDimitry Andric if (UseMI.isPHI()) { 11330b57cec5SDimitry Andric // A PHI inside the loop causes a copy because the live range of Reg is 11340b57cec5SDimitry Andric // extended across the PHI. 11350b57cec5SDimitry Andric if (CurLoop->contains(&UseMI)) 11360b57cec5SDimitry Andric return true; 11370b57cec5SDimitry Andric // A PHI in an exit block can cause a copy to be inserted if the PHI 11380b57cec5SDimitry Andric // has multiple predecessors in the loop with different values. 11390b57cec5SDimitry Andric // For now, approximate by rejecting all exit blocks. 11405f757f3fSDimitry Andric if (isExitBlock(CurLoop, UseMI.getParent())) 11410b57cec5SDimitry Andric return true; 11420b57cec5SDimitry Andric continue; 11430b57cec5SDimitry Andric } 11440b57cec5SDimitry Andric // Look past copies as well. 11450b57cec5SDimitry Andric if (UseMI.isCopy() && CurLoop->contains(&UseMI)) 11460b57cec5SDimitry Andric Work.push_back(&UseMI); 11470b57cec5SDimitry Andric } 11480b57cec5SDimitry Andric } 11490b57cec5SDimitry Andric } while (!Work.empty()); 11500b57cec5SDimitry Andric return false; 11510b57cec5SDimitry Andric } 11520b57cec5SDimitry Andric 11530b57cec5SDimitry Andric /// Compute operand latency between a def of 'Reg' and an use in the current 11540b57cec5SDimitry Andric /// loop, return true if the target considered it high. 1155e8d8bef9SDimitry Andric bool MachineLICMBase::HasHighOperandLatency(MachineInstr &MI, unsigned DefIdx, 11565f757f3fSDimitry Andric Register Reg, 11575f757f3fSDimitry Andric MachineLoop *CurLoop) const { 11580b57cec5SDimitry Andric if (MRI->use_nodbg_empty(Reg)) 11590b57cec5SDimitry Andric return false; 11600b57cec5SDimitry Andric 11610b57cec5SDimitry Andric for (MachineInstr &UseMI : MRI->use_nodbg_instructions(Reg)) { 11620b57cec5SDimitry Andric if (UseMI.isCopyLike()) 11630b57cec5SDimitry Andric continue; 11640b57cec5SDimitry Andric if (!CurLoop->contains(UseMI.getParent())) 11650b57cec5SDimitry Andric continue; 11660b57cec5SDimitry Andric for (unsigned i = 0, e = UseMI.getNumOperands(); i != e; ++i) { 11670b57cec5SDimitry Andric const MachineOperand &MO = UseMI.getOperand(i); 11680b57cec5SDimitry Andric if (!MO.isReg() || !MO.isUse()) 11690b57cec5SDimitry Andric continue; 11708bcb0991SDimitry Andric Register MOReg = MO.getReg(); 11710b57cec5SDimitry Andric if (MOReg != Reg) 11720b57cec5SDimitry Andric continue; 11730b57cec5SDimitry Andric 11740b57cec5SDimitry Andric if (TII->hasHighOperandLatency(SchedModel, MRI, MI, DefIdx, UseMI, i)) 11750b57cec5SDimitry Andric return true; 11760b57cec5SDimitry Andric } 11770b57cec5SDimitry Andric 11780b57cec5SDimitry Andric // Only look at the first in loop use. 11790b57cec5SDimitry Andric break; 11800b57cec5SDimitry Andric } 11810b57cec5SDimitry Andric 11820b57cec5SDimitry Andric return false; 11830b57cec5SDimitry Andric } 11840b57cec5SDimitry Andric 11850b57cec5SDimitry Andric /// Return true if the instruction is marked "cheap" or the operand latency 11860b57cec5SDimitry Andric /// between its def and a use is one or less. 11870b57cec5SDimitry Andric bool MachineLICMBase::IsCheapInstruction(MachineInstr &MI) const { 11880b57cec5SDimitry Andric if (TII->isAsCheapAsAMove(MI) || MI.isCopyLike()) 11890b57cec5SDimitry Andric return true; 11900b57cec5SDimitry Andric 11910b57cec5SDimitry Andric bool isCheap = false; 11920b57cec5SDimitry Andric unsigned NumDefs = MI.getDesc().getNumDefs(); 11930b57cec5SDimitry Andric for (unsigned i = 0, e = MI.getNumOperands(); NumDefs && i != e; ++i) { 11940b57cec5SDimitry Andric MachineOperand &DefMO = MI.getOperand(i); 11950b57cec5SDimitry Andric if (!DefMO.isReg() || !DefMO.isDef()) 11960b57cec5SDimitry Andric continue; 11970b57cec5SDimitry Andric --NumDefs; 11988bcb0991SDimitry Andric Register Reg = DefMO.getReg(); 1199bdd1243dSDimitry Andric if (Reg.isPhysical()) 12000b57cec5SDimitry Andric continue; 12010b57cec5SDimitry Andric 12020b57cec5SDimitry Andric if (!TII->hasLowDefLatency(SchedModel, MI, i)) 12030b57cec5SDimitry Andric return false; 12040b57cec5SDimitry Andric isCheap = true; 12050b57cec5SDimitry Andric } 12060b57cec5SDimitry Andric 12070b57cec5SDimitry Andric return isCheap; 12080b57cec5SDimitry Andric } 12090b57cec5SDimitry Andric 12100b57cec5SDimitry Andric /// Visit BBs from header to current BB, check if hoisting an instruction of the 12110b57cec5SDimitry Andric /// given cost matrix can cause high register pressure. 12120b57cec5SDimitry Andric bool 12130b57cec5SDimitry Andric MachineLICMBase::CanCauseHighRegPressure(const DenseMap<unsigned, int>& Cost, 12140b57cec5SDimitry Andric bool CheapInstr) { 12150b57cec5SDimitry Andric for (const auto &RPIdAndCost : Cost) { 12160b57cec5SDimitry Andric if (RPIdAndCost.second <= 0) 12170b57cec5SDimitry Andric continue; 12180b57cec5SDimitry Andric 12190b57cec5SDimitry Andric unsigned Class = RPIdAndCost.first; 12200b57cec5SDimitry Andric int Limit = RegLimit[Class]; 12210b57cec5SDimitry Andric 12220b57cec5SDimitry Andric // Don't hoist cheap instructions if they would increase register pressure, 12230b57cec5SDimitry Andric // even if we're under the limit. 12240b57cec5SDimitry Andric if (CheapInstr && !HoistCheapInsts) 12250b57cec5SDimitry Andric return true; 12260b57cec5SDimitry Andric 12270b57cec5SDimitry Andric for (const auto &RP : BackTrace) 12280b57cec5SDimitry Andric if (static_cast<int>(RP[Class]) + RPIdAndCost.second >= Limit) 12290b57cec5SDimitry Andric return true; 12300b57cec5SDimitry Andric } 12310b57cec5SDimitry Andric 12320b57cec5SDimitry Andric return false; 12330b57cec5SDimitry Andric } 12340b57cec5SDimitry Andric 12350b57cec5SDimitry Andric /// Traverse the back trace from header to the current block and update their 12360b57cec5SDimitry Andric /// register pressures to reflect the effect of hoisting MI from the current 12370b57cec5SDimitry Andric /// block to the preheader. 12380b57cec5SDimitry Andric void MachineLICMBase::UpdateBackTraceRegPressure(const MachineInstr *MI) { 12390b57cec5SDimitry Andric // First compute the 'cost' of the instruction, i.e. its contribution 12400b57cec5SDimitry Andric // to register pressure. 12410b57cec5SDimitry Andric auto Cost = calcRegisterCost(MI, /*ConsiderSeen=*/false, 12420b57cec5SDimitry Andric /*ConsiderUnseenAsDef=*/false); 12430b57cec5SDimitry Andric 12440b57cec5SDimitry Andric // Update register pressure of blocks from loop header to current block. 12450b57cec5SDimitry Andric for (auto &RP : BackTrace) 12460b57cec5SDimitry Andric for (const auto &RPIdAndCost : Cost) 12470b57cec5SDimitry Andric RP[RPIdAndCost.first] += RPIdAndCost.second; 12480b57cec5SDimitry Andric } 12490b57cec5SDimitry Andric 12500b57cec5SDimitry Andric /// Return true if it is potentially profitable to hoist the given loop 12510b57cec5SDimitry Andric /// invariant. 12525f757f3fSDimitry Andric bool MachineLICMBase::IsProfitableToHoist(MachineInstr &MI, 12535f757f3fSDimitry Andric MachineLoop *CurLoop) { 12540b57cec5SDimitry Andric if (MI.isImplicitDef()) 12550b57cec5SDimitry Andric return true; 12560b57cec5SDimitry Andric 12570b57cec5SDimitry Andric // Besides removing computation from the loop, hoisting an instruction has 12580b57cec5SDimitry Andric // these effects: 12590b57cec5SDimitry Andric // 12600b57cec5SDimitry Andric // - The value defined by the instruction becomes live across the entire 12610b57cec5SDimitry Andric // loop. This increases register pressure in the loop. 12620b57cec5SDimitry Andric // 12630b57cec5SDimitry Andric // - If the value is used by a PHI in the loop, a copy will be required for 12640b57cec5SDimitry Andric // lowering the PHI after extending the live range. 12650b57cec5SDimitry Andric // 12660b57cec5SDimitry Andric // - When hoisting the last use of a value in the loop, that value no longer 12670b57cec5SDimitry Andric // needs to be live in the loop. This lowers register pressure in the loop. 12680b57cec5SDimitry Andric 12690b57cec5SDimitry Andric if (HoistConstStores && isCopyFeedingInvariantStore(MI, MRI, TRI)) 12700b57cec5SDimitry Andric return true; 12710b57cec5SDimitry Andric 12720b57cec5SDimitry Andric bool CheapInstr = IsCheapInstruction(MI); 12735f757f3fSDimitry Andric bool CreatesCopy = HasLoopPHIUse(&MI, CurLoop); 12740b57cec5SDimitry Andric 12750b57cec5SDimitry Andric // Don't hoist a cheap instruction if it would create a copy in the loop. 12760b57cec5SDimitry Andric if (CheapInstr && CreatesCopy) { 12770b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Won't hoist cheap instr with loop PHI use: " << MI); 12780b57cec5SDimitry Andric return false; 12790b57cec5SDimitry Andric } 12800b57cec5SDimitry Andric 1281349cc55cSDimitry Andric // Rematerializable instructions should always be hoisted providing the 1282349cc55cSDimitry Andric // register allocator can just pull them down again when needed. 1283fcaf7f86SDimitry Andric if (isTriviallyReMaterializable(MI)) 12840b57cec5SDimitry Andric return true; 12850b57cec5SDimitry Andric 12860b57cec5SDimitry Andric // FIXME: If there are long latency loop-invariant instructions inside the 12870b57cec5SDimitry Andric // loop at this point, why didn't the optimizer's LICM hoist them? 12880b57cec5SDimitry Andric for (unsigned i = 0, e = MI.getDesc().getNumOperands(); i != e; ++i) { 12890b57cec5SDimitry Andric const MachineOperand &MO = MI.getOperand(i); 12900b57cec5SDimitry Andric if (!MO.isReg() || MO.isImplicit()) 12910b57cec5SDimitry Andric continue; 12928bcb0991SDimitry Andric Register Reg = MO.getReg(); 1293bdd1243dSDimitry Andric if (!Reg.isVirtual()) 12940b57cec5SDimitry Andric continue; 12955f757f3fSDimitry Andric if (MO.isDef() && HasHighOperandLatency(MI, i, Reg, CurLoop)) { 12960b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Hoist High Latency: " << MI); 12970b57cec5SDimitry Andric ++NumHighLatency; 12980b57cec5SDimitry Andric return true; 12990b57cec5SDimitry Andric } 13000b57cec5SDimitry Andric } 13010b57cec5SDimitry Andric 13020b57cec5SDimitry Andric // Estimate register pressure to determine whether to LICM the instruction. 13030b57cec5SDimitry Andric // In low register pressure situation, we can be more aggressive about 13040b57cec5SDimitry Andric // hoisting. Also, favors hoisting long latency instructions even in 13050b57cec5SDimitry Andric // moderately high pressure situation. 13060b57cec5SDimitry Andric // Cheap instructions will only be hoisted if they don't increase register 13070b57cec5SDimitry Andric // pressure at all. 13080b57cec5SDimitry Andric auto Cost = calcRegisterCost(&MI, /*ConsiderSeen=*/false, 13090b57cec5SDimitry Andric /*ConsiderUnseenAsDef=*/false); 13100b57cec5SDimitry Andric 13110b57cec5SDimitry Andric // Visit BBs from header to current BB, if hoisting this doesn't cause 13120b57cec5SDimitry Andric // high register pressure, then it's safe to proceed. 13130b57cec5SDimitry Andric if (!CanCauseHighRegPressure(Cost, CheapInstr)) { 13140b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Hoist non-reg-pressure: " << MI); 13150b57cec5SDimitry Andric ++NumLowRP; 13160b57cec5SDimitry Andric return true; 13170b57cec5SDimitry Andric } 13180b57cec5SDimitry Andric 13190b57cec5SDimitry Andric // Don't risk increasing register pressure if it would create copies. 13200b57cec5SDimitry Andric if (CreatesCopy) { 13210b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Won't hoist instr with loop PHI use: " << MI); 13220b57cec5SDimitry Andric return false; 13230b57cec5SDimitry Andric } 13240b57cec5SDimitry Andric 13250b57cec5SDimitry Andric // Do not "speculate" in high register pressure situation. If an 13260b57cec5SDimitry Andric // instruction is not guaranteed to be executed in the loop, it's best to be 13270b57cec5SDimitry Andric // conservative. 13280b57cec5SDimitry Andric if (AvoidSpeculation && 13295f757f3fSDimitry Andric (!IsGuaranteedToExecute(MI.getParent(), CurLoop) && !MayCSE(&MI))) { 13300b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Won't speculate: " << MI); 13310b57cec5SDimitry Andric return false; 13320b57cec5SDimitry Andric } 13330b57cec5SDimitry Andric 13345f757f3fSDimitry Andric // If we have a COPY with other uses in the loop, hoist to allow the users to 13355f757f3fSDimitry Andric // also be hoisted. 13360fca6ea1SDimitry Andric // TODO: Handle all isCopyLike? 13370fca6ea1SDimitry Andric if (MI.isCopy() || MI.isRegSequence()) { 13380fca6ea1SDimitry Andric Register DefReg = MI.getOperand(0).getReg(); 13390fca6ea1SDimitry Andric if (DefReg.isVirtual() && 13400fca6ea1SDimitry Andric all_of(MI.uses(), 13410fca6ea1SDimitry Andric [this](const MachineOperand &UseOp) { 13420fca6ea1SDimitry Andric return !UseOp.isReg() || UseOp.getReg().isVirtual() || 13430fca6ea1SDimitry Andric MRI->isConstantPhysReg(UseOp.getReg()); 13440fca6ea1SDimitry Andric }) && 13455f757f3fSDimitry Andric IsLoopInvariantInst(MI, CurLoop) && 13460fca6ea1SDimitry Andric any_of(MRI->use_nodbg_instructions(DefReg), 13470fca6ea1SDimitry Andric [&CurLoop, this, DefReg, Cost](MachineInstr &UseMI) { 13480fca6ea1SDimitry Andric if (!CurLoop->contains(&UseMI)) 13490fca6ea1SDimitry Andric return false; 13500fca6ea1SDimitry Andric 13510fca6ea1SDimitry Andric // COPY is a cheap instruction, but if moving it won't cause 13520fca6ea1SDimitry Andric // high RP we're fine to hoist it even if the user can't be 13530fca6ea1SDimitry Andric // hoisted later Otherwise we want to check the user if it's 13540fca6ea1SDimitry Andric // hoistable 13550fca6ea1SDimitry Andric if (CanCauseHighRegPressure(Cost, false) && 13560fca6ea1SDimitry Andric !CurLoop->isLoopInvariant(UseMI, DefReg)) 13570fca6ea1SDimitry Andric return false; 13580fca6ea1SDimitry Andric 13590fca6ea1SDimitry Andric return true; 13605f757f3fSDimitry Andric })) 13615f757f3fSDimitry Andric return true; 13620fca6ea1SDimitry Andric } 13635f757f3fSDimitry Andric 13640b57cec5SDimitry Andric // High register pressure situation, only hoist if the instruction is going 13650b57cec5SDimitry Andric // to be remat'ed. 1366fcaf7f86SDimitry Andric if (!isTriviallyReMaterializable(MI) && 1367fcaf7f86SDimitry Andric !MI.isDereferenceableInvariantLoad()) { 13680b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Can't remat / high reg-pressure: " << MI); 13690b57cec5SDimitry Andric return false; 13700b57cec5SDimitry Andric } 13710b57cec5SDimitry Andric 13720b57cec5SDimitry Andric return true; 13730b57cec5SDimitry Andric } 13740b57cec5SDimitry Andric 13750b57cec5SDimitry Andric /// Unfold a load from the given machineinstr if the load itself could be 13760b57cec5SDimitry Andric /// hoisted. Return the unfolded and hoistable load, or null if the load 13770b57cec5SDimitry Andric /// couldn't be unfolded or if it wouldn't be hoistable. 13785f757f3fSDimitry Andric MachineInstr *MachineLICMBase::ExtractHoistableLoad(MachineInstr *MI, 13795f757f3fSDimitry Andric MachineLoop *CurLoop) { 13800b57cec5SDimitry Andric // Don't unfold simple loads. 13810b57cec5SDimitry Andric if (MI->canFoldAsLoad()) 13820b57cec5SDimitry Andric return nullptr; 13830b57cec5SDimitry Andric 13840b57cec5SDimitry Andric // If not, we may be able to unfold a load and hoist that. 13850b57cec5SDimitry Andric // First test whether the instruction is loading from an amenable 13860b57cec5SDimitry Andric // memory location. 1387fcaf7f86SDimitry Andric if (!MI->isDereferenceableInvariantLoad()) 13880b57cec5SDimitry Andric return nullptr; 13890b57cec5SDimitry Andric 13900b57cec5SDimitry Andric // Next determine the register class for a temporary register. 13910b57cec5SDimitry Andric unsigned LoadRegIndex; 13920b57cec5SDimitry Andric unsigned NewOpc = 13930b57cec5SDimitry Andric TII->getOpcodeAfterMemoryUnfold(MI->getOpcode(), 13940b57cec5SDimitry Andric /*UnfoldLoad=*/true, 13950b57cec5SDimitry Andric /*UnfoldStore=*/false, 13960b57cec5SDimitry Andric &LoadRegIndex); 13970b57cec5SDimitry Andric if (NewOpc == 0) return nullptr; 13980b57cec5SDimitry Andric const MCInstrDesc &MID = TII->get(NewOpc); 13990b57cec5SDimitry Andric MachineFunction &MF = *MI->getMF(); 14000b57cec5SDimitry Andric const TargetRegisterClass *RC = TII->getRegClass(MID, LoadRegIndex, TRI, MF); 14010b57cec5SDimitry Andric // Ok, we're unfolding. Create a temporary register and do the unfold. 14028bcb0991SDimitry Andric Register Reg = MRI->createVirtualRegister(RC); 14030b57cec5SDimitry Andric 14040b57cec5SDimitry Andric SmallVector<MachineInstr *, 2> NewMIs; 14050b57cec5SDimitry Andric bool Success = TII->unfoldMemoryOperand(MF, *MI, Reg, 14060b57cec5SDimitry Andric /*UnfoldLoad=*/true, 14070b57cec5SDimitry Andric /*UnfoldStore=*/false, NewMIs); 14080b57cec5SDimitry Andric (void)Success; 14090b57cec5SDimitry Andric assert(Success && 14100b57cec5SDimitry Andric "unfoldMemoryOperand failed when getOpcodeAfterMemoryUnfold " 14110b57cec5SDimitry Andric "succeeded!"); 14120b57cec5SDimitry Andric assert(NewMIs.size() == 2 && 14130b57cec5SDimitry Andric "Unfolded a load into multiple instructions!"); 14140b57cec5SDimitry Andric MachineBasicBlock *MBB = MI->getParent(); 14150b57cec5SDimitry Andric MachineBasicBlock::iterator Pos = MI; 14160b57cec5SDimitry Andric MBB->insert(Pos, NewMIs[0]); 14170b57cec5SDimitry Andric MBB->insert(Pos, NewMIs[1]); 14180b57cec5SDimitry Andric // If unfolding produced a load that wasn't loop-invariant or profitable to 14190b57cec5SDimitry Andric // hoist, discard the new instructions and bail. 14205f757f3fSDimitry Andric if (!IsLoopInvariantInst(*NewMIs[0], CurLoop) || 14215f757f3fSDimitry Andric !IsProfitableToHoist(*NewMIs[0], CurLoop)) { 14220b57cec5SDimitry Andric NewMIs[0]->eraseFromParent(); 14230b57cec5SDimitry Andric NewMIs[1]->eraseFromParent(); 14240b57cec5SDimitry Andric return nullptr; 14250b57cec5SDimitry Andric } 14260b57cec5SDimitry Andric 14270b57cec5SDimitry Andric // Update register pressure for the unfolded instruction. 14280b57cec5SDimitry Andric UpdateRegPressure(NewMIs[1]); 14290b57cec5SDimitry Andric 14300b57cec5SDimitry Andric // Otherwise we successfully unfolded a load that we can hoist. 14315ffd83dbSDimitry Andric 14325ffd83dbSDimitry Andric // Update the call site info. 14335ffd83dbSDimitry Andric if (MI->shouldUpdateCallSiteInfo()) 14345ffd83dbSDimitry Andric MF.eraseCallSiteInfo(MI); 14355ffd83dbSDimitry Andric 14360b57cec5SDimitry Andric MI->eraseFromParent(); 14370b57cec5SDimitry Andric return NewMIs[0]; 14380b57cec5SDimitry Andric } 14390b57cec5SDimitry Andric 14400b57cec5SDimitry Andric /// Initialize the CSE map with instructions that are in the current loop 14410b57cec5SDimitry Andric /// preheader that may become duplicates of instructions that are hoisted 14420b57cec5SDimitry Andric /// out of the loop. 14430b57cec5SDimitry Andric void MachineLICMBase::InitCSEMap(MachineBasicBlock *BB) { 14440b57cec5SDimitry Andric for (MachineInstr &MI : *BB) 14455f757f3fSDimitry Andric CSEMap[BB][MI.getOpcode()].push_back(&MI); 14465f757f3fSDimitry Andric } 14475f757f3fSDimitry Andric 14485f757f3fSDimitry Andric /// Initialize AllowedToHoistLoads with information about whether invariant 14495f757f3fSDimitry Andric /// loads can be moved outside a given loop 14505f757f3fSDimitry Andric void MachineLICMBase::InitializeLoadsHoistableLoops() { 14515f757f3fSDimitry Andric SmallVector<MachineLoop *, 8> Worklist(MLI->begin(), MLI->end()); 14525f757f3fSDimitry Andric SmallVector<MachineLoop *, 8> LoopsInPreOrder; 14535f757f3fSDimitry Andric 14545f757f3fSDimitry Andric // Mark all loops as hoistable initially and prepare a list of loops in 14555f757f3fSDimitry Andric // pre-order DFS. 14565f757f3fSDimitry Andric while (!Worklist.empty()) { 14575f757f3fSDimitry Andric auto *L = Worklist.pop_back_val(); 14585f757f3fSDimitry Andric AllowedToHoistLoads[L] = true; 14595f757f3fSDimitry Andric LoopsInPreOrder.push_back(L); 14605f757f3fSDimitry Andric Worklist.insert(Worklist.end(), L->getSubLoops().begin(), 14615f757f3fSDimitry Andric L->getSubLoops().end()); 14625f757f3fSDimitry Andric } 14635f757f3fSDimitry Andric 14645f757f3fSDimitry Andric // Going from the innermost to outermost loops, check if a loop has 14655f757f3fSDimitry Andric // instructions preventing invariant load hoisting. If such instruction is 14665f757f3fSDimitry Andric // found, mark this loop and its parent as non-hoistable and continue 14675f757f3fSDimitry Andric // investigating the next loop. 14685f757f3fSDimitry Andric // Visiting in a reversed pre-ordered DFS manner 14695f757f3fSDimitry Andric // allows us to not process all the instructions of the outer loop if the 14705f757f3fSDimitry Andric // inner loop is proved to be non-load-hoistable. 14715f757f3fSDimitry Andric for (auto *Loop : reverse(LoopsInPreOrder)) { 14725f757f3fSDimitry Andric for (auto *MBB : Loop->blocks()) { 14735f757f3fSDimitry Andric // If this loop has already been marked as non-hoistable, skip it. 14745f757f3fSDimitry Andric if (!AllowedToHoistLoads[Loop]) 14755f757f3fSDimitry Andric continue; 14765f757f3fSDimitry Andric for (auto &MI : *MBB) { 1477*71ac745dSDimitry Andric if (!MI.isLoadFoldBarrier() && !MI.mayStore() && !MI.isCall() && 14785f757f3fSDimitry Andric !(MI.mayLoad() && MI.hasOrderedMemoryRef())) 14795f757f3fSDimitry Andric continue; 14805f757f3fSDimitry Andric for (MachineLoop *L = Loop; L != nullptr; L = L->getParentLoop()) 14815f757f3fSDimitry Andric AllowedToHoistLoads[L] = false; 14825f757f3fSDimitry Andric break; 14835f757f3fSDimitry Andric } 14845f757f3fSDimitry Andric } 14855f757f3fSDimitry Andric } 14860b57cec5SDimitry Andric } 14870b57cec5SDimitry Andric 14880b57cec5SDimitry Andric /// Find an instruction amount PrevMIs that is a duplicate of MI. 14890b57cec5SDimitry Andric /// Return this instruction if it's found. 1490e8d8bef9SDimitry Andric MachineInstr * 14910b57cec5SDimitry Andric MachineLICMBase::LookForDuplicate(const MachineInstr *MI, 1492e8d8bef9SDimitry Andric std::vector<MachineInstr *> &PrevMIs) { 1493e8d8bef9SDimitry Andric for (MachineInstr *PrevMI : PrevMIs) 14940b57cec5SDimitry Andric if (TII->produceSameValue(*MI, *PrevMI, (PreRegAlloc ? MRI : nullptr))) 14950b57cec5SDimitry Andric return PrevMI; 14960b57cec5SDimitry Andric 14970b57cec5SDimitry Andric return nullptr; 14980b57cec5SDimitry Andric } 14990b57cec5SDimitry Andric 15000b57cec5SDimitry Andric /// Given a LICM'ed instruction, look for an instruction on the preheader that 15010b57cec5SDimitry Andric /// computes the same value. If it's found, do a RAU on with the definition of 15020b57cec5SDimitry Andric /// the existing instruction rather than hoisting the instruction to the 15030b57cec5SDimitry Andric /// preheader. 1504e8d8bef9SDimitry Andric bool MachineLICMBase::EliminateCSE( 1505e8d8bef9SDimitry Andric MachineInstr *MI, 1506e8d8bef9SDimitry Andric DenseMap<unsigned, std::vector<MachineInstr *>>::iterator &CI) { 15070b57cec5SDimitry Andric // Do not CSE implicit_def so ProcessImplicitDefs can properly propagate 15080b57cec5SDimitry Andric // the undef property onto uses. 15095f757f3fSDimitry Andric if (MI->isImplicitDef()) 15105f757f3fSDimitry Andric return false; 15115f757f3fSDimitry Andric 15125f757f3fSDimitry Andric // Do not CSE normal loads because between them could be store instructions 15135f757f3fSDimitry Andric // that change the loaded value 15145f757f3fSDimitry Andric if (MI->mayLoad() && !MI->isDereferenceableInvariantLoad()) 15150b57cec5SDimitry Andric return false; 15160b57cec5SDimitry Andric 1517e8d8bef9SDimitry Andric if (MachineInstr *Dup = LookForDuplicate(MI, CI->second)) { 15180b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "CSEing " << *MI << " with " << *Dup); 15190b57cec5SDimitry Andric 15200b57cec5SDimitry Andric // Replace virtual registers defined by MI by their counterparts defined 15210b57cec5SDimitry Andric // by Dup. 15220b57cec5SDimitry Andric SmallVector<unsigned, 2> Defs; 15230b57cec5SDimitry Andric for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 15240b57cec5SDimitry Andric const MachineOperand &MO = MI->getOperand(i); 15250b57cec5SDimitry Andric 15260b57cec5SDimitry Andric // Physical registers may not differ here. 1527bdd1243dSDimitry Andric assert((!MO.isReg() || MO.getReg() == 0 || !MO.getReg().isPhysical() || 15280b57cec5SDimitry Andric MO.getReg() == Dup->getOperand(i).getReg()) && 15290b57cec5SDimitry Andric "Instructions with different phys regs are not identical!"); 15300b57cec5SDimitry Andric 1531bdd1243dSDimitry Andric if (MO.isReg() && MO.isDef() && !MO.getReg().isPhysical()) 15320b57cec5SDimitry Andric Defs.push_back(i); 15330b57cec5SDimitry Andric } 15340b57cec5SDimitry Andric 15350b57cec5SDimitry Andric SmallVector<const TargetRegisterClass*, 2> OrigRCs; 15360b57cec5SDimitry Andric for (unsigned i = 0, e = Defs.size(); i != e; ++i) { 15370b57cec5SDimitry Andric unsigned Idx = Defs[i]; 15388bcb0991SDimitry Andric Register Reg = MI->getOperand(Idx).getReg(); 15398bcb0991SDimitry Andric Register DupReg = Dup->getOperand(Idx).getReg(); 15400b57cec5SDimitry Andric OrigRCs.push_back(MRI->getRegClass(DupReg)); 15410b57cec5SDimitry Andric 15420b57cec5SDimitry Andric if (!MRI->constrainRegClass(DupReg, MRI->getRegClass(Reg))) { 15430b57cec5SDimitry Andric // Restore old RCs if more than one defs. 15440b57cec5SDimitry Andric for (unsigned j = 0; j != i; ++j) 15450b57cec5SDimitry Andric MRI->setRegClass(Dup->getOperand(Defs[j]).getReg(), OrigRCs[j]); 15460b57cec5SDimitry Andric return false; 15470b57cec5SDimitry Andric } 15480b57cec5SDimitry Andric } 15490b57cec5SDimitry Andric 15500b57cec5SDimitry Andric for (unsigned Idx : Defs) { 15518bcb0991SDimitry Andric Register Reg = MI->getOperand(Idx).getReg(); 15528bcb0991SDimitry Andric Register DupReg = Dup->getOperand(Idx).getReg(); 15530b57cec5SDimitry Andric MRI->replaceRegWith(Reg, DupReg); 15540b57cec5SDimitry Andric MRI->clearKillFlags(DupReg); 1555e8d8bef9SDimitry Andric // Clear Dup dead flag if any, we reuse it for Reg. 1556e8d8bef9SDimitry Andric if (!MRI->use_nodbg_empty(DupReg)) 1557e8d8bef9SDimitry Andric Dup->getOperand(Idx).setIsDead(false); 15580b57cec5SDimitry Andric } 15590b57cec5SDimitry Andric 15600b57cec5SDimitry Andric MI->eraseFromParent(); 15610b57cec5SDimitry Andric ++NumCSEed; 15620b57cec5SDimitry Andric return true; 15630b57cec5SDimitry Andric } 15640b57cec5SDimitry Andric return false; 15650b57cec5SDimitry Andric } 15660b57cec5SDimitry Andric 15670b57cec5SDimitry Andric /// Return true if the given instruction will be CSE'd if it's hoisted out of 15680b57cec5SDimitry Andric /// the loop. 15690b57cec5SDimitry Andric bool MachineLICMBase::MayCSE(MachineInstr *MI) { 15705f757f3fSDimitry Andric if (MI->mayLoad() && !MI->isDereferenceableInvariantLoad()) 15710b57cec5SDimitry Andric return false; 15720b57cec5SDimitry Andric 15735f757f3fSDimitry Andric unsigned Opcode = MI->getOpcode(); 15745f757f3fSDimitry Andric for (auto &Map : CSEMap) { 15755f757f3fSDimitry Andric // Check this CSEMap's preheader dominates MI's basic block. 15765f757f3fSDimitry Andric if (DT->dominates(Map.first, MI->getParent())) { 15775f757f3fSDimitry Andric DenseMap<unsigned, std::vector<MachineInstr *>>::iterator CI = 15785f757f3fSDimitry Andric Map.second.find(Opcode); 15795f757f3fSDimitry Andric // Do not CSE implicit_def so ProcessImplicitDefs can properly propagate 15805f757f3fSDimitry Andric // the undef property onto uses. 15815f757f3fSDimitry Andric if (CI == Map.second.end() || MI->isImplicitDef()) 15825f757f3fSDimitry Andric continue; 15835f757f3fSDimitry Andric if (LookForDuplicate(MI, CI->second) != nullptr) 15845f757f3fSDimitry Andric return true; 15855f757f3fSDimitry Andric } 15865f757f3fSDimitry Andric } 15875f757f3fSDimitry Andric 15885f757f3fSDimitry Andric return false; 15890b57cec5SDimitry Andric } 15900b57cec5SDimitry Andric 15910b57cec5SDimitry Andric /// When an instruction is found to use only loop invariant operands 15920b57cec5SDimitry Andric /// that are safe to hoist, this instruction is called to do the dirty work. 15930b57cec5SDimitry Andric /// It returns true if the instruction is hoisted. 15945f757f3fSDimitry Andric unsigned MachineLICMBase::Hoist(MachineInstr *MI, MachineBasicBlock *Preheader, 15955f757f3fSDimitry Andric MachineLoop *CurLoop) { 1596480093f4SDimitry Andric MachineBasicBlock *SrcBlock = MI->getParent(); 1597480093f4SDimitry Andric 1598480093f4SDimitry Andric // Disable the instruction hoisting due to block hotness 1599480093f4SDimitry Andric if ((DisableHoistingToHotterBlocks == UseBFI::All || 1600480093f4SDimitry Andric (DisableHoistingToHotterBlocks == UseBFI::PGO && HasProfileData)) && 1601480093f4SDimitry Andric isTgtHotterThanSrc(SrcBlock, Preheader)) { 1602480093f4SDimitry Andric ++NumNotHoistedDueToHotness; 16035f757f3fSDimitry Andric return HoistResult::NotHoisted; 1604480093f4SDimitry Andric } 16050b57cec5SDimitry Andric // First check whether we should hoist this instruction. 16065f757f3fSDimitry Andric bool HasExtractHoistableLoad = false; 16075f757f3fSDimitry Andric if (!IsLoopInvariantInst(*MI, CurLoop) || 16085f757f3fSDimitry Andric !IsProfitableToHoist(*MI, CurLoop)) { 16090b57cec5SDimitry Andric // If not, try unfolding a hoistable load. 16105f757f3fSDimitry Andric MI = ExtractHoistableLoad(MI, CurLoop); 16115f757f3fSDimitry Andric if (!MI) 16125f757f3fSDimitry Andric return HoistResult::NotHoisted; 16135f757f3fSDimitry Andric HasExtractHoistableLoad = true; 16140b57cec5SDimitry Andric } 16150b57cec5SDimitry Andric 16160b57cec5SDimitry Andric // If we have hoisted an instruction that may store, it can only be a constant 16170b57cec5SDimitry Andric // store. 16180b57cec5SDimitry Andric if (MI->mayStore()) 16190b57cec5SDimitry Andric NumStoreConst++; 16200b57cec5SDimitry Andric 16210b57cec5SDimitry Andric // Now move the instructions to the predecessor, inserting it before any 16220b57cec5SDimitry Andric // terminator instructions. 16230b57cec5SDimitry Andric LLVM_DEBUG({ 16240b57cec5SDimitry Andric dbgs() << "Hoisting " << *MI; 16250b57cec5SDimitry Andric if (MI->getParent()->getBasicBlock()) 16260b57cec5SDimitry Andric dbgs() << " from " << printMBBReference(*MI->getParent()); 16270b57cec5SDimitry Andric if (Preheader->getBasicBlock()) 16280b57cec5SDimitry Andric dbgs() << " to " << printMBBReference(*Preheader); 16290b57cec5SDimitry Andric dbgs() << "\n"; 16300b57cec5SDimitry Andric }); 16310b57cec5SDimitry Andric 16320b57cec5SDimitry Andric // If this is the first instruction being hoisted to the preheader, 16330b57cec5SDimitry Andric // initialize the CSE map with potential common expressions. 16340b57cec5SDimitry Andric if (FirstInLoop) { 16350b57cec5SDimitry Andric InitCSEMap(Preheader); 16360b57cec5SDimitry Andric FirstInLoop = false; 16370b57cec5SDimitry Andric } 16380b57cec5SDimitry Andric 16390b57cec5SDimitry Andric // Look for opportunity to CSE the hoisted instruction. 16400b57cec5SDimitry Andric unsigned Opcode = MI->getOpcode(); 16415f757f3fSDimitry Andric bool HasCSEDone = false; 16425f757f3fSDimitry Andric for (auto &Map : CSEMap) { 16435f757f3fSDimitry Andric // Check this CSEMap's preheader dominates MI's basic block. 16445f757f3fSDimitry Andric if (DT->dominates(Map.first, MI->getParent())) { 1645e8d8bef9SDimitry Andric DenseMap<unsigned, std::vector<MachineInstr *>>::iterator CI = 16465f757f3fSDimitry Andric Map.second.find(Opcode); 16475f757f3fSDimitry Andric if (CI != Map.second.end()) { 16485f757f3fSDimitry Andric if (EliminateCSE(MI, CI)) { 16495f757f3fSDimitry Andric HasCSEDone = true; 16505f757f3fSDimitry Andric break; 16515f757f3fSDimitry Andric } 16525f757f3fSDimitry Andric } 16535f757f3fSDimitry Andric } 16545f757f3fSDimitry Andric } 16555f757f3fSDimitry Andric 16565f757f3fSDimitry Andric if (!HasCSEDone) { 16570b57cec5SDimitry Andric // Otherwise, splice the instruction to the preheader. 16580b57cec5SDimitry Andric Preheader->splice(Preheader->getFirstTerminator(),MI->getParent(),MI); 16590b57cec5SDimitry Andric 16600b57cec5SDimitry Andric // Since we are moving the instruction out of its basic block, we do not 16610b57cec5SDimitry Andric // retain its debug location. Doing so would degrade the debugging 16620b57cec5SDimitry Andric // experience and adversely affect the accuracy of profiling information. 16635ffd83dbSDimitry Andric assert(!MI->isDebugInstr() && "Should not hoist debug inst"); 16640b57cec5SDimitry Andric MI->setDebugLoc(DebugLoc()); 16650b57cec5SDimitry Andric 16660b57cec5SDimitry Andric // Update register pressure for BBs from header to this block. 16670b57cec5SDimitry Andric UpdateBackTraceRegPressure(MI); 16680b57cec5SDimitry Andric 16690b57cec5SDimitry Andric // Clear the kill flags of any register this instruction defines, 16700b57cec5SDimitry Andric // since they may need to be live throughout the entire loop 16710b57cec5SDimitry Andric // rather than just live for part of it. 167206c3fb27SDimitry Andric for (MachineOperand &MO : MI->all_defs()) 167306c3fb27SDimitry Andric if (!MO.isDead()) 16740b57cec5SDimitry Andric MRI->clearKillFlags(MO.getReg()); 16750b57cec5SDimitry Andric 16765f757f3fSDimitry Andric CSEMap[Preheader][Opcode].push_back(MI); 16770b57cec5SDimitry Andric } 16780b57cec5SDimitry Andric 16790b57cec5SDimitry Andric ++NumHoisted; 16800b57cec5SDimitry Andric Changed = true; 16810b57cec5SDimitry Andric 16825f757f3fSDimitry Andric if (HasCSEDone || HasExtractHoistableLoad) 16835f757f3fSDimitry Andric return HoistResult::Hoisted | HoistResult::ErasedMI; 16845f757f3fSDimitry Andric return HoistResult::Hoisted; 16850b57cec5SDimitry Andric } 16860b57cec5SDimitry Andric 16870b57cec5SDimitry Andric /// Get the preheader for the current loop, splitting a critical edge if needed. 16885f757f3fSDimitry Andric MachineBasicBlock * 16895f757f3fSDimitry Andric MachineLICMBase::getCurPreheader(MachineLoop *CurLoop, 16905f757f3fSDimitry Andric MachineBasicBlock *CurPreheader) { 16910b57cec5SDimitry Andric // Determine the block to which to hoist instructions. If we can't find a 16920b57cec5SDimitry Andric // suitable loop predecessor, we can't do any hoisting. 16930b57cec5SDimitry Andric 16940b57cec5SDimitry Andric // If we've tried to get a preheader and failed, don't try again. 16950b57cec5SDimitry Andric if (CurPreheader == reinterpret_cast<MachineBasicBlock *>(-1)) 16960b57cec5SDimitry Andric return nullptr; 16970b57cec5SDimitry Andric 16980b57cec5SDimitry Andric if (!CurPreheader) { 16990b57cec5SDimitry Andric CurPreheader = CurLoop->getLoopPreheader(); 17000b57cec5SDimitry Andric if (!CurPreheader) { 17010b57cec5SDimitry Andric MachineBasicBlock *Pred = CurLoop->getLoopPredecessor(); 17020b57cec5SDimitry Andric if (!Pred) { 17030b57cec5SDimitry Andric CurPreheader = reinterpret_cast<MachineBasicBlock *>(-1); 17040b57cec5SDimitry Andric return nullptr; 17050b57cec5SDimitry Andric } 17060b57cec5SDimitry Andric 17070b57cec5SDimitry Andric CurPreheader = Pred->SplitCriticalEdge(CurLoop->getHeader(), *this); 17080b57cec5SDimitry Andric if (!CurPreheader) { 17090b57cec5SDimitry Andric CurPreheader = reinterpret_cast<MachineBasicBlock *>(-1); 17100b57cec5SDimitry Andric return nullptr; 17110b57cec5SDimitry Andric } 17120b57cec5SDimitry Andric } 17130b57cec5SDimitry Andric } 17140b57cec5SDimitry Andric return CurPreheader; 17150b57cec5SDimitry Andric } 1716480093f4SDimitry Andric 1717480093f4SDimitry Andric /// Is the target basic block at least "BlockFrequencyRatioThreshold" 1718480093f4SDimitry Andric /// times hotter than the source basic block. 1719480093f4SDimitry Andric bool MachineLICMBase::isTgtHotterThanSrc(MachineBasicBlock *SrcBlock, 1720480093f4SDimitry Andric MachineBasicBlock *TgtBlock) { 1721480093f4SDimitry Andric // Parse source and target basic block frequency from MBFI 1722480093f4SDimitry Andric uint64_t SrcBF = MBFI->getBlockFreq(SrcBlock).getFrequency(); 1723480093f4SDimitry Andric uint64_t DstBF = MBFI->getBlockFreq(TgtBlock).getFrequency(); 1724480093f4SDimitry Andric 1725480093f4SDimitry Andric // Disable the hoisting if source block frequency is zero 1726480093f4SDimitry Andric if (!SrcBF) 1727480093f4SDimitry Andric return true; 1728480093f4SDimitry Andric 1729480093f4SDimitry Andric double Ratio = (double)DstBF / SrcBF; 1730480093f4SDimitry Andric 1731480093f4SDimitry Andric // Compare the block frequency ratio with the threshold 1732480093f4SDimitry Andric return Ratio > BlockFrequencyRatioThreshold; 1733480093f4SDimitry Andric } 1734