From 7cd2ca13c1920e9db68695a364048cb6586bb324 Mon Sep 17 00:00:00 2001 From: Ruchira Sasanka Date: Sat, 8 Sep 2001 14:22:50 +0000 Subject: [PATCH] Committed for compliation. Not yet final. --Ruchira git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@505 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/InterferenceGraph.h | 76 +++++++++++ include/llvm/CodeGen/MachineInstr.h | 23 +++- include/llvm/CodeGen/MachineRegInfo.h | 121 +++++++++++++++++ include/llvm/CodeGen/RegAllocCommon.h | 10 ++ include/llvm/CodeGen/RegClass.h | 125 ++++++++++++++++++ include/llvm/CodeGen/RegColorMap.h | 37 ++++++ include/llvm/CodeGen/Sparc.h | 34 ++++- include/llvm/CodeGen/SparcRegInfo.h | 5 +- include/llvm/CodeGen/TargetData.h | 1 + include/llvm/CodeGen/TargetMachine.h | 18 ++- lib/CodeGen/RegAlloc/InterferenceGraph.h | 76 +++++++++++ lib/CodeGen/RegAlloc/PhyRegAlloc.h | 106 +++++++++++++++ lib/CodeGen/RegAlloc/RegAllocCommon.h | 10 ++ lib/CodeGen/RegAlloc/RegClass.h | 125 ++++++++++++++++++ .../SparcV9/RegAlloc/InterferenceGraph.h | 76 +++++++++++ lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h | 106 +++++++++++++++ lib/Target/SparcV9/RegAlloc/RegAllocCommon.h | 10 ++ lib/Target/SparcV9/RegAlloc/RegClass.h | 125 ++++++++++++++++++ 18 files changed, 1074 insertions(+), 10 deletions(-) create mode 100644 include/llvm/CodeGen/InterferenceGraph.h create mode 100644 include/llvm/CodeGen/MachineRegInfo.h create mode 100644 include/llvm/CodeGen/RegAllocCommon.h create mode 100644 include/llvm/CodeGen/RegClass.h create mode 100644 include/llvm/CodeGen/RegColorMap.h create mode 100644 lib/CodeGen/RegAlloc/InterferenceGraph.h create mode 100644 lib/CodeGen/RegAlloc/PhyRegAlloc.h create mode 100644 lib/CodeGen/RegAlloc/RegAllocCommon.h create mode 100644 lib/CodeGen/RegAlloc/RegClass.h create mode 100644 lib/Target/SparcV9/RegAlloc/InterferenceGraph.h create mode 100644 lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h create mode 100644 lib/Target/SparcV9/RegAlloc/RegAllocCommon.h create mode 100644 lib/Target/SparcV9/RegAlloc/RegClass.h diff --git a/include/llvm/CodeGen/InterferenceGraph.h b/include/llvm/CodeGen/InterferenceGraph.h new file mode 100644 index 00000000000..99dea8fbe0a --- /dev/null +++ b/include/llvm/CodeGen/InterferenceGraph.h @@ -0,0 +1,76 @@ +/* Title: InterferenceGraph.h + Author: Ruchira Sasanka + Date: July 20, 01 + Purpose: Interference Graph used for register coloring. + + Notes: + Adj Info is stored in the lower trangular matrix (i.e., row > col ) + + This class must be used in the following way: + + * Construct class + * call addLRToIG as many times to add ALL LRs to this IG + * call createGraph to create the actual matrix + * Then setInterference, getInterference, mergeIGNodesOfLRs can be + called as desired to modify the graph. + * Once the modifications to the graph are over, call + setCurDegreeOfIGNodes() before pushing IGNodes on to stack for coloring. +*/ + + +#ifndef INTERFERENCE_GRAPH_H +#define INTERFERENCE_GRAPH_H + + +#include "llvm/CodeGen/IGNode.h" + +typedef vector IGNodeListType; + + +class InterferenceGraph +{ + char **IG; // a poiner to the interference graph + unsigned int Size; // size of a side of the IG + RegClass *const RegCl; // RegCl contains this IG + IGNodeListType IGNodeList; // a list of all IGNodes in a reg class + + // for asserting this IG node is infact in the IGNodeList of this class + inline void assertIGNode(const IGNode *const Node) const { + assert( IGNodeList[ Node->getIndex() ] == Node ); + } + + + + public: + + // the matrix is not yet created by the constructor. Call createGraph() + // to create it after adding all IGNodes to the IGNodeList + + InterferenceGraph(RegClass *const RC); + void createGraph(); + + void addLRToIG(LiveRange *const LR); + + void setInterference(const LiveRange *const LR1, + const LiveRange *const LR2 ); + + unsigned getInterference(const LiveRange *const LR1, + const LiveRange *const LR2 ) const ; + + void mergeIGNodesOfLRs(const LiveRange *const LR1, LiveRange *const LR2); + + inline IGNodeListType &getIGNodeList() { return IGNodeList; } + + void setCurDegreeOfIGNodes(); + + void printIG() const; + void printIGNodeList() const; + + ~InterferenceGraph(); + + +}; + + +#endif + diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index fbb3106810d..949c1832d1b 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -135,6 +135,17 @@ private: friend class MachineInstr; friend class ValOpIterator; friend class ValOpIterator< MachineInstr, Value>; + + +public: + + // this replaces a value with a register after register allcoation + void setRegForValue(int Reg) { + assert(opType == MO_VirtualRegister || opType == MO_CCRegister); + opType = MO_MachineRegister; + regNum = Reg; + } + }; @@ -244,6 +255,10 @@ public: bool operandIsDefined(unsigned int i) const; void dump (unsigned int indent = 0) const; + + + + public: friend ostream& operator<<(ostream& os, const MachineInstr& minstr); @@ -395,10 +410,10 @@ MachineCodeForVMInstr::~MachineCodeForVMInstr() //--------------------------------------------------------------------------- -class MachineCodeForBasicBlock: public vector { +class MachineCodeForBasicBlock: public vector { public: - typedef vector::iterator iterator; - typedef vector::const_iterator const_iterator; + typedef vector::iterator iterator; + typedef vector::const_iterator const_iterator; }; @@ -461,7 +476,7 @@ ostream& operator<<(ostream& os, const MachineInstr& minstr); ostream& operator<<(ostream& os, const MachineOperand& mop); -void PrintMachineInstructions (Method* method); +void PrintMachineInstructions (const Method *const method); //**************************************************************************/ diff --git a/include/llvm/CodeGen/MachineRegInfo.h b/include/llvm/CodeGen/MachineRegInfo.h new file mode 100644 index 00000000000..64fd29eee51 --- /dev/null +++ b/include/llvm/CodeGen/MachineRegInfo.h @@ -0,0 +1,121 @@ +/* Title: MachineRegInfo.h + Author: Ruchira Sasanka + Date: Aug 20, 01 + Purpose: Contains the description of machine register classes. + + Notes: + + A machine will have several register classes. For each register class, the + machine has to provide a class which is derived class of the virtual class + MachineRegClass. This virtual class itself is machine independent but + the derived classes are all machine dependent. +*/ + + +#ifndef MACHINE_REG_INFO_H +#define MACHINE_REG_INFO_H + +#include "llvm/CodeGen/MachineInstr.h" + + + +// This is the virtual class which must be subclassed by all machine specific +// register classes. + + unsigned RegClassID; // integer ID of a reg class + unsigned NumOfAvailRegs; // # of avail for coloring (without SP, g0 etc) + unsigned NumOfAllRegs; // # of all registers (including SP, g0 etc + + +class MachineRegClass +{ + + private: + const unsigned RegClassID; + + public: + + virtual unsigned getRegClassID() const = 0; + + // Number of registes available for coloring (e.g., without SP, g0 etc) + virtual unsigned getNumOfAvailRegs() const = 0; + + // Number of all registers (e.g., including SP, g0 etc) + virtual unsigned getNumOfAllRegs() const = 0; + + // This method should find a color which is not used by neighbors + // (i.e., a false position in IsColorUsedArr) and + virtual void colorIGNode(IGNode * Node, bool IsColorUsedArr[] ) const = 0; + + + MachineRegClass(const unsigned ID) : RegClassID(ID) { } + + +}; + + +// include .h files that describes machine reg classes here + +#include "RegAlloc/Sparc/SparcIntRegClass.h" + +typedef vector MachineRegClassArrayType; + + + +class MachineRegInfo +{ + private: + + // A vector of all machine register classes + MachineRegClassArrayType MachineRegClassArr; + + + public: + + MachineRegInfo() : MachineRegClassArr() { + + MachineRegClassArr.push_back( new SparcIntRegClass(0) ); + // RegClassArr.pushback( new SparcFloatRegClass(1) ); + // RegClassArr.pushback( new SparcFloatCCRegClass(2) ); + + if(DEBUG_RA) + cout << "Created machine register classes." << endl; + + } + + + inline unsigned int getNumOfRegClasses() const { + return MachineRegClassArr.size(); + } + + unsigned getRegClassIDOfValue (const Value *const Val) const ; + + const MachineRegClass *const getMachineRegClass(unsigned i) const { + return MachineRegClassArr[i]; + } + + inline bool isCallInst(const MachineInstr *const MI) const { + MachineOpCode Op = MI->getOpCode(); + return false; // ######################################## + // return (Op == CALL || Op == JMPL); + } + +}; + + +// This function should detrmine the register class of a value. This can be +// done on type information in the value class. The register class returned +// must be same as the array index of RegClassArr. + +unsigned MachineRegInfo::getRegClassIDOfValue (const Value *const Val) const +{ + + return 0; + +} + + + + +#endif + diff --git a/include/llvm/CodeGen/RegAllocCommon.h b/include/llvm/CodeGen/RegAllocCommon.h new file mode 100644 index 00000000000..2e3286a887d --- /dev/null +++ b/include/llvm/CodeGen/RegAllocCommon.h @@ -0,0 +1,10 @@ +#ifndef REG_ALLOC_COMMON_H +#define REG_ALLOC_COMMON_H + +// set DEBUG_RA for printing out debug messages +// if DEBUG_RA is 1 normal output messages +// if DEBUG_RA is 2 extensive debug info for each instr + +#define DEBUG_RA (1) + +#endif diff --git a/include/llvm/CodeGen/RegClass.h b/include/llvm/CodeGen/RegClass.h new file mode 100644 index 00000000000..1d08502445d --- /dev/null +++ b/include/llvm/CodeGen/RegClass.h @@ -0,0 +1,125 @@ +/* Title: RegClass.h + Author: Ruchira Sasanka + Date: Aug 20, 01 + Purpose: Contains machine independent methods for register coloring. + + This is the class that contains all data structures and common algos + for coloring a particular register class (e.g., int class, fp class). + This class is hardware independent. This class accepts a hardware + dependent description of machine registers (MachineRegInfo class) to + get hardware specific info and color and indidual IG node. + + This class contains the InterferenceGraph (IG). + Also it contains an IGNode stack that can be used for coloring. + The class provides some easy access methods to the IG methods, since these + methods are called thru a register class. + +*/ + + + +#ifndef REG_CLASS_H +#define REG_CLASS_H + +#include "llvm/CodeGen/IGNode.h" +#include "llvm/CodeGen/InterferenceGraph.h" +#include "llvm/CodeGen/TargetMachine.h" + + +#include + + +typedef vector ReservedColorListType; + + +class RegClass +{ + + private: + const Method *const Meth; // Method we are working on + + const MachineRegClassInfo *const MRC; // corresponding MRC + + const unsigned RegClassID; // my int ID + + InterferenceGraph IG; // Interference graph - constructed by + // buildInterferenceGraph + stack IGNodeStack; // the stack used for coloring + + // for passing registered that are pre-allocated (e.g., %g's) + const ReservedColorListType *const ReservedColorList; + + // An array used for coloring each node. This array must be of size + // MRC->getNumOfAllRegs(). Allocated once in the constructor + // for efficiency. + bool *IsColorUsedArr; + + + //------------ private methods ------------------ + + void pushAllIGNodes(); + bool pushUnconstrainedIGNodes(); + IGNode * getIGNodeWithMinSpillCost(); + void colorIGNode(IGNode *const Node); + + public: + + RegClass(const Method *const M, + const MachineRegClassInfo *const MRC, + const ReservedColorListType *const RCL = NULL); + + inline void createInterferenceGraph() + { IG.createGraph(); } + + inline InterferenceGraph &getIG() { return IG; } + + inline const unsigned getID() const { return RegClassID; } + + void colorAllRegs(); // main method called for coloring regs + + inline unsigned getNumOfAvailRegs() const + { return MRC->getNumOfAvailRegs(); } + + ~RegClass() { delete[] IsColorUsedArr; }; + + + + // --- following methods are provided to access the IG contained within this + // ---- RegClass easilly. + + + inline void addLRToIG(LiveRange *const LR) + { IG.addLRToIG(LR); } + + inline void setInterference(const LiveRange *const LR1, + const LiveRange *const LR2) + { IG.setInterference(LR1, LR2); } + + inline unsigned getInterference(const LiveRange *const LR1, + const LiveRange *const LR2) const + { return IG.getInterference(LR1, LR2); } + + inline void mergeIGNodesOfLRs(const LiveRange *const LR1, + LiveRange *const LR2) + { IG.mergeIGNodesOfLRs(LR1, LR2); } + + + inline void printIGNodeList() const { + cout << "IG Nodes for Register Class " << RegClassID << ":" << endl; + IG.printIGNodeList(); + } + + inline void printIG() { + cout << "IG for Register Class " << RegClassID << ":" << endl; + IG.printIG(); + } + +}; + + + + + + + +#endif diff --git a/include/llvm/CodeGen/RegColorMap.h b/include/llvm/CodeGen/RegColorMap.h new file mode 100644 index 00000000000..10987a59275 --- /dev/null +++ b/include/llvm/CodeGen/RegColorMap.h @@ -0,0 +1,37 @@ +#ifndef REG_COLOR_MAP +#define REG_COLOR_MAP + +#include + + +#ifndef VALUE_SET_H + +struct hashFuncValue { // sturcture containing the hash func + inline size_t operator () (const Value *const val) const + { return (size_t) val; } +}; + +#endif + + +typedef int RegColorType; + + +class RegColorMap : hash_map +{ + + public: + + inline void setRegColor(const Value *const Val, RegColorType Col) { + (*this)[Val] = Col; + } + + + inline RegColorType getRegColor(const Value *const Val) { + return (*this)[Val]; + } + + +}; + +#endif diff --git a/include/llvm/CodeGen/Sparc.h b/include/llvm/CodeGen/Sparc.h index 776dc84491e..8c964fe8117 100644 --- a/include/llvm/CodeGen/Sparc.h +++ b/include/llvm/CodeGen/Sparc.h @@ -933,10 +933,40 @@ class UltraSparcRegInfo : public MachineRegInfo void colorArgs(const Method *const Meth, LiveRangeInfo& LRI) const; - static void printReg(const LiveRange *const LR); + static void printReg(const LiveRange *const LR) ; void colorCallArgs(vector & CallInstrList, - LiveRangeInfo& LRI ) const; + LiveRangeInfo& LRI, + AddedInstrMapType& AddedInstrMap ) const; + + // this method provides a unique number for each register + inline int getUnifiedRegNum(int RegClassID, int reg) const { + + if( RegClassID == IntRegClassID && reg < 32 ) + return reg; + else if ( RegClassID == FloatRegClassID && reg < 64) + return reg + 32; // we have 32 int regs + else if( RegClassID == FloatCCREgClassID && reg < 4) + return reg + 32 + 64; // 32 int, 64 float + else + assert(0 && "Invalid register class or reg number"); + + } + + // given the unified register number, this gives the name + inline const string getUnifiedRegName(int reg) const { + + if( reg < 32 ) + return SparcIntRegOrder::getRegName(reg); + else if ( reg < (64 + 32) ) + return SparcFloatRegOrder::getRegName( reg - 32); + else if( reg < (64+32+4) ) + assert( 0 && "no float condition reg class yet"); + // return reg + 32 + 64; + else + assert(0 && "Invalid register number"); + } + }; diff --git a/include/llvm/CodeGen/SparcRegInfo.h b/include/llvm/CodeGen/SparcRegInfo.h index c97eb9d7e38..41a6d00a081 100644 --- a/include/llvm/CodeGen/SparcRegInfo.h +++ b/include/llvm/CodeGen/SparcRegInfo.h @@ -54,9 +54,9 @@ class SparcIntRegOrder{ // --- following colors are not available for allocation within this phase // --- but can appear for pre-colored ranges - g0, i6, i7, o6, + g0, i6, i7, o6 - NumOfAllRegs // place holder to count all possilbe colors + }; @@ -65,6 +65,7 @@ class SparcIntRegOrder{ static unsigned int const StartOfNonVolatileRegs = l0; static unsigned int const StartOfAllRegs = g1; + static unsigned int const NumOfAllRegs = o6 + 1; static const string getRegName(const unsigned reg) { diff --git a/include/llvm/CodeGen/TargetData.h b/include/llvm/CodeGen/TargetData.h index cf449702b7b..c5675a8c431 100644 --- a/include/llvm/CodeGen/TargetData.h +++ b/include/llvm/CodeGen/TargetData.h @@ -14,6 +14,7 @@ #define LLVM_CODEGEN_TARGETDATA_H #include "llvm/Type.h" +#include "llvm/Annotation.h" #include class StructType; diff --git a/include/llvm/CodeGen/TargetMachine.h b/include/llvm/CodeGen/TargetMachine.h index 7682ad955ad..c35e51b1ae8 100644 --- a/include/llvm/CodeGen/TargetMachine.h +++ b/include/llvm/CodeGen/TargetMachine.h @@ -224,8 +224,12 @@ public: return getDescriptor(opCode).iclass & M_DUMMY_PHI_FLAG; } + + // delete this later ******* + bool isPhi(MachineOpCode opCode) { return isDummyPhiInstr(opCode); } - // + + // Check if an instruction can be issued before its operands are ready, // or if a subsequent instruction that uses its result can be issued // before the results are ready. @@ -685,6 +689,10 @@ class Value; class LiveRangeInfo; class Method; class Instruction; +class LiveRange; +class AddedInstrns; +class MachineInstr; +typedef hash_map AddedInstrMapType; // A vector of all machine register classes typedef vector MachineRegClassArrayType; @@ -715,8 +723,14 @@ public: LiveRangeInfo & LRI) const = 0; virtual void colorCallArgs(vector & CallInstrList, - LiveRangeInfo& LRI ) const = 0 ; + LiveRangeInfo& LRI, + AddedInstrMapType& AddedInstrMap ) const = 0 ; + virtual int getUnifiedRegNum(int RegClassID, int reg) const = 0; + + virtual const string getUnifiedRegName(int reg) const = 0; + + //virtual void printReg(const LiveRange *const LR) const =0; MachineRegInfo() { } diff --git a/lib/CodeGen/RegAlloc/InterferenceGraph.h b/lib/CodeGen/RegAlloc/InterferenceGraph.h new file mode 100644 index 00000000000..99dea8fbe0a --- /dev/null +++ b/lib/CodeGen/RegAlloc/InterferenceGraph.h @@ -0,0 +1,76 @@ +/* Title: InterferenceGraph.h + Author: Ruchira Sasanka + Date: July 20, 01 + Purpose: Interference Graph used for register coloring. + + Notes: + Adj Info is stored in the lower trangular matrix (i.e., row > col ) + + This class must be used in the following way: + + * Construct class + * call addLRToIG as many times to add ALL LRs to this IG + * call createGraph to create the actual matrix + * Then setInterference, getInterference, mergeIGNodesOfLRs can be + called as desired to modify the graph. + * Once the modifications to the graph are over, call + setCurDegreeOfIGNodes() before pushing IGNodes on to stack for coloring. +*/ + + +#ifndef INTERFERENCE_GRAPH_H +#define INTERFERENCE_GRAPH_H + + +#include "llvm/CodeGen/IGNode.h" + +typedef vector IGNodeListType; + + +class InterferenceGraph +{ + char **IG; // a poiner to the interference graph + unsigned int Size; // size of a side of the IG + RegClass *const RegCl; // RegCl contains this IG + IGNodeListType IGNodeList; // a list of all IGNodes in a reg class + + // for asserting this IG node is infact in the IGNodeList of this class + inline void assertIGNode(const IGNode *const Node) const { + assert( IGNodeList[ Node->getIndex() ] == Node ); + } + + + + public: + + // the matrix is not yet created by the constructor. Call createGraph() + // to create it after adding all IGNodes to the IGNodeList + + InterferenceGraph(RegClass *const RC); + void createGraph(); + + void addLRToIG(LiveRange *const LR); + + void setInterference(const LiveRange *const LR1, + const LiveRange *const LR2 ); + + unsigned getInterference(const LiveRange *const LR1, + const LiveRange *const LR2 ) const ; + + void mergeIGNodesOfLRs(const LiveRange *const LR1, LiveRange *const LR2); + + inline IGNodeListType &getIGNodeList() { return IGNodeList; } + + void setCurDegreeOfIGNodes(); + + void printIG() const; + void printIGNodeList() const; + + ~InterferenceGraph(); + + +}; + + +#endif + diff --git a/lib/CodeGen/RegAlloc/PhyRegAlloc.h b/lib/CodeGen/RegAlloc/PhyRegAlloc.h new file mode 100644 index 00000000000..bcb8aa56eaa --- /dev/null +++ b/lib/CodeGen/RegAlloc/PhyRegAlloc.h @@ -0,0 +1,106 @@ +/* Title: PhyRegAlloc.h + Author: Ruchira Sasanka + Date: Aug 20, 01 + Purpose: This is the main entry point for register allocation. + + Notes: + + * RegisterClasses: Each RegClass accepts a + MachineRegClass which contains machine specific info about that register + class. The code in the RegClass is machine independent and they use + access functions in the MachineRegClass object passed into it to get + machine specific info. + + * Machine dependent work: All parts of the register coloring algorithm + except coloring of an individual node are machine independent. + + Register allocation must be done as: + + static const MachineRegInfo MRI = MachineRegInfo(); // machine reg info + + MethodLiveVarInfo LVI(*MethodI ); // compute LV info + LVI.analyze(); + + PhyRegAlloc PRA(*MethodI, &MRI, &LVI); // allocate regs + PRA.allocateRegisters(); + + Assumptions: + All values in a live range will be of the same physical reg class. + +*/ + + + +#ifndef PHY_REG_ALLOC_H +#define PHY_REG_ALLOC_H + +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/Sparc.h" + +#include "llvm/CodeGen/RegClass.h" +#include "llvm/CodeGen/LiveRangeInfo.h" +#include "llvm/Analysis/LiveVar/MethodLiveVarInfo.h" + + +class AddedInstrns +{ + public: + vector InstrnsBefore; + vector InstrnsAfter; + + AddedInstrns() : InstrnsBefore(), InstrnsAfter() { } +}; + +typedef hash_map AddedInstrMapType; + + + +class PhyRegAlloc +{ + + vector RegClassList ; // vector of register classes + const Method *const Meth; // name of the method we work on + const TargetMachine &TM; // target machine + MethodLiveVarInfo *const LVI; // LV information for this method + // (already computed for BBs) + LiveRangeInfo LRI; // LR info (will be computed) + const MachineRegInfo &MRI; // Machine Register information + const unsigned NumOfRegClasses; // recorded here for efficiency + + vector CallInstrList; // a list of all call instrs + + AddedInstrMapType AddedInstrMap; // to store instrns added in this phase + + + //------- private methods --------------------------------------------------- + + void addInterference(const Value *const Def, const LiveVarSet *const LVSet, + const bool isCallInst); + + void addInterferencesForArgs(); + void createIGNodeListsAndIGs(); + void buildInterferenceGraphs(); + + inline void constructLiveRanges() + { LRI.constructLiveRanges(); } + + void colorIncomingArgs(); + void updateMachineCode(); + + public: + PhyRegAlloc(const Method *const M, const TargetMachine& TM, + MethodLiveVarInfo *const Lvi); + + void allocateRegisters(); // main method called for allocatin + +}; + + + + + + + + +#endif + diff --git a/lib/CodeGen/RegAlloc/RegAllocCommon.h b/lib/CodeGen/RegAlloc/RegAllocCommon.h new file mode 100644 index 00000000000..2e3286a887d --- /dev/null +++ b/lib/CodeGen/RegAlloc/RegAllocCommon.h @@ -0,0 +1,10 @@ +#ifndef REG_ALLOC_COMMON_H +#define REG_ALLOC_COMMON_H + +// set DEBUG_RA for printing out debug messages +// if DEBUG_RA is 1 normal output messages +// if DEBUG_RA is 2 extensive debug info for each instr + +#define DEBUG_RA (1) + +#endif diff --git a/lib/CodeGen/RegAlloc/RegClass.h b/lib/CodeGen/RegAlloc/RegClass.h new file mode 100644 index 00000000000..1d08502445d --- /dev/null +++ b/lib/CodeGen/RegAlloc/RegClass.h @@ -0,0 +1,125 @@ +/* Title: RegClass.h + Author: Ruchira Sasanka + Date: Aug 20, 01 + Purpose: Contains machine independent methods for register coloring. + + This is the class that contains all data structures and common algos + for coloring a particular register class (e.g., int class, fp class). + This class is hardware independent. This class accepts a hardware + dependent description of machine registers (MachineRegInfo class) to + get hardware specific info and color and indidual IG node. + + This class contains the InterferenceGraph (IG). + Also it contains an IGNode stack that can be used for coloring. + The class provides some easy access methods to the IG methods, since these + methods are called thru a register class. + +*/ + + + +#ifndef REG_CLASS_H +#define REG_CLASS_H + +#include "llvm/CodeGen/IGNode.h" +#include "llvm/CodeGen/InterferenceGraph.h" +#include "llvm/CodeGen/TargetMachine.h" + + +#include + + +typedef vector ReservedColorListType; + + +class RegClass +{ + + private: + const Method *const Meth; // Method we are working on + + const MachineRegClassInfo *const MRC; // corresponding MRC + + const unsigned RegClassID; // my int ID + + InterferenceGraph IG; // Interference graph - constructed by + // buildInterferenceGraph + stack IGNodeStack; // the stack used for coloring + + // for passing registered that are pre-allocated (e.g., %g's) + const ReservedColorListType *const ReservedColorList; + + // An array used for coloring each node. This array must be of size + // MRC->getNumOfAllRegs(). Allocated once in the constructor + // for efficiency. + bool *IsColorUsedArr; + + + //------------ private methods ------------------ + + void pushAllIGNodes(); + bool pushUnconstrainedIGNodes(); + IGNode * getIGNodeWithMinSpillCost(); + void colorIGNode(IGNode *const Node); + + public: + + RegClass(const Method *const M, + const MachineRegClassInfo *const MRC, + const ReservedColorListType *const RCL = NULL); + + inline void createInterferenceGraph() + { IG.createGraph(); } + + inline InterferenceGraph &getIG() { return IG; } + + inline const unsigned getID() const { return RegClassID; } + + void colorAllRegs(); // main method called for coloring regs + + inline unsigned getNumOfAvailRegs() const + { return MRC->getNumOfAvailRegs(); } + + ~RegClass() { delete[] IsColorUsedArr; }; + + + + // --- following methods are provided to access the IG contained within this + // ---- RegClass easilly. + + + inline void addLRToIG(LiveRange *const LR) + { IG.addLRToIG(LR); } + + inline void setInterference(const LiveRange *const LR1, + const LiveRange *const LR2) + { IG.setInterference(LR1, LR2); } + + inline unsigned getInterference(const LiveRange *const LR1, + const LiveRange *const LR2) const + { return IG.getInterference(LR1, LR2); } + + inline void mergeIGNodesOfLRs(const LiveRange *const LR1, + LiveRange *const LR2) + { IG.mergeIGNodesOfLRs(LR1, LR2); } + + + inline void printIGNodeList() const { + cout << "IG Nodes for Register Class " << RegClassID << ":" << endl; + IG.printIGNodeList(); + } + + inline void printIG() { + cout << "IG for Register Class " << RegClassID << ":" << endl; + IG.printIG(); + } + +}; + + + + + + + +#endif diff --git a/lib/Target/SparcV9/RegAlloc/InterferenceGraph.h b/lib/Target/SparcV9/RegAlloc/InterferenceGraph.h new file mode 100644 index 00000000000..99dea8fbe0a --- /dev/null +++ b/lib/Target/SparcV9/RegAlloc/InterferenceGraph.h @@ -0,0 +1,76 @@ +/* Title: InterferenceGraph.h + Author: Ruchira Sasanka + Date: July 20, 01 + Purpose: Interference Graph used for register coloring. + + Notes: + Adj Info is stored in the lower trangular matrix (i.e., row > col ) + + This class must be used in the following way: + + * Construct class + * call addLRToIG as many times to add ALL LRs to this IG + * call createGraph to create the actual matrix + * Then setInterference, getInterference, mergeIGNodesOfLRs can be + called as desired to modify the graph. + * Once the modifications to the graph are over, call + setCurDegreeOfIGNodes() before pushing IGNodes on to stack for coloring. +*/ + + +#ifndef INTERFERENCE_GRAPH_H +#define INTERFERENCE_GRAPH_H + + +#include "llvm/CodeGen/IGNode.h" + +typedef vector IGNodeListType; + + +class InterferenceGraph +{ + char **IG; // a poiner to the interference graph + unsigned int Size; // size of a side of the IG + RegClass *const RegCl; // RegCl contains this IG + IGNodeListType IGNodeList; // a list of all IGNodes in a reg class + + // for asserting this IG node is infact in the IGNodeList of this class + inline void assertIGNode(const IGNode *const Node) const { + assert( IGNodeList[ Node->getIndex() ] == Node ); + } + + + + public: + + // the matrix is not yet created by the constructor. Call createGraph() + // to create it after adding all IGNodes to the IGNodeList + + InterferenceGraph(RegClass *const RC); + void createGraph(); + + void addLRToIG(LiveRange *const LR); + + void setInterference(const LiveRange *const LR1, + const LiveRange *const LR2 ); + + unsigned getInterference(const LiveRange *const LR1, + const LiveRange *const LR2 ) const ; + + void mergeIGNodesOfLRs(const LiveRange *const LR1, LiveRange *const LR2); + + inline IGNodeListType &getIGNodeList() { return IGNodeList; } + + void setCurDegreeOfIGNodes(); + + void printIG() const; + void printIGNodeList() const; + + ~InterferenceGraph(); + + +}; + + +#endif + diff --git a/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h b/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h new file mode 100644 index 00000000000..bcb8aa56eaa --- /dev/null +++ b/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h @@ -0,0 +1,106 @@ +/* Title: PhyRegAlloc.h + Author: Ruchira Sasanka + Date: Aug 20, 01 + Purpose: This is the main entry point for register allocation. + + Notes: + + * RegisterClasses: Each RegClass accepts a + MachineRegClass which contains machine specific info about that register + class. The code in the RegClass is machine independent and they use + access functions in the MachineRegClass object passed into it to get + machine specific info. + + * Machine dependent work: All parts of the register coloring algorithm + except coloring of an individual node are machine independent. + + Register allocation must be done as: + + static const MachineRegInfo MRI = MachineRegInfo(); // machine reg info + + MethodLiveVarInfo LVI(*MethodI ); // compute LV info + LVI.analyze(); + + PhyRegAlloc PRA(*MethodI, &MRI, &LVI); // allocate regs + PRA.allocateRegisters(); + + Assumptions: + All values in a live range will be of the same physical reg class. + +*/ + + + +#ifndef PHY_REG_ALLOC_H +#define PHY_REG_ALLOC_H + +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/Sparc.h" + +#include "llvm/CodeGen/RegClass.h" +#include "llvm/CodeGen/LiveRangeInfo.h" +#include "llvm/Analysis/LiveVar/MethodLiveVarInfo.h" + + +class AddedInstrns +{ + public: + vector InstrnsBefore; + vector InstrnsAfter; + + AddedInstrns() : InstrnsBefore(), InstrnsAfter() { } +}; + +typedef hash_map AddedInstrMapType; + + + +class PhyRegAlloc +{ + + vector RegClassList ; // vector of register classes + const Method *const Meth; // name of the method we work on + const TargetMachine &TM; // target machine + MethodLiveVarInfo *const LVI; // LV information for this method + // (already computed for BBs) + LiveRangeInfo LRI; // LR info (will be computed) + const MachineRegInfo &MRI; // Machine Register information + const unsigned NumOfRegClasses; // recorded here for efficiency + + vector CallInstrList; // a list of all call instrs + + AddedInstrMapType AddedInstrMap; // to store instrns added in this phase + + + //------- private methods --------------------------------------------------- + + void addInterference(const Value *const Def, const LiveVarSet *const LVSet, + const bool isCallInst); + + void addInterferencesForArgs(); + void createIGNodeListsAndIGs(); + void buildInterferenceGraphs(); + + inline void constructLiveRanges() + { LRI.constructLiveRanges(); } + + void colorIncomingArgs(); + void updateMachineCode(); + + public: + PhyRegAlloc(const Method *const M, const TargetMachine& TM, + MethodLiveVarInfo *const Lvi); + + void allocateRegisters(); // main method called for allocatin + +}; + + + + + + + + +#endif + diff --git a/lib/Target/SparcV9/RegAlloc/RegAllocCommon.h b/lib/Target/SparcV9/RegAlloc/RegAllocCommon.h new file mode 100644 index 00000000000..2e3286a887d --- /dev/null +++ b/lib/Target/SparcV9/RegAlloc/RegAllocCommon.h @@ -0,0 +1,10 @@ +#ifndef REG_ALLOC_COMMON_H +#define REG_ALLOC_COMMON_H + +// set DEBUG_RA for printing out debug messages +// if DEBUG_RA is 1 normal output messages +// if DEBUG_RA is 2 extensive debug info for each instr + +#define DEBUG_RA (1) + +#endif diff --git a/lib/Target/SparcV9/RegAlloc/RegClass.h b/lib/Target/SparcV9/RegAlloc/RegClass.h new file mode 100644 index 00000000000..1d08502445d --- /dev/null +++ b/lib/Target/SparcV9/RegAlloc/RegClass.h @@ -0,0 +1,125 @@ +/* Title: RegClass.h + Author: Ruchira Sasanka + Date: Aug 20, 01 + Purpose: Contains machine independent methods for register coloring. + + This is the class that contains all data structures and common algos + for coloring a particular register class (e.g., int class, fp class). + This class is hardware independent. This class accepts a hardware + dependent description of machine registers (MachineRegInfo class) to + get hardware specific info and color and indidual IG node. + + This class contains the InterferenceGraph (IG). + Also it contains an IGNode stack that can be used for coloring. + The class provides some easy access methods to the IG methods, since these + methods are called thru a register class. + +*/ + + + +#ifndef REG_CLASS_H +#define REG_CLASS_H + +#include "llvm/CodeGen/IGNode.h" +#include "llvm/CodeGen/InterferenceGraph.h" +#include "llvm/CodeGen/TargetMachine.h" + + +#include + + +typedef vector ReservedColorListType; + + +class RegClass +{ + + private: + const Method *const Meth; // Method we are working on + + const MachineRegClassInfo *const MRC; // corresponding MRC + + const unsigned RegClassID; // my int ID + + InterferenceGraph IG; // Interference graph - constructed by + // buildInterferenceGraph + stack IGNodeStack; // the stack used for coloring + + // for passing registered that are pre-allocated (e.g., %g's) + const ReservedColorListType *const ReservedColorList; + + // An array used for coloring each node. This array must be of size + // MRC->getNumOfAllRegs(). Allocated once in the constructor + // for efficiency. + bool *IsColorUsedArr; + + + //------------ private methods ------------------ + + void pushAllIGNodes(); + bool pushUnconstrainedIGNodes(); + IGNode * getIGNodeWithMinSpillCost(); + void colorIGNode(IGNode *const Node); + + public: + + RegClass(const Method *const M, + const MachineRegClassInfo *const MRC, + const ReservedColorListType *const RCL = NULL); + + inline void createInterferenceGraph() + { IG.createGraph(); } + + inline InterferenceGraph &getIG() { return IG; } + + inline const unsigned getID() const { return RegClassID; } + + void colorAllRegs(); // main method called for coloring regs + + inline unsigned getNumOfAvailRegs() const + { return MRC->getNumOfAvailRegs(); } + + ~RegClass() { delete[] IsColorUsedArr; }; + + + + // --- following methods are provided to access the IG contained within this + // ---- RegClass easilly. + + + inline void addLRToIG(LiveRange *const LR) + { IG.addLRToIG(LR); } + + inline void setInterference(const LiveRange *const LR1, + const LiveRange *const LR2) + { IG.setInterference(LR1, LR2); } + + inline unsigned getInterference(const LiveRange *const LR1, + const LiveRange *const LR2) const + { return IG.getInterference(LR1, LR2); } + + inline void mergeIGNodesOfLRs(const LiveRange *const LR1, + LiveRange *const LR2) + { IG.mergeIGNodesOfLRs(LR1, LR2); } + + + inline void printIGNodeList() const { + cout << "IG Nodes for Register Class " << RegClassID << ":" << endl; + IG.printIGNodeList(); + } + + inline void printIG() { + cout << "IG for Register Class " << RegClassID << ":" << endl; + IG.printIG(); + } + +}; + + + + + + + +#endif