namespace llvm {
+class MRegisterInfo;
+class TargetInstrInfo;
class TargetRegisterClass;
class RegScavenger {
MachineBasicBlock::iterator MBBI;
unsigned NumPhysRegs;
- /// Initialized - All states are initialized and ready to go!
- bool Initialized;
+ /// Tracking - True if RegScavenger is currently tracking the liveness of
+ /// registers.
+ bool Tracking;
- /// RegStates - The current state of all the physical registers immediately
+ /// ScavengingFrameIndex - Special spill slot used for scavenging a register
+ /// post register allocation.
+ int ScavengingFrameIndex;
+
+ /// ScavengedReg - If none zero, the specific register is currently being
+ /// scavenged. That is, it is spilled to the special scavenging stack slot.
+ unsigned ScavengedReg;
+
+ /// ScavengedRC - Register class of the scavenged register.
+ ///
+ const TargetRegisterClass *ScavengedRC;
+
+ /// RegsAvailable - The current state of all the physical registers immediately
/// before MBBI. One bit per physical register. If bit is set that means it's
/// available, unset means the register is currently being used.
- BitVector RegStates;
+ BitVector RegsAvailable;
public:
RegScavenger()
- : MBB(NULL), Initialized(false) {};
+ : MBB(NULL), NumPhysRegs(0), Tracking(false),
+ ScavengingFrameIndex(-1), ScavengedReg(0), ScavengedRC(NULL) {};
RegScavenger(MachineBasicBlock *mbb)
- : MBB(mbb), Initialized(false) {};
+ : MBB(mbb), NumPhysRegs(0), Tracking(false),
+ ScavengingFrameIndex(-1), ScavengedReg(0), ScavengedRC(NULL) {};
- /// Init - Initialize the states.
- ///
- void init();
-
- /// Reset - Discard previous states and re-initialize the states given for
- /// the specific basic block.
- void reset(MachineBasicBlock *mbb) {
- MBB = mbb;
- clear();
- init();
- }
+ /// enterBasicBlock - Start tracking liveness from the begin of the specific
+ /// basic block.
+ void enterBasicBlock(MachineBasicBlock *mbb);
/// forward / backward - Move the internal MBB iterator and update register
/// states.
void backward();
/// forward / backward - Move the internal MBB iterator and update register
- /// states until it has reached but not processed the specific iterator.
+ /// states until it has processed the specific iterator.
void forward(MachineBasicBlock::iterator I) {
while (MBBI != I) forward();
}
while (MBBI != I) backward();
}
+ /// skipTo - Move the internal MBB iterator but do not update register states.
+ ///
+ void skipTo(MachineBasicBlock::iterator I) { MBBI = I; }
+
/// isReserved - Returns true if a register is reserved. It is never "unused".
bool isReserved(unsigned Reg) const { return ReservedRegs[Reg]; }
/// isUsed / isUsed - Test if a register is currently being used.
///
- bool isUsed(unsigned Reg) const { return !RegStates[Reg]; }
- bool isUnused(unsigned Reg) const { return RegStates[Reg]; }
+ bool isUsed(unsigned Reg) const { return !RegsAvailable[Reg]; }
+ bool isUnused(unsigned Reg) const { return RegsAvailable[Reg]; }
+
+ /// getRegsUsed - return all registers currently in use in used.
+ void getRegsUsed(BitVector &used, bool includeReserved);
/// setUsed / setUnused - Mark the state of one or a number of registers.
///
- void setUsed(unsigned Reg) { RegStates.reset(Reg); }
- void setUsed(BitVector Regs) { RegStates &= ~Regs; }
- void setUnused(unsigned Reg) { RegStates.set(Reg); }
- void setUnused(BitVector Regs) { RegStates |= Regs; }
+ void setUsed(unsigned Reg) { RegsAvailable.reset(Reg); }
+ void setUsed(BitVector Regs) { RegsAvailable &= ~Regs; }
+ void setUnused(unsigned Reg) { RegsAvailable.set(Reg); }
+ void setUnused(BitVector Regs) { RegsAvailable |= Regs; }
+
+ /// FindUnusedReg - Find a unused register of the specified register class
+ /// from the specified set of registers. It return 0 is none is found.
+ unsigned FindUnusedReg(const TargetRegisterClass *RegClass,
+ const BitVector &Candidates) const;
/// FindUnusedReg - Find a unused register of the specified register class.
/// Exclude callee saved registers if directed. It return 0 is none is found.
unsigned FindUnusedReg(const TargetRegisterClass *RegClass,
bool ExCalleeSaved = false) const;
+ /// setScavengingFrameIndex / getScavengingFrameIndex - accessor and setter of
+ /// ScavengingFrameIndex.
+ void setScavengingFrameIndex(int FI) { ScavengingFrameIndex = FI; }
+ int getScavengingFrameIndex() const { return ScavengingFrameIndex; }
+
+ /// scavengeRegister - Make a register of the specific register class
+ /// available and do the appropriate bookkeeping. SPAdj is the stack
+ /// adjustment due to call frame, it's passed along to eliminateFrameIndex().
+ /// Returns the scavenged register.
+ unsigned scavengeRegister(const TargetRegisterClass *RegClass,
+ MachineBasicBlock::iterator I, int SPAdj);
+ unsigned scavengeRegister(const TargetRegisterClass *RegClass, int SPAdj) {
+ return scavengeRegister(RegClass, MBBI, SPAdj);
+ }
+
private:
- /// clear - Clear states.
- ///
- void clear();
+ const MRegisterInfo *RegInfo;
+ const TargetInstrInfo *TII;
/// CalleeSavedrRegs - A bitvector of callee saved registers for the target.
///
/// ReservedRegs - A bitvector of reserved registers.
///
BitVector ReservedRegs;
+
+ /// restoreScavengedReg - Restore scavenged by loading it back from the
+ /// emergency spill slot. Mark it used.
+ void restoreScavengedReg();
};
} // End llvm namespace