RegisterScavenging.h revision 27ea9999e84dfb1e6c2baf06ec27a92f12753917
196fa612373e258120d351ed14361f964ad22f99dEvan Cheng//===-- RegisterScavenging.h - Machine register scavenging ------*- C++ -*-===//
296fa612373e258120d351ed14361f964ad22f99dEvan Cheng//
396fa612373e258120d351ed14361f964ad22f99dEvan Cheng//                     The LLVM Compiler Infrastructure
496fa612373e258120d351ed14361f964ad22f99dEvan Cheng//
57ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// This file is distributed under the University of Illinois Open Source
67ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// License. See LICENSE.TXT for details.
796fa612373e258120d351ed14361f964ad22f99dEvan Cheng//
896fa612373e258120d351ed14361f964ad22f99dEvan Cheng//===----------------------------------------------------------------------===//
996fa612373e258120d351ed14361f964ad22f99dEvan Cheng//
1096fa612373e258120d351ed14361f964ad22f99dEvan Cheng// This file declares the machine register scavenger class. It can provide
1196fa612373e258120d351ed14361f964ad22f99dEvan Cheng// information such as unused register at any point in a machine basic block.
1296fa612373e258120d351ed14361f964ad22f99dEvan Cheng// It also provides a mechanism to make registers availbale by evicting them
1396fa612373e258120d351ed14361f964ad22f99dEvan Cheng// to spill slots.
1496fa612373e258120d351ed14361f964ad22f99dEvan Cheng//
1596fa612373e258120d351ed14361f964ad22f99dEvan Cheng//===----------------------------------------------------------------------===//
1696fa612373e258120d351ed14361f964ad22f99dEvan Cheng
1796fa612373e258120d351ed14361f964ad22f99dEvan Cheng#ifndef LLVM_CODEGEN_REGISTER_SCAVENGING_H
1896fa612373e258120d351ed14361f964ad22f99dEvan Cheng#define LLVM_CODEGEN_REGISTER_SCAVENGING_H
1996fa612373e258120d351ed14361f964ad22f99dEvan Cheng
2096fa612373e258120d351ed14361f964ad22f99dEvan Cheng#include "llvm/CodeGen/MachineBasicBlock.h"
2196fa612373e258120d351ed14361f964ad22f99dEvan Cheng#include "llvm/ADT/BitVector.h"
2296fa612373e258120d351ed14361f964ad22f99dEvan Cheng
2396fa612373e258120d351ed14361f964ad22f99dEvan Chengnamespace llvm {
2496fa612373e258120d351ed14361f964ad22f99dEvan Cheng
25c5ea2010c06fa6a2eaac17e493fbfe8a042e132aEvan Chengclass MachineRegisterInfo;
266f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohmanclass TargetRegisterInfo;
27b74a3e6fda768eb6160559e025f8b65c46db46d9Evan Chengclass TargetInstrInfo;
2896fa612373e258120d351ed14361f964ad22f99dEvan Chengclass TargetRegisterClass;
2996fa612373e258120d351ed14361f964ad22f99dEvan Cheng
3096fa612373e258120d351ed14361f964ad22f99dEvan Chengclass RegScavenger {
31d37c13cfd1bf4b08d0b99d93c799a1caa74cf3c6Evan Cheng  const TargetRegisterInfo *TRI;
32d37c13cfd1bf4b08d0b99d93c799a1caa74cf3c6Evan Cheng  const TargetInstrInfo *TII;
33d37c13cfd1bf4b08d0b99d93c799a1caa74cf3c6Evan Cheng  MachineRegisterInfo* MRI;
3496fa612373e258120d351ed14361f964ad22f99dEvan Cheng  MachineBasicBlock *MBB;
3596fa612373e258120d351ed14361f964ad22f99dEvan Cheng  MachineBasicBlock::iterator MBBI;
3696fa612373e258120d351ed14361f964ad22f99dEvan Cheng  unsigned NumPhysRegs;
3796fa612373e258120d351ed14361f964ad22f99dEvan Cheng
38898218cc5edecea1275ee266b2cd13313ea6b67bEvan Cheng  /// Tracking - True if RegScavenger is currently tracking the liveness of
39898218cc5edecea1275ee266b2cd13313ea6b67bEvan Cheng  /// registers.
40898218cc5edecea1275ee266b2cd13313ea6b67bEvan Cheng  bool Tracking;
41bb6fb3357d6c1e9ffb15de4893e59e3bbdd600a3Evan Cheng
42b74a3e6fda768eb6160559e025f8b65c46db46d9Evan Cheng  /// ScavengingFrameIndex - Special spill slot used for scavenging a register
43b74a3e6fda768eb6160559e025f8b65c46db46d9Evan Cheng  /// post register allocation.
44b74a3e6fda768eb6160559e025f8b65c46db46d9Evan Cheng  int ScavengingFrameIndex;
45b74a3e6fda768eb6160559e025f8b65c46db46d9Evan Cheng
46b74a3e6fda768eb6160559e025f8b65c46db46d9Evan Cheng  /// ScavengedReg - If none zero, the specific register is currently being
47b74a3e6fda768eb6160559e025f8b65c46db46d9Evan Cheng  /// scavenged. That is, it is spilled to the special scavenging stack slot.
48b74a3e6fda768eb6160559e025f8b65c46db46d9Evan Cheng  unsigned ScavengedReg;
49b74a3e6fda768eb6160559e025f8b65c46db46d9Evan Cheng
50b74a3e6fda768eb6160559e025f8b65c46db46d9Evan Cheng  /// ScavengedRC - Register class of the scavenged register.
51b74a3e6fda768eb6160559e025f8b65c46db46d9Evan Cheng  ///
52b74a3e6fda768eb6160559e025f8b65c46db46d9Evan Cheng  const TargetRegisterClass *ScavengedRC;
53b74a3e6fda768eb6160559e025f8b65c46db46d9Evan Cheng
54d37c13cfd1bf4b08d0b99d93c799a1caa74cf3c6Evan Cheng  /// ScavengeRestore - Instruction that restores the scavenged register from
55d37c13cfd1bf4b08d0b99d93c799a1caa74cf3c6Evan Cheng  /// stack.
56d37c13cfd1bf4b08d0b99d93c799a1caa74cf3c6Evan Cheng  const MachineInstr *ScavengeRestore;
57d37c13cfd1bf4b08d0b99d93c799a1caa74cf3c6Evan Cheng
58d37c13cfd1bf4b08d0b99d93c799a1caa74cf3c6Evan Cheng  /// CalleeSavedrRegs - A bitvector of callee saved registers for the target.
59d37c13cfd1bf4b08d0b99d93c799a1caa74cf3c6Evan Cheng  ///
60d37c13cfd1bf4b08d0b99d93c799a1caa74cf3c6Evan Cheng  BitVector CalleeSavedRegs;
61d37c13cfd1bf4b08d0b99d93c799a1caa74cf3c6Evan Cheng
62d37c13cfd1bf4b08d0b99d93c799a1caa74cf3c6Evan Cheng  /// ReservedRegs - A bitvector of reserved registers.
63d37c13cfd1bf4b08d0b99d93c799a1caa74cf3c6Evan Cheng  ///
64d37c13cfd1bf4b08d0b99d93c799a1caa74cf3c6Evan Cheng  BitVector ReservedRegs;
65d37c13cfd1bf4b08d0b99d93c799a1caa74cf3c6Evan Cheng
66c6b9ef80a890fcf75f18cabc3fe2d5f9ef2faaf5Dale Johannesen  /// RegsAvailable - The current state of all the physical registers immediately
6796fa612373e258120d351ed14361f964ad22f99dEvan Cheng  /// before MBBI. One bit per physical register. If bit is set that means it's
6896fa612373e258120d351ed14361f964ad22f99dEvan Cheng  /// available, unset means the register is currently being used.
69c6b9ef80a890fcf75f18cabc3fe2d5f9ef2faaf5Dale Johannesen  BitVector RegsAvailable;
7096fa612373e258120d351ed14361f964ad22f99dEvan Cheng
7196fa612373e258120d351ed14361f964ad22f99dEvan Chengpublic:
72bb6fb3357d6c1e9ffb15de4893e59e3bbdd600a3Evan Cheng  RegScavenger()
73b74a3e6fda768eb6160559e025f8b65c46db46d9Evan Cheng    : MBB(NULL), NumPhysRegs(0), Tracking(false),
7481975f6dfd9d306d0ea7ce3ef22561c949de9af9Dan Gohman      ScavengingFrameIndex(-1), ScavengedReg(0), ScavengedRC(NULL) {}
75bb6fb3357d6c1e9ffb15de4893e59e3bbdd600a3Evan Cheng
7628654b6205acc56863cdf988eed3e345da11eca3Evan Cheng  /// enterBasicBlock - Start tracking liveness from the begin of the specific
7728654b6205acc56863cdf988eed3e345da11eca3Evan Cheng  /// basic block.
7828654b6205acc56863cdf988eed3e345da11eca3Evan Cheng  void enterBasicBlock(MachineBasicBlock *mbb);
7996fa612373e258120d351ed14361f964ad22f99dEvan Cheng
80e0161ea1050fd4107f3307b1e25b3aac02c2ba16John Mosby  /// initRegState - allow resetting register state info for multiple
81e0161ea1050fd4107f3307b1e25b3aac02c2ba16John Mosby  /// passes over/within the same function.
82e0161ea1050fd4107f3307b1e25b3aac02c2ba16John Mosby  void initRegState();
83e0161ea1050fd4107f3307b1e25b3aac02c2ba16John Mosby
8431f5591c91d4c012901018013aba19b0015fa6a0Jakob Stoklund Olesen  /// forward - Move the internal MBB iterator and update register states.
8596fa612373e258120d351ed14361f964ad22f99dEvan Cheng  void forward();
8696fa612373e258120d351ed14361f964ad22f99dEvan Cheng
8731f5591c91d4c012901018013aba19b0015fa6a0Jakob Stoklund Olesen  /// forward - Move the internal MBB iterator and update register states until
8831f5591c91d4c012901018013aba19b0015fa6a0Jakob Stoklund Olesen  /// it has processed the specific iterator.
89bb6fb3357d6c1e9ffb15de4893e59e3bbdd600a3Evan Cheng  void forward(MachineBasicBlock::iterator I) {
905b200d8a133a07af1f7802025bd5a58a1cdd544dDan Gohman    if (!Tracking && MBB->begin() != I) forward();
91bb6fb3357d6c1e9ffb15de4893e59e3bbdd600a3Evan Cheng    while (MBBI != I) forward();
92bb6fb3357d6c1e9ffb15de4893e59e3bbdd600a3Evan Cheng  }
93ed570dedad945e1fe9a4bfeaa47276d875f1feedEvan Cheng
94f262b355593100c6e0fc629b03c76ab0b1e2d915Evan Cheng  /// skipTo - Move the internal MBB iterator but do not update register states.
95f262b355593100c6e0fc629b03c76ab0b1e2d915Evan Cheng  ///
96f262b355593100c6e0fc629b03c76ab0b1e2d915Evan Cheng  void skipTo(MachineBasicBlock::iterator I) { MBBI = I; }
97f262b355593100c6e0fc629b03c76ab0b1e2d915Evan Cheng
9869cb9b78f11d505f4351a269fc90e7b77fcda437Dale Johannesen  /// getRegsUsed - return all registers currently in use in used.
9969cb9b78f11d505f4351a269fc90e7b77fcda437Dale Johannesen  void getRegsUsed(BitVector &used, bool includeReserved);
10069cb9b78f11d505f4351a269fc90e7b77fcda437Dale Johannesen
101d9642faf7c66273eb3a8d99e5fa6b542da5374ddJim Grosbach  /// getRegsAvailable - Return all available registers in the register class
102d9642faf7c66273eb3a8d99e5fa6b542da5374ddJim Grosbach  /// in Mask.
10327ea9999e84dfb1e6c2baf06ec27a92f12753917Jim Grosbach  BitVector getRegsAvailable(const TargetRegisterClass *RC);
104d9642faf7c66273eb3a8d99e5fa6b542da5374ddJim Grosbach
10596fa612373e258120d351ed14361f964ad22f99dEvan Cheng  /// FindUnusedReg - Find a unused register of the specified register class.
106c0823fe7c679ca8f7d1667a310c2fca97b9402d5Jakob Stoklund Olesen  /// Return 0 if none is found.
107c0823fe7c679ca8f7d1667a310c2fca97b9402d5Jakob Stoklund Olesen  unsigned FindUnusedReg(const TargetRegisterClass *RegClass) const;
10896fa612373e258120d351ed14361f964ad22f99dEvan Cheng
109b74a3e6fda768eb6160559e025f8b65c46db46d9Evan Cheng  /// setScavengingFrameIndex / getScavengingFrameIndex - accessor and setter of
110b74a3e6fda768eb6160559e025f8b65c46db46d9Evan Cheng  /// ScavengingFrameIndex.
111b74a3e6fda768eb6160559e025f8b65c46db46d9Evan Cheng  void setScavengingFrameIndex(int FI) { ScavengingFrameIndex = FI; }
112b74a3e6fda768eb6160559e025f8b65c46db46d9Evan Cheng  int getScavengingFrameIndex() const { return ScavengingFrameIndex; }
113b74a3e6fda768eb6160559e025f8b65c46db46d9Evan Cheng
114b74a3e6fda768eb6160559e025f8b65c46db46d9Evan Cheng  /// scavengeRegister - Make a register of the specific register class
115a09f0d4ab76725827d1c4e737b99ff15ba454cbcEvan Cheng  /// available and do the appropriate bookkeeping. SPAdj is the stack
116a09f0d4ab76725827d1c4e737b99ff15ba454cbcEvan Cheng  /// adjustment due to call frame, it's passed along to eliminateFrameIndex().
117a09f0d4ab76725827d1c4e737b99ff15ba454cbcEvan Cheng  /// Returns the scavenged register.
118b74a3e6fda768eb6160559e025f8b65c46db46d9Evan Cheng  unsigned scavengeRegister(const TargetRegisterClass *RegClass,
119a09f0d4ab76725827d1c4e737b99ff15ba454cbcEvan Cheng                            MachineBasicBlock::iterator I, int SPAdj);
120a09f0d4ab76725827d1c4e737b99ff15ba454cbcEvan Cheng  unsigned scavengeRegister(const TargetRegisterClass *RegClass, int SPAdj) {
121a09f0d4ab76725827d1c4e737b99ff15ba454cbcEvan Cheng    return scavengeRegister(RegClass, MBBI, SPAdj);
122b74a3e6fda768eb6160559e025f8b65c46db46d9Evan Cheng  }
123b74a3e6fda768eb6160559e025f8b65c46db46d9Evan Cheng
124b58f498f7502e7e1833decbbbb4df771367c7341Jim Grosbach  /// setUsed - Tell the scavenger a register is used.
125b58f498f7502e7e1833decbbbb4df771367c7341Jim Grosbach  ///
126b58f498f7502e7e1833decbbbb4df771367c7341Jim Grosbach  void setUsed(unsigned Reg);
12796fa612373e258120d351ed14361f964ad22f99dEvan Chengprivate:
128e689ce626ce1d0022f70fb4a85113590bbdbb5e9Jakob Stoklund Olesen  /// isReserved - Returns true if a register is reserved. It is never "unused".
129e689ce626ce1d0022f70fb4a85113590bbdbb5e9Jakob Stoklund Olesen  bool isReserved(unsigned Reg) const { return ReservedRegs.test(Reg); }
130e689ce626ce1d0022f70fb4a85113590bbdbb5e9Jakob Stoklund Olesen
13144ac22cb27684e84f7d5bc6f3d6541de6d1f529eJim Grosbach  /// isUsed / isUnused - Test if a register is currently being used.
132e689ce626ce1d0022f70fb4a85113590bbdbb5e9Jakob Stoklund Olesen  ///
133e689ce626ce1d0022f70fb4a85113590bbdbb5e9Jakob Stoklund Olesen  bool isUsed(unsigned Reg) const   { return !RegsAvailable.test(Reg); }
134e689ce626ce1d0022f70fb4a85113590bbdbb5e9Jakob Stoklund Olesen  bool isUnused(unsigned Reg) const { return RegsAvailable.test(Reg); }
135e689ce626ce1d0022f70fb4a85113590bbdbb5e9Jakob Stoklund Olesen
136e689ce626ce1d0022f70fb4a85113590bbdbb5e9Jakob Stoklund Olesen  /// isAliasUsed - Is Reg or an alias currently in use?
137e689ce626ce1d0022f70fb4a85113590bbdbb5e9Jakob Stoklund Olesen  bool isAliasUsed(unsigned Reg) const;
138e689ce626ce1d0022f70fb4a85113590bbdbb5e9Jakob Stoklund Olesen
139e689ce626ce1d0022f70fb4a85113590bbdbb5e9Jakob Stoklund Olesen  /// setUsed / setUnused - Mark the state of one or a number of registers.
140e689ce626ce1d0022f70fb4a85113590bbdbb5e9Jakob Stoklund Olesen  ///
141e689ce626ce1d0022f70fb4a85113590bbdbb5e9Jakob Stoklund Olesen  void setUsed(BitVector &Regs) {
142e689ce626ce1d0022f70fb4a85113590bbdbb5e9Jakob Stoklund Olesen    RegsAvailable &= ~Regs;
143e689ce626ce1d0022f70fb4a85113590bbdbb5e9Jakob Stoklund Olesen  }
144e689ce626ce1d0022f70fb4a85113590bbdbb5e9Jakob Stoklund Olesen  void setUnused(BitVector &Regs) {
145e689ce626ce1d0022f70fb4a85113590bbdbb5e9Jakob Stoklund Olesen    RegsAvailable |= Regs;
146e689ce626ce1d0022f70fb4a85113590bbdbb5e9Jakob Stoklund Olesen  }
147d37c13cfd1bf4b08d0b99d93c799a1caa74cf3c6Evan Cheng
148dffb051c21d32209c601ca0ca6baae75b6c6463fJakob Stoklund Olesen  /// Add Reg and all its sub-registers to BV.
149dffb051c21d32209c601ca0ca6baae75b6c6463fJakob Stoklund Olesen  void addRegWithSubRegs(BitVector &BV, unsigned Reg);
150dffb051c21d32209c601ca0ca6baae75b6c6463fJakob Stoklund Olesen
151dffb051c21d32209c601ca0ca6baae75b6c6463fJakob Stoklund Olesen  /// Add Reg and its aliases to BV.
152dffb051c21d32209c601ca0ca6baae75b6c6463fJakob Stoklund Olesen  void addRegWithAliases(BitVector &BV, unsigned Reg);
15366a39699fb6b862e674415b32d307263812e996eJakob Stoklund Olesen
154b113cf2fedaf290242939c8f8c6f7e1438d46024Jim Grosbach  /// findSurvivorReg - Return the candidate register that is unused for the
155b113cf2fedaf290242939c8f8c6f7e1438d46024Jim Grosbach  /// longest after StartMI. UseMI is set to the instruction where the search
156b113cf2fedaf290242939c8f8c6f7e1438d46024Jim Grosbach  /// stopped.
157b113cf2fedaf290242939c8f8c6f7e1438d46024Jim Grosbach  ///
158b113cf2fedaf290242939c8f8c6f7e1438d46024Jim Grosbach  /// No more than InstrLimit instructions are inspected.
159b113cf2fedaf290242939c8f8c6f7e1438d46024Jim Grosbach  unsigned findSurvivorReg(MachineBasicBlock::iterator StartMI,
160b113cf2fedaf290242939c8f8c6f7e1438d46024Jim Grosbach                           BitVector &Candidates,
161b113cf2fedaf290242939c8f8c6f7e1438d46024Jim Grosbach                           unsigned InstrLimit,
162b113cf2fedaf290242939c8f8c6f7e1438d46024Jim Grosbach                           MachineBasicBlock::iterator &UseMI);
163b113cf2fedaf290242939c8f8c6f7e1438d46024Jim Grosbach
16496fa612373e258120d351ed14361f964ad22f99dEvan Cheng};
165dffb051c21d32209c601ca0ca6baae75b6c6463fJakob Stoklund Olesen
16696fa612373e258120d351ed14361f964ad22f99dEvan Cheng} // End llvm namespace
16796fa612373e258120d351ed14361f964ad22f99dEvan Cheng
16896fa612373e258120d351ed14361f964ad22f99dEvan Cheng#endif
169