xref: /aosp_15_r20/external/llvm/include/llvm/CodeGen/RegisterScavenging.h (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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