X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FRegAllocBase.h;h=c17a8d96ef6a303e1500eb7832c38ada8265a44c;hb=5be77762a3aa434ee877b0a03b98b5c3a7571918;hp=1534c0d7eb8259a48390103d0cb8304014a6bb82;hpb=e16eecc323879744dcff4f359ba9ccdb25bd6909;p=oota-llvm.git diff --git a/lib/CodeGen/RegAllocBase.h b/lib/CodeGen/RegAllocBase.h index 1534c0d7eb8..c17a8d96ef6 100644 --- a/lib/CodeGen/RegAllocBase.h +++ b/lib/CodeGen/RegAllocBase.h @@ -11,11 +11,11 @@ // register allocation algorithm and interface for extending it. It provides the // building blocks on which to construct other experimental allocators and test // the validity of two principles: -// +// // - If virtual and physical register liveness is modeled using intervals, then // on-the-fly interference checking is cheap. Furthermore, interferences can be // lazily cached and reused. -// +// // - Register allocation complexity, and generated code performance is // determined by the effectiveness of live range splitting rather than optimal // coloring. @@ -30,7 +30,7 @@ // of registers, if a more sophisticated allocator chooses to do that. // // This framework provides a way to engineer the compile time vs. code -// quality trade-off without relying a particular theoretical solver. +// quality trade-off without relying on a particular theoretical solver. // //===----------------------------------------------------------------------===// @@ -38,6 +38,8 @@ #define LLVM_CODEGEN_REGALLOCBASE #include "llvm/ADT/OwningPtr.h" +#include "llvm/CodeGen/LiveInterval.h" +#include "llvm/CodeGen/RegisterClassInfo.h" namespace llvm { @@ -45,86 +47,61 @@ template class SmallVectorImpl; class TargetRegisterInfo; class VirtRegMap; class LiveIntervals; - -// Heuristic that determines the priority of assigning virtual to physical -// registers. The main impact of the heuristic is expected to be compile time. -// The default is to simply compare spill weights. -struct LessSpillWeightPriority - : public std::binary_function { - bool operator()(const LiveInterval *left, const LiveInterval *right) const { - return left->weight < right->weight; - } -}; - -// Forward declare a priority queue of live virtual registers. If an -// implementation needs to prioritize by anything other than spill weight, then -// this will become an abstract base class with virtual calls to push/get. -class LiveVirtRegQueue; +class LiveRegMatrix; +class Spiller; /// RegAllocBase provides the register allocation driver and interface that can /// be extended to add interesting heuristics. /// -/// More sophisticated allocators must override the selectOrSplit() method to -/// implement live range splitting and must specify a comparator to determine -/// register assignment priority. LessSpillWeightPriority is provided as a -/// standard comparator. +/// Register allocators must override the selectOrSplit() method to implement +/// live range splitting. They must also override enqueue/dequeue to provide an +/// assignment order. class RegAllocBase { + virtual void anchor(); protected: - // Array of LiveIntervalUnions indexed by physical register. - class LIUArray { - unsigned nRegs_; - OwningArrayPtr array_; - public: - LIUArray(): nRegs_(0) {} - - unsigned numRegs() const { return nRegs_; } - - void init(unsigned nRegs); - - void clear(); - - LiveIntervalUnion& operator[](unsigned physReg) { - assert(physReg < nRegs_ && "physReg out of bounds"); - return array_[physReg]; - } - }; - - const TargetRegisterInfo *tri_; - VirtRegMap *vrm_; - LiveIntervals *lis_; - LIUArray physReg2liu_; - - RegAllocBase(): tri_(0), vrm_(0), lis_(0) {} + const TargetRegisterInfo *TRI; + MachineRegisterInfo *MRI; + VirtRegMap *VRM; + LiveIntervals *LIS; + LiveRegMatrix *Matrix; + RegisterClassInfo RegClassInfo; + + RegAllocBase(): TRI(0), MRI(0), VRM(0), LIS(0), Matrix(0) {} virtual ~RegAllocBase() {} // A RegAlloc pass should call this before allocatePhysRegs. - void init(const TargetRegisterInfo &tri, VirtRegMap &vrm, LiveIntervals &lis); + void init(VirtRegMap &vrm, LiveIntervals &lis, LiveRegMatrix &mat); // The top-level driver. The output is a VirtRegMap that us updated with // physical register assignments. - // - // If an implementation wants to override the LiveInterval comparator, we - // should modify this interface to allow passing in an instance derived from - // LiveVirtRegQueue. void allocatePhysRegs(); + // Get a temporary reference to a Spiller instance. + virtual Spiller &spiller() = 0; + + /// enqueue - Add VirtReg to the priority queue of unassigned registers. + virtual void enqueue(LiveInterval *LI) = 0; + + /// dequeue - Return the next unassigned register, or NULL. + virtual LiveInterval *dequeue() = 0; + // A RegAlloc pass should override this to provide the allocation heuristics. // Each call must guarantee forward progess by returning an available PhysReg // or new set of split live virtual registers. It is up to the splitter to // converge quickly toward fully spilled live ranges. - virtual unsigned selectOrSplit(LiveInterval &lvr, - SmallVectorImpl &splitLVRs) = 0; + virtual unsigned selectOrSplit(LiveInterval &VirtReg, + SmallVectorImpl &splitLVRs) = 0; + + // Use this group name for NamedRegionTimer. + static const char TimerGroupName[]; - // A RegAlloc pass should call this when PassManager releases its memory. - virtual void releaseMemory(); +public: + /// VerifyEnabled - True when -verify-regalloc is given. + static bool VerifyEnabled; - // Helper for checking interference between a live virtual register and a - // physical register, including all its register aliases. - bool checkPhysRegInterference(LiveIntervalUnion::Query &query, unsigned preg); - private: - void seedLiveVirtRegs(LiveVirtRegQueue &lvrQ); + void seedLiveRegs(); }; } // end namespace llvm