X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FCodeGen%2FRegisterScavenging.h;h=122c78534253ebf0f603eb2ebee2c83f4cfde796;hb=23c4c62511ff7846af251d2a7ac0cd8c6a558f6b;hp=2b86e5fda7d4e352f724eff7b1acbd9e0a9f9de4;hpb=9390cd0e86cb3b79f6836acab2a27b275e5bde9e;p=oota-llvm.git diff --git a/include/llvm/CodeGen/RegisterScavenging.h b/include/llvm/CodeGen/RegisterScavenging.h index 2b86e5fda7d..122c7853425 100644 --- a/include/llvm/CodeGen/RegisterScavenging.h +++ b/include/llvm/CodeGen/RegisterScavenging.h @@ -9,17 +9,17 @@ // // This file declares the machine register scavenger class. It can provide // information such as unused register at any point in a machine basic block. -// It also provides a mechanism to make registers availbale by evicting them +// It also provides a mechanism to make registers available by evicting them // to spill slots. // //===----------------------------------------------------------------------===// -#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/ADT/DenseMap.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" namespace llvm { @@ -34,114 +34,108 @@ class RegScavenger { MachineRegisterInfo* MRI; MachineBasicBlock *MBB; MachineBasicBlock::iterator MBBI; - unsigned NumPhysRegs; + unsigned NumRegUnits; - /// Tracking - True if RegScavenger is currently tracking the liveness of - /// registers. + /// True if RegScavenger is currently tracking the liveness of registers. bool Tracking; - /// 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; + /// Information on scavenged registers (held in a spill slot). + struct ScavengedInfo { + ScavengedInfo(int FI = -1) : FrameIndex(FI), Reg(0), Restore(nullptr) {} - /// ScavengeRestore - Instruction that restores the scavenged register from - /// stack. - const MachineInstr *ScavengeRestore; + /// A spill slot used for scavenging a register post register allocation. + int FrameIndex; - /// CalleeSavedrRegs - A bitvector of callee saved registers for the target. - /// - BitVector CalleeSavedRegs; + /// If non-zero, the specific register is currently being + /// scavenged. That is, it is spilled to this scavenging stack slot. + unsigned Reg; - /// ReservedRegs - A bitvector of reserved registers. - /// - BitVector ReservedRegs; + /// The instruction that restores the scavenged register from stack. + const MachineInstr *Restore; + }; - /// 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 RegsAvailable; + /// A vector of information on scavenged registers. + SmallVector Scavenged; - /// CurrDist - Distance from MBB entry to the current instruction MBBI. - /// - unsigned CurrDist; + /// The current state of each reg unit immediately before MBBI. + /// One bit per register unit. If bit is not set it means any + /// register containing that register unit is currently being used. + BitVector RegUnitsAvailable; - /// DistanceMap - Keep track the distance of a MI from the start of the - /// current basic block. - DenseMap DistanceMap; + // These BitVectors are only used internally to forward(). They are members + // to avoid frequent reallocations. + BitVector KillRegUnits, DefRegUnits; + BitVector TmpRegUnits; public: RegScavenger() - : MBB(NULL), NumPhysRegs(0), Tracking(false), - ScavengingFrameIndex(-1), ScavengedReg(0), ScavengedRC(NULL) {} + : MBB(nullptr), NumRegUnits(0), Tracking(false) {} - /// enterBasicBlock - Start tracking liveness from the begin of the specific - /// basic block. + /// Start tracking liveness from the begin of the specific basic block. void enterBasicBlock(MachineBasicBlock *mbb); - /// initRegState - allow resetting register state info for multiple - /// passes over/within the same function. - void initRegState(); - - /// forward - Move the internal MBB iterator and update register states. + /// Move the internal MBB iterator and update register states. void forward(); - /// forward - Move the internal MBB iterator and update register states until + /// 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(); } - /// skipTo - Move the internal MBB iterator but do not update register states. - /// - void skipTo(MachineBasicBlock::iterator I) { MBBI = I; } + /// Invert the behavior of forward() on the current instruction (undo the + /// changes to the available registers made by forward()). + void unprocess(); - /// isReserved - Returns true if a register is reserved. It is never "unused". - bool isReserved(unsigned Reg) const { return ReservedRegs[Reg]; } + /// Unprocess instructions until you reach the provided iterator. + void unprocess(MachineBasicBlock::iterator I) { + while (MBBI != I) unprocess(); + } - /// isUsed / isUsed - Test if a register is currently being used. - /// - bool isUsed(unsigned Reg) const { return !RegsAvailable[Reg]; } - bool isUnused(unsigned Reg) const { return RegsAvailable[Reg]; } + /// Move the internal MBB iterator but do not update register states. + void skipTo(MachineBasicBlock::iterator I) { + if (I == MachineBasicBlock::iterator(nullptr)) + Tracking = false; + MBBI = I; + } - /// getRegsUsed - return all registers currently in use in used. - void getRegsUsed(BitVector &used, bool includeReserved); + MachineBasicBlock::iterator getCurrentPosition() const { return MBBI; } - /// setUsed / setUnused - Mark the state of one or a number of registers. - /// - void setUsed(unsigned Reg); - void setUsed(BitVector &Regs) { - RegsAvailable &= ~Regs; - } - void setUnused(unsigned Reg, const MachineInstr *MI); - void setUnused(BitVector &Regs) { - RegsAvailable |= Regs; + /// Return if a specific register is currently used. + bool isRegUsed(unsigned Reg, bool includeReserved = true) const; + + /// Return all available registers in the register class in Mask. + BitVector getRegsAvailable(const TargetRegisterClass *RC); + + /// Find an unused register of the specified register class. + /// Return 0 if none is found. + unsigned FindUnusedReg(const TargetRegisterClass *RegClass) const; + + /// Add a scavenging frame index. + void addScavengingFrameIndex(int FI) { + Scavenged.push_back(ScavengedInfo(FI)); } - /// 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; + /// Query whether a frame index is a scavenging frame index. + bool isScavengingFrameIndex(int FI) const { + for (SmallVectorImpl::const_iterator I = Scavenged.begin(), + IE = Scavenged.end(); I != IE; ++I) + if (I->FrameIndex == FI) + return true; - /// 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 false; + } - /// setScavengingFrameIndex / getScavengingFrameIndex - accessor and setter of - /// ScavengingFrameIndex. - void setScavengingFrameIndex(int FI) { ScavengingFrameIndex = FI; } - int getScavengingFrameIndex() const { return ScavengingFrameIndex; } + /// Get an array of scavenging frame indices. + void getScavengingFrameIndices(SmallVectorImpl &A) const { + for (SmallVectorImpl::const_iterator I = Scavenged.begin(), + IE = Scavenged.end(); I != IE; ++I) + if (I->FrameIndex >= 0) + A.push_back(I->FrameIndex); + } - /// scavengeRegister - Make a register of the specific register class + /// 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. @@ -151,20 +145,40 @@ public: return scavengeRegister(RegClass, MBBI, SPAdj); } + /// Tell the scavenger a register is used. + void setRegUsed(unsigned Reg, LaneBitmask LaneMask = ~0u); private: - /// restoreScavengedReg - Restore scavenged by loading it back from the - /// emergency spill slot. Mark it used. - void restoreScavengedReg(); + /// Returns true if a register is reserved. It is never "unused". + bool isReserved(unsigned Reg) const { return MRI->isReserved(Reg); } - MachineInstr *findFirstUse(MachineBasicBlock *MBB, - MachineBasicBlock::iterator I, unsigned Reg, - unsigned &Dist); + /// setUsed / setUnused - Mark the state of one or a number of register units. + /// + void setUsed(BitVector &RegUnits) { + RegUnitsAvailable.reset(RegUnits); + } + void setUnused(BitVector &RegUnits) { + RegUnitsAvailable |= RegUnits; + } - /// Add Reg and all its sub-registers to BV. - void addRegWithSubRegs(BitVector &BV, unsigned Reg); + /// Processes the current instruction and fill the KillRegUnits and + /// DefRegUnits bit vectors. + void determineKillsAndDefs(); - /// Add Reg and its aliases to BV. - void addRegWithAliases(BitVector &BV, unsigned Reg); + /// Add all Reg Units that Reg contains to BV. + void addRegUnits(BitVector &BV, unsigned Reg); + + /// Return the candidate register that is unused for the longest after + /// StartMI. UseMI is set to the instruction where the search stopped. + /// + /// No more than InstrLimit instructions are inspected. + unsigned findSurvivorReg(MachineBasicBlock::iterator StartMI, + BitVector &Candidates, + unsigned InstrLimit, + MachineBasicBlock::iterator &UseMI); + + /// Allow resetting register state info for multiple + /// passes over/within the same function. + void initRegState(); }; } // End llvm namespace