1*9880d681SAndroid Build Coastguard Worker //===-- RegisterScavenging.h - Machine register scavenging ------*- C++ -*-===// 2*9880d681SAndroid Build Coastguard Worker // 3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker // 5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker // 8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker // 10*9880d681SAndroid Build Coastguard Worker /// \file 11*9880d681SAndroid Build Coastguard Worker /// This file declares the machine register scavenger class. It can provide 12*9880d681SAndroid Build Coastguard Worker /// information such as unused register at any point in a machine basic block. 13*9880d681SAndroid Build Coastguard Worker /// It also provides a mechanism to make registers available by evicting them 14*9880d681SAndroid Build Coastguard Worker /// to spill slots. 15*9880d681SAndroid Build Coastguard Worker // 16*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 17*9880d681SAndroid Build Coastguard Worker 18*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_CODEGEN_REGISTERSCAVENGING_H 19*9880d681SAndroid Build Coastguard Worker #define LLVM_CODEGEN_REGISTERSCAVENGING_H 20*9880d681SAndroid Build Coastguard Worker 21*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/BitVector.h" 22*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineBasicBlock.h" 23*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h" 24*9880d681SAndroid Build Coastguard Worker 25*9880d681SAndroid Build Coastguard Worker namespace llvm { 26*9880d681SAndroid Build Coastguard Worker 27*9880d681SAndroid Build Coastguard Worker class MachineRegisterInfo; 28*9880d681SAndroid Build Coastguard Worker class TargetRegisterInfo; 29*9880d681SAndroid Build Coastguard Worker class TargetInstrInfo; 30*9880d681SAndroid Build Coastguard Worker class TargetRegisterClass; 31*9880d681SAndroid Build Coastguard Worker 32*9880d681SAndroid Build Coastguard Worker class RegScavenger { 33*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI; 34*9880d681SAndroid Build Coastguard Worker const TargetInstrInfo *TII; 35*9880d681SAndroid Build Coastguard Worker MachineRegisterInfo* MRI; 36*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *MBB; 37*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator MBBI; 38*9880d681SAndroid Build Coastguard Worker unsigned NumRegUnits; 39*9880d681SAndroid Build Coastguard Worker 40*9880d681SAndroid Build Coastguard Worker /// True if RegScavenger is currently tracking the liveness of registers. 41*9880d681SAndroid Build Coastguard Worker bool Tracking; 42*9880d681SAndroid Build Coastguard Worker 43*9880d681SAndroid Build Coastguard Worker /// Information on scavenged registers (held in a spill slot). 44*9880d681SAndroid Build Coastguard Worker struct ScavengedInfo { FrameIndexScavengedInfo45*9880d681SAndroid Build Coastguard Worker ScavengedInfo(int FI = -1) : FrameIndex(FI), Reg(0), Restore(nullptr) {} 46*9880d681SAndroid Build Coastguard Worker 47*9880d681SAndroid Build Coastguard Worker /// A spill slot used for scavenging a register post register allocation. 48*9880d681SAndroid Build Coastguard Worker int FrameIndex; 49*9880d681SAndroid Build Coastguard Worker 50*9880d681SAndroid Build Coastguard Worker /// If non-zero, the specific register is currently being 51*9880d681SAndroid Build Coastguard Worker /// scavenged. That is, it is spilled to this scavenging stack slot. 52*9880d681SAndroid Build Coastguard Worker unsigned Reg; 53*9880d681SAndroid Build Coastguard Worker 54*9880d681SAndroid Build Coastguard Worker /// The instruction that restores the scavenged register from stack. 55*9880d681SAndroid Build Coastguard Worker const MachineInstr *Restore; 56*9880d681SAndroid Build Coastguard Worker }; 57*9880d681SAndroid Build Coastguard Worker 58*9880d681SAndroid Build Coastguard Worker /// A vector of information on scavenged registers. 59*9880d681SAndroid Build Coastguard Worker SmallVector<ScavengedInfo, 2> Scavenged; 60*9880d681SAndroid Build Coastguard Worker 61*9880d681SAndroid Build Coastguard Worker /// The current state of each reg unit immediately before MBBI. 62*9880d681SAndroid Build Coastguard Worker /// One bit per register unit. If bit is not set it means any 63*9880d681SAndroid Build Coastguard Worker /// register containing that register unit is currently being used. 64*9880d681SAndroid Build Coastguard Worker BitVector RegUnitsAvailable; 65*9880d681SAndroid Build Coastguard Worker 66*9880d681SAndroid Build Coastguard Worker // These BitVectors are only used internally to forward(). They are members 67*9880d681SAndroid Build Coastguard Worker // to avoid frequent reallocations. 68*9880d681SAndroid Build Coastguard Worker BitVector KillRegUnits, DefRegUnits; 69*9880d681SAndroid Build Coastguard Worker BitVector TmpRegUnits; 70*9880d681SAndroid Build Coastguard Worker 71*9880d681SAndroid Build Coastguard Worker public: RegScavenger()72*9880d681SAndroid Build Coastguard Worker RegScavenger() 73*9880d681SAndroid Build Coastguard Worker : MBB(nullptr), NumRegUnits(0), Tracking(false) {} 74*9880d681SAndroid Build Coastguard Worker 75*9880d681SAndroid Build Coastguard Worker /// Start tracking liveness from the begin of basic block \p MBB. 76*9880d681SAndroid Build Coastguard Worker void enterBasicBlock(MachineBasicBlock &MBB); 77*9880d681SAndroid Build Coastguard Worker 78*9880d681SAndroid Build Coastguard Worker /// Move the internal MBB iterator and update register states. 79*9880d681SAndroid Build Coastguard Worker void forward(); 80*9880d681SAndroid Build Coastguard Worker 81*9880d681SAndroid Build Coastguard Worker /// Move the internal MBB iterator and update register states until 82*9880d681SAndroid Build Coastguard Worker /// it has processed the specific iterator. forward(MachineBasicBlock::iterator I)83*9880d681SAndroid Build Coastguard Worker void forward(MachineBasicBlock::iterator I) { 84*9880d681SAndroid Build Coastguard Worker if (!Tracking && MBB->begin() != I) forward(); 85*9880d681SAndroid Build Coastguard Worker while (MBBI != I) forward(); 86*9880d681SAndroid Build Coastguard Worker } 87*9880d681SAndroid Build Coastguard Worker 88*9880d681SAndroid Build Coastguard Worker /// Invert the behavior of forward() on the current instruction (undo the 89*9880d681SAndroid Build Coastguard Worker /// changes to the available registers made by forward()). 90*9880d681SAndroid Build Coastguard Worker void unprocess(); 91*9880d681SAndroid Build Coastguard Worker 92*9880d681SAndroid Build Coastguard Worker /// Unprocess instructions until you reach the provided iterator. unprocess(MachineBasicBlock::iterator I)93*9880d681SAndroid Build Coastguard Worker void unprocess(MachineBasicBlock::iterator I) { 94*9880d681SAndroid Build Coastguard Worker while (MBBI != I) unprocess(); 95*9880d681SAndroid Build Coastguard Worker } 96*9880d681SAndroid Build Coastguard Worker 97*9880d681SAndroid Build Coastguard Worker /// Move the internal MBB iterator but do not update register states. skipTo(MachineBasicBlock::iterator I)98*9880d681SAndroid Build Coastguard Worker void skipTo(MachineBasicBlock::iterator I) { 99*9880d681SAndroid Build Coastguard Worker if (I == MachineBasicBlock::iterator(nullptr)) 100*9880d681SAndroid Build Coastguard Worker Tracking = false; 101*9880d681SAndroid Build Coastguard Worker MBBI = I; 102*9880d681SAndroid Build Coastguard Worker } 103*9880d681SAndroid Build Coastguard Worker getCurrentPosition()104*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator getCurrentPosition() const { return MBBI; } 105*9880d681SAndroid Build Coastguard Worker 106*9880d681SAndroid Build Coastguard Worker /// Return if a specific register is currently used. 107*9880d681SAndroid Build Coastguard Worker bool isRegUsed(unsigned Reg, bool includeReserved = true) const; 108*9880d681SAndroid Build Coastguard Worker 109*9880d681SAndroid Build Coastguard Worker /// Return all available registers in the register class in Mask. 110*9880d681SAndroid Build Coastguard Worker BitVector getRegsAvailable(const TargetRegisterClass *RC); 111*9880d681SAndroid Build Coastguard Worker 112*9880d681SAndroid Build Coastguard Worker /// Find an unused register of the specified register class. 113*9880d681SAndroid Build Coastguard Worker /// Return 0 if none is found. 114*9880d681SAndroid Build Coastguard Worker unsigned FindUnusedReg(const TargetRegisterClass *RegClass) const; 115*9880d681SAndroid Build Coastguard Worker 116*9880d681SAndroid Build Coastguard Worker /// Add a scavenging frame index. addScavengingFrameIndex(int FI)117*9880d681SAndroid Build Coastguard Worker void addScavengingFrameIndex(int FI) { 118*9880d681SAndroid Build Coastguard Worker Scavenged.push_back(ScavengedInfo(FI)); 119*9880d681SAndroid Build Coastguard Worker } 120*9880d681SAndroid Build Coastguard Worker 121*9880d681SAndroid Build Coastguard Worker /// Query whether a frame index is a scavenging frame index. isScavengingFrameIndex(int FI)122*9880d681SAndroid Build Coastguard Worker bool isScavengingFrameIndex(int FI) const { 123*9880d681SAndroid Build Coastguard Worker for (SmallVectorImpl<ScavengedInfo>::const_iterator I = Scavenged.begin(), 124*9880d681SAndroid Build Coastguard Worker IE = Scavenged.end(); I != IE; ++I) 125*9880d681SAndroid Build Coastguard Worker if (I->FrameIndex == FI) 126*9880d681SAndroid Build Coastguard Worker return true; 127*9880d681SAndroid Build Coastguard Worker 128*9880d681SAndroid Build Coastguard Worker return false; 129*9880d681SAndroid Build Coastguard Worker } 130*9880d681SAndroid Build Coastguard Worker 131*9880d681SAndroid Build Coastguard Worker /// Get an array of scavenging frame indices. getScavengingFrameIndices(SmallVectorImpl<int> & A)132*9880d681SAndroid Build Coastguard Worker void getScavengingFrameIndices(SmallVectorImpl<int> &A) const { 133*9880d681SAndroid Build Coastguard Worker for (SmallVectorImpl<ScavengedInfo>::const_iterator I = Scavenged.begin(), 134*9880d681SAndroid Build Coastguard Worker IE = Scavenged.end(); I != IE; ++I) 135*9880d681SAndroid Build Coastguard Worker if (I->FrameIndex >= 0) 136*9880d681SAndroid Build Coastguard Worker A.push_back(I->FrameIndex); 137*9880d681SAndroid Build Coastguard Worker } 138*9880d681SAndroid Build Coastguard Worker 139*9880d681SAndroid Build Coastguard Worker /// Make a register of the specific register class 140*9880d681SAndroid Build Coastguard Worker /// available and do the appropriate bookkeeping. SPAdj is the stack 141*9880d681SAndroid Build Coastguard Worker /// adjustment due to call frame, it's passed along to eliminateFrameIndex(). 142*9880d681SAndroid Build Coastguard Worker /// Returns the scavenged register. 143*9880d681SAndroid Build Coastguard Worker unsigned scavengeRegister(const TargetRegisterClass *RegClass, 144*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator I, int SPAdj); scavengeRegister(const TargetRegisterClass * RegClass,int SPAdj)145*9880d681SAndroid Build Coastguard Worker unsigned scavengeRegister(const TargetRegisterClass *RegClass, int SPAdj) { 146*9880d681SAndroid Build Coastguard Worker return scavengeRegister(RegClass, MBBI, SPAdj); 147*9880d681SAndroid Build Coastguard Worker } 148*9880d681SAndroid Build Coastguard Worker 149*9880d681SAndroid Build Coastguard Worker /// Tell the scavenger a register is used. 150*9880d681SAndroid Build Coastguard Worker void setRegUsed(unsigned Reg, LaneBitmask LaneMask = ~0u); 151*9880d681SAndroid Build Coastguard Worker private: 152*9880d681SAndroid Build Coastguard Worker /// Returns true if a register is reserved. It is never "unused". isReserved(unsigned Reg)153*9880d681SAndroid Build Coastguard Worker bool isReserved(unsigned Reg) const { return MRI->isReserved(Reg); } 154*9880d681SAndroid Build Coastguard Worker 155*9880d681SAndroid Build Coastguard Worker /// setUsed / setUnused - Mark the state of one or a number of register units. 156*9880d681SAndroid Build Coastguard Worker /// setUsed(BitVector & RegUnits)157*9880d681SAndroid Build Coastguard Worker void setUsed(BitVector &RegUnits) { 158*9880d681SAndroid Build Coastguard Worker RegUnitsAvailable.reset(RegUnits); 159*9880d681SAndroid Build Coastguard Worker } setUnused(BitVector & RegUnits)160*9880d681SAndroid Build Coastguard Worker void setUnused(BitVector &RegUnits) { 161*9880d681SAndroid Build Coastguard Worker RegUnitsAvailable |= RegUnits; 162*9880d681SAndroid Build Coastguard Worker } 163*9880d681SAndroid Build Coastguard Worker 164*9880d681SAndroid Build Coastguard Worker /// Processes the current instruction and fill the KillRegUnits and 165*9880d681SAndroid Build Coastguard Worker /// DefRegUnits bit vectors. 166*9880d681SAndroid Build Coastguard Worker void determineKillsAndDefs(); 167*9880d681SAndroid Build Coastguard Worker 168*9880d681SAndroid Build Coastguard Worker /// Add all Reg Units that Reg contains to BV. 169*9880d681SAndroid Build Coastguard Worker void addRegUnits(BitVector &BV, unsigned Reg); 170*9880d681SAndroid Build Coastguard Worker 171*9880d681SAndroid Build Coastguard Worker /// Return the candidate register that is unused for the longest after 172*9880d681SAndroid Build Coastguard Worker /// StartMI. UseMI is set to the instruction where the search stopped. 173*9880d681SAndroid Build Coastguard Worker /// 174*9880d681SAndroid Build Coastguard Worker /// No more than InstrLimit instructions are inspected. 175*9880d681SAndroid Build Coastguard Worker unsigned findSurvivorReg(MachineBasicBlock::iterator StartMI, 176*9880d681SAndroid Build Coastguard Worker BitVector &Candidates, 177*9880d681SAndroid Build Coastguard Worker unsigned InstrLimit, 178*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator &UseMI); 179*9880d681SAndroid Build Coastguard Worker 180*9880d681SAndroid Build Coastguard Worker /// Allow resetting register state info for multiple 181*9880d681SAndroid Build Coastguard Worker /// passes over/within the same function. 182*9880d681SAndroid Build Coastguard Worker void initRegState(); 183*9880d681SAndroid Build Coastguard Worker }; 184*9880d681SAndroid Build Coastguard Worker 185*9880d681SAndroid Build Coastguard Worker } // End llvm namespace 186*9880d681SAndroid Build Coastguard Worker 187*9880d681SAndroid Build Coastguard Worker #endif 188