1*09467b48Spatrick //===- LiveRangeShrink.cpp - Move instructions to shrink live range -------===// 2*09467b48Spatrick // 3*09467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*09467b48Spatrick // See https://llvm.org/LICENSE.txt for license information. 5*09467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*09467b48Spatrick // 7*09467b48Spatrick ///===---------------------------------------------------------------------===// 8*09467b48Spatrick /// 9*09467b48Spatrick /// \file 10*09467b48Spatrick /// This pass moves instructions close to the definition of its operands to 11*09467b48Spatrick /// shrink live range of the def instruction. The code motion is limited within 12*09467b48Spatrick /// the basic block. The moved instruction should have 1 def, and more than one 13*09467b48Spatrick /// uses, all of which are the only use of the def. 14*09467b48Spatrick /// 15*09467b48Spatrick ///===---------------------------------------------------------------------===// 16*09467b48Spatrick 17*09467b48Spatrick #include "llvm/ADT/DenseMap.h" 18*09467b48Spatrick #include "llvm/ADT/Statistic.h" 19*09467b48Spatrick #include "llvm/ADT/iterator_range.h" 20*09467b48Spatrick #include "llvm/CodeGen/MachineBasicBlock.h" 21*09467b48Spatrick #include "llvm/CodeGen/MachineFunction.h" 22*09467b48Spatrick #include "llvm/CodeGen/MachineFunctionPass.h" 23*09467b48Spatrick #include "llvm/CodeGen/MachineInstr.h" 24*09467b48Spatrick #include "llvm/CodeGen/MachineOperand.h" 25*09467b48Spatrick #include "llvm/CodeGen/MachineRegisterInfo.h" 26*09467b48Spatrick #include "llvm/CodeGen/TargetRegisterInfo.h" 27*09467b48Spatrick #include "llvm/InitializePasses.h" 28*09467b48Spatrick #include "llvm/Pass.h" 29*09467b48Spatrick #include "llvm/Support/Debug.h" 30*09467b48Spatrick #include "llvm/Support/raw_ostream.h" 31*09467b48Spatrick #include <iterator> 32*09467b48Spatrick #include <utility> 33*09467b48Spatrick 34*09467b48Spatrick using namespace llvm; 35*09467b48Spatrick 36*09467b48Spatrick #define DEBUG_TYPE "lrshrink" 37*09467b48Spatrick 38*09467b48Spatrick STATISTIC(NumInstrsHoistedToShrinkLiveRange, 39*09467b48Spatrick "Number of insructions hoisted to shrink live range."); 40*09467b48Spatrick 41*09467b48Spatrick namespace { 42*09467b48Spatrick 43*09467b48Spatrick class LiveRangeShrink : public MachineFunctionPass { 44*09467b48Spatrick public: 45*09467b48Spatrick static char ID; 46*09467b48Spatrick 47*09467b48Spatrick LiveRangeShrink() : MachineFunctionPass(ID) { 48*09467b48Spatrick initializeLiveRangeShrinkPass(*PassRegistry::getPassRegistry()); 49*09467b48Spatrick } 50*09467b48Spatrick 51*09467b48Spatrick void getAnalysisUsage(AnalysisUsage &AU) const override { 52*09467b48Spatrick AU.setPreservesCFG(); 53*09467b48Spatrick MachineFunctionPass::getAnalysisUsage(AU); 54*09467b48Spatrick } 55*09467b48Spatrick 56*09467b48Spatrick StringRef getPassName() const override { return "Live Range Shrink"; } 57*09467b48Spatrick 58*09467b48Spatrick bool runOnMachineFunction(MachineFunction &MF) override; 59*09467b48Spatrick }; 60*09467b48Spatrick 61*09467b48Spatrick } // end anonymous namespace 62*09467b48Spatrick 63*09467b48Spatrick char LiveRangeShrink::ID = 0; 64*09467b48Spatrick 65*09467b48Spatrick char &llvm::LiveRangeShrinkID = LiveRangeShrink::ID; 66*09467b48Spatrick 67*09467b48Spatrick INITIALIZE_PASS(LiveRangeShrink, "lrshrink", "Live Range Shrink Pass", false, 68*09467b48Spatrick false) 69*09467b48Spatrick 70*09467b48Spatrick using InstOrderMap = DenseMap<MachineInstr *, unsigned>; 71*09467b48Spatrick 72*09467b48Spatrick /// Returns \p New if it's dominated by \p Old, otherwise return \p Old. 73*09467b48Spatrick /// \p M maintains a map from instruction to its dominating order that satisfies 74*09467b48Spatrick /// M[A] > M[B] guarantees that A is dominated by B. 75*09467b48Spatrick /// If \p New is not in \p M, return \p Old. Otherwise if \p Old is null, return 76*09467b48Spatrick /// \p New. 77*09467b48Spatrick static MachineInstr *FindDominatedInstruction(MachineInstr &New, 78*09467b48Spatrick MachineInstr *Old, 79*09467b48Spatrick const InstOrderMap &M) { 80*09467b48Spatrick auto NewIter = M.find(&New); 81*09467b48Spatrick if (NewIter == M.end()) 82*09467b48Spatrick return Old; 83*09467b48Spatrick if (Old == nullptr) 84*09467b48Spatrick return &New; 85*09467b48Spatrick unsigned OrderOld = M.find(Old)->second; 86*09467b48Spatrick unsigned OrderNew = NewIter->second; 87*09467b48Spatrick if (OrderOld != OrderNew) 88*09467b48Spatrick return OrderOld < OrderNew ? &New : Old; 89*09467b48Spatrick // OrderOld == OrderNew, we need to iterate down from Old to see if it 90*09467b48Spatrick // can reach New, if yes, New is dominated by Old. 91*09467b48Spatrick for (MachineInstr *I = Old->getNextNode(); M.find(I)->second == OrderNew; 92*09467b48Spatrick I = I->getNextNode()) 93*09467b48Spatrick if (I == &New) 94*09467b48Spatrick return &New; 95*09467b48Spatrick return Old; 96*09467b48Spatrick } 97*09467b48Spatrick 98*09467b48Spatrick /// Builds Instruction to its dominating order number map \p M by traversing 99*09467b48Spatrick /// from instruction \p Start. 100*09467b48Spatrick static void BuildInstOrderMap(MachineBasicBlock::iterator Start, 101*09467b48Spatrick InstOrderMap &M) { 102*09467b48Spatrick M.clear(); 103*09467b48Spatrick unsigned i = 0; 104*09467b48Spatrick for (MachineInstr &I : make_range(Start, Start->getParent()->end())) 105*09467b48Spatrick M[&I] = i++; 106*09467b48Spatrick } 107*09467b48Spatrick 108*09467b48Spatrick bool LiveRangeShrink::runOnMachineFunction(MachineFunction &MF) { 109*09467b48Spatrick if (skipFunction(MF.getFunction())) 110*09467b48Spatrick return false; 111*09467b48Spatrick 112*09467b48Spatrick MachineRegisterInfo &MRI = MF.getRegInfo(); 113*09467b48Spatrick 114*09467b48Spatrick LLVM_DEBUG(dbgs() << "**** Analysing " << MF.getName() << '\n'); 115*09467b48Spatrick 116*09467b48Spatrick InstOrderMap IOM; 117*09467b48Spatrick // Map from register to instruction order (value of IOM) where the 118*09467b48Spatrick // register is used last. When moving instructions up, we need to 119*09467b48Spatrick // make sure all its defs (including dead def) will not cross its 120*09467b48Spatrick // last use when moving up. 121*09467b48Spatrick DenseMap<unsigned, std::pair<unsigned, MachineInstr *>> UseMap; 122*09467b48Spatrick 123*09467b48Spatrick for (MachineBasicBlock &MBB : MF) { 124*09467b48Spatrick if (MBB.empty()) 125*09467b48Spatrick continue; 126*09467b48Spatrick bool SawStore = false; 127*09467b48Spatrick BuildInstOrderMap(MBB.begin(), IOM); 128*09467b48Spatrick UseMap.clear(); 129*09467b48Spatrick 130*09467b48Spatrick for (MachineBasicBlock::iterator Next = MBB.begin(); Next != MBB.end();) { 131*09467b48Spatrick MachineInstr &MI = *Next; 132*09467b48Spatrick ++Next; 133*09467b48Spatrick if (MI.isPHI() || MI.isDebugInstr()) 134*09467b48Spatrick continue; 135*09467b48Spatrick if (MI.mayStore()) 136*09467b48Spatrick SawStore = true; 137*09467b48Spatrick 138*09467b48Spatrick unsigned CurrentOrder = IOM[&MI]; 139*09467b48Spatrick unsigned Barrier = 0; 140*09467b48Spatrick MachineInstr *BarrierMI = nullptr; 141*09467b48Spatrick for (const MachineOperand &MO : MI.operands()) { 142*09467b48Spatrick if (!MO.isReg() || MO.isDebug()) 143*09467b48Spatrick continue; 144*09467b48Spatrick if (MO.isUse()) 145*09467b48Spatrick UseMap[MO.getReg()] = std::make_pair(CurrentOrder, &MI); 146*09467b48Spatrick else if (MO.isDead() && UseMap.count(MO.getReg())) 147*09467b48Spatrick // Barrier is the last instruction where MO get used. MI should not 148*09467b48Spatrick // be moved above Barrier. 149*09467b48Spatrick if (Barrier < UseMap[MO.getReg()].first) { 150*09467b48Spatrick Barrier = UseMap[MO.getReg()].first; 151*09467b48Spatrick BarrierMI = UseMap[MO.getReg()].second; 152*09467b48Spatrick } 153*09467b48Spatrick } 154*09467b48Spatrick 155*09467b48Spatrick if (!MI.isSafeToMove(nullptr, SawStore)) { 156*09467b48Spatrick // If MI has side effects, it should become a barrier for code motion. 157*09467b48Spatrick // IOM is rebuild from the next instruction to prevent later 158*09467b48Spatrick // instructions from being moved before this MI. 159*09467b48Spatrick if (MI.hasUnmodeledSideEffects() && Next != MBB.end()) { 160*09467b48Spatrick BuildInstOrderMap(Next, IOM); 161*09467b48Spatrick SawStore = false; 162*09467b48Spatrick } 163*09467b48Spatrick continue; 164*09467b48Spatrick } 165*09467b48Spatrick 166*09467b48Spatrick const MachineOperand *DefMO = nullptr; 167*09467b48Spatrick MachineInstr *Insert = nullptr; 168*09467b48Spatrick 169*09467b48Spatrick // Number of live-ranges that will be shortened. We do not count 170*09467b48Spatrick // live-ranges that are defined by a COPY as it could be coalesced later. 171*09467b48Spatrick unsigned NumEligibleUse = 0; 172*09467b48Spatrick 173*09467b48Spatrick for (const MachineOperand &MO : MI.operands()) { 174*09467b48Spatrick if (!MO.isReg() || MO.isDead() || MO.isDebug()) 175*09467b48Spatrick continue; 176*09467b48Spatrick Register Reg = MO.getReg(); 177*09467b48Spatrick // Do not move the instruction if it def/uses a physical register, 178*09467b48Spatrick // unless it is a constant physical register or a noreg. 179*09467b48Spatrick if (!Register::isVirtualRegister(Reg)) { 180*09467b48Spatrick if (!Reg || MRI.isConstantPhysReg(Reg)) 181*09467b48Spatrick continue; 182*09467b48Spatrick Insert = nullptr; 183*09467b48Spatrick break; 184*09467b48Spatrick } 185*09467b48Spatrick if (MO.isDef()) { 186*09467b48Spatrick // Do not move if there is more than one def. 187*09467b48Spatrick if (DefMO) { 188*09467b48Spatrick Insert = nullptr; 189*09467b48Spatrick break; 190*09467b48Spatrick } 191*09467b48Spatrick DefMO = &MO; 192*09467b48Spatrick } else if (MRI.hasOneNonDBGUse(Reg) && MRI.hasOneDef(Reg) && DefMO && 193*09467b48Spatrick MRI.getRegClass(DefMO->getReg()) == 194*09467b48Spatrick MRI.getRegClass(MO.getReg())) { 195*09467b48Spatrick // The heuristic does not handle different register classes yet 196*09467b48Spatrick // (registers of different sizes, looser/tighter constraints). This 197*09467b48Spatrick // is because it needs more accurate model to handle register 198*09467b48Spatrick // pressure correctly. 199*09467b48Spatrick MachineInstr &DefInstr = *MRI.def_instr_begin(Reg); 200*09467b48Spatrick if (!DefInstr.isCopy()) 201*09467b48Spatrick NumEligibleUse++; 202*09467b48Spatrick Insert = FindDominatedInstruction(DefInstr, Insert, IOM); 203*09467b48Spatrick } else { 204*09467b48Spatrick Insert = nullptr; 205*09467b48Spatrick break; 206*09467b48Spatrick } 207*09467b48Spatrick } 208*09467b48Spatrick 209*09467b48Spatrick // If Barrier equals IOM[I], traverse forward to find if BarrierMI is 210*09467b48Spatrick // after Insert, if yes, then we should not hoist. 211*09467b48Spatrick for (MachineInstr *I = Insert; I && IOM[I] == Barrier; 212*09467b48Spatrick I = I->getNextNode()) 213*09467b48Spatrick if (I == BarrierMI) { 214*09467b48Spatrick Insert = nullptr; 215*09467b48Spatrick break; 216*09467b48Spatrick } 217*09467b48Spatrick // Move the instruction when # of shrunk live range > 1. 218*09467b48Spatrick if (DefMO && Insert && NumEligibleUse > 1 && Barrier <= IOM[Insert]) { 219*09467b48Spatrick MachineBasicBlock::iterator I = std::next(Insert->getIterator()); 220*09467b48Spatrick // Skip all the PHI and debug instructions. 221*09467b48Spatrick while (I != MBB.end() && (I->isPHI() || I->isDebugInstr())) 222*09467b48Spatrick I = std::next(I); 223*09467b48Spatrick if (I == MI.getIterator()) 224*09467b48Spatrick continue; 225*09467b48Spatrick 226*09467b48Spatrick // Update the dominator order to be the same as the insertion point. 227*09467b48Spatrick // We do this to maintain a non-decreasing order without need to update 228*09467b48Spatrick // all instruction orders after the insertion point. 229*09467b48Spatrick unsigned NewOrder = IOM[&*I]; 230*09467b48Spatrick IOM[&MI] = NewOrder; 231*09467b48Spatrick NumInstrsHoistedToShrinkLiveRange++; 232*09467b48Spatrick 233*09467b48Spatrick // Find MI's debug value following MI. 234*09467b48Spatrick MachineBasicBlock::iterator EndIter = std::next(MI.getIterator()); 235*09467b48Spatrick if (MI.getOperand(0).isReg()) 236*09467b48Spatrick for (; EndIter != MBB.end() && EndIter->isDebugValue() && 237*09467b48Spatrick EndIter->getOperand(0).isReg() && 238*09467b48Spatrick EndIter->getOperand(0).getReg() == MI.getOperand(0).getReg(); 239*09467b48Spatrick ++EndIter, ++Next) 240*09467b48Spatrick IOM[&*EndIter] = NewOrder; 241*09467b48Spatrick MBB.splice(I, &MBB, MI.getIterator(), EndIter); 242*09467b48Spatrick } 243*09467b48Spatrick } 244*09467b48Spatrick } 245*09467b48Spatrick return false; 246*09467b48Spatrick } 247