//
// The LLVM Compiler Infrastructure
//
-// This file was developed by the Evan Cheng and is distributed under the
-// University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CODEGEN_REGISTER_SCAVENGING_H
-#define LLVM_CODEGEN_REGISTER_SCAVENGING_H
+#ifndef LLVM_CODEGEN_REGISTERSCAVENGING_H
+#define LLVM_CODEGEN_REGISTERSCAVENGING_H
-#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/ADT/BitVector.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
namespace llvm {
+class MachineRegisterInfo;
+class TargetRegisterInfo;
+class TargetInstrInfo;
class TargetRegisterClass;
class RegScavenger {
+ const TargetRegisterInfo *TRI;
+ const TargetInstrInfo *TII;
+ MachineRegisterInfo* MRI;
MachineBasicBlock *MBB;
MachineBasicBlock::iterator MBBI;
unsigned NumPhysRegs;
/// 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;
+
+ /// ScavengeRestore - Instruction that restores the scavenged register from
+ /// stack.
+ const MachineInstr *ScavengeRestore;
+
+ /// CalleeSavedrRegs - A bitvector of callee saved registers for the target.
+ ///
+ BitVector CalleeSavedRegs;
+
+ /// 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;
+
+ // These BitVectors are only used internally to forward(). They are members
+ // to avoid frequent reallocations.
+ BitVector KillRegs, DefRegs;
public:
RegScavenger()
- : MBB(NULL), NumPhysRegs(0), Tracking(false) {};
+ : MBB(NULL), NumPhysRegs(0), Tracking(false),
+ ScavengingFrameIndex(-1), ScavengedReg(0), ScavengedRC(NULL) {}
- RegScavenger(MachineBasicBlock *mbb)
- : MBB(mbb), NumPhysRegs(0), Tracking(false) {};
+ /// enterBasicBlock - Start tracking liveness from the begin of the specific
+ /// basic block.
+ void enterBasicBlock(MachineBasicBlock *mbb);
- /// Init - Initialize the states.
- ///
- void init(MachineBasicBlock *mbb);
+ /// initRegState - allow resetting register state info for multiple
+ /// passes over/within the same function.
+ void initRegState();
- /// Reset - Discard previous states and re-initialize the states given for
- /// the specific basic block.
- void reset(MachineBasicBlock *mbb) {
- clear();
- init(mbb);
- }
-
- /// forward / backward - Move the internal MBB iterator and update register
- /// states.
+ /// forward - Move the internal MBB iterator and update register states.
void forward();
- void backward();
- /// forward / backward - Move the internal MBB iterator and update register
- /// states until it has reached but not processed the specific iterator.
+ /// forward - Move the internal MBB iterator and update register states until
+ /// it has processed the specific iterator.
void forward(MachineBasicBlock::iterator I) {
+ if (!Tracking && MBB->begin() != I) forward();
while (MBBI != I) forward();
}
- void backward(MachineBasicBlock::iterator I) {
- while (MBBI != I) backward();
- }
-
- /// 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.
+ /// skipTo - Move the internal MBB iterator but do not update register states.
///
- bool isUsed(unsigned Reg) const { return !RegStates[Reg]; }
- bool isUnused(unsigned Reg) const { return RegStates[Reg]; }
+ void skipTo(MachineBasicBlock::iterator I) { MBBI = I; }
- /// 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; }
+ /// getRegsUsed - return all registers currently in use in used.
+ void getRegsUsed(BitVector &used, bool includeReserved);
+
+ /// getRegsAvailable - Return all available registers in the register class
+ /// in Mask.
+ BitVector getRegsAvailable(const TargetRegisterClass *RC);
/// 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;
+ /// Return 0 if none is found.
+ unsigned FindUnusedReg(const TargetRegisterClass *RegClass) 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);
+ }
+ /// setUsed - Tell the scavenger a register is used.
+ ///
+ void setUsed(unsigned Reg);
private:
- /// clear - Clear states.
+ /// isReserved - Returns true if a register is reserved. It is never "unused".
+ bool isReserved(unsigned Reg) const { return MRI->isReserved(Reg); }
+
+ /// isUsed - Test if a register is currently being used. When called by the
+ /// isAliasUsed function, we only check isReserved if this is the original
+ /// register, not an alias register.
///
- void clear();
+ bool isUsed(unsigned Reg, bool CheckReserved = true) const {
+ return !RegsAvailable.test(Reg) || (CheckReserved && isReserved(Reg));
+ }
- /// CalleeSavedrRegs - A bitvector of callee saved registers for the target.
+ /// isAliasUsed - Is Reg or an alias currently in use?
+ bool isAliasUsed(unsigned Reg) const;
+
+ /// setUsed / setUnused - Mark the state of one or a number of registers.
///
- BitVector CalleeSavedRegs;
+ void setUsed(BitVector &Regs) {
+ RegsAvailable.reset(Regs);
+ }
+ void setUnused(BitVector &Regs) {
+ RegsAvailable |= Regs;
+ }
+
+ /// Add Reg and all its sub-registers to BV.
+ void addRegWithSubRegs(BitVector &BV, unsigned Reg);
- /// ReservedRegs - A bitvector of reserved registers.
+ /// findSurvivorReg - Return the candidate register that is unused for the
+ /// longest after StartMI. UseMI is set to the instruction where the search
+ /// stopped.
///
- BitVector ReservedRegs;
+ /// No more than InstrLimit instructions are inspected.
+ unsigned findSurvivorReg(MachineBasicBlock::iterator StartMI,
+ BitVector &Candidates,
+ unsigned InstrLimit,
+ MachineBasicBlock::iterator &UseMI);
+
};
-
+
} // End llvm namespace
#endif