Committed for compliation. Not yet final.
authorRuchira Sasanka <sasanka@students.uiuc.edu>
Sat, 8 Sep 2001 14:22:50 +0000 (14:22 +0000)
committerRuchira Sasanka <sasanka@students.uiuc.edu>
Sat, 8 Sep 2001 14:22:50 +0000 (14:22 +0000)
--Ruchira

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@505 91177308-0d34-0410-b5e6-96231b3b80d8

18 files changed:
include/llvm/CodeGen/InterferenceGraph.h [new file with mode: 0644]
include/llvm/CodeGen/MachineInstr.h
include/llvm/CodeGen/MachineRegInfo.h [new file with mode: 0644]
include/llvm/CodeGen/RegAllocCommon.h [new file with mode: 0644]
include/llvm/CodeGen/RegClass.h [new file with mode: 0644]
include/llvm/CodeGen/RegColorMap.h [new file with mode: 0644]
include/llvm/CodeGen/Sparc.h
include/llvm/CodeGen/SparcRegInfo.h
include/llvm/CodeGen/TargetData.h
include/llvm/CodeGen/TargetMachine.h
lib/CodeGen/RegAlloc/InterferenceGraph.h [new file with mode: 0644]
lib/CodeGen/RegAlloc/PhyRegAlloc.h [new file with mode: 0644]
lib/CodeGen/RegAlloc/RegAllocCommon.h [new file with mode: 0644]
lib/CodeGen/RegAlloc/RegClass.h [new file with mode: 0644]
lib/Target/SparcV9/RegAlloc/InterferenceGraph.h [new file with mode: 0644]
lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h [new file with mode: 0644]
lib/Target/SparcV9/RegAlloc/RegAllocCommon.h [new file with mode: 0644]
lib/Target/SparcV9/RegAlloc/RegClass.h [new file with mode: 0644]

diff --git a/include/llvm/CodeGen/InterferenceGraph.h b/include/llvm/CodeGen/InterferenceGraph.h
new file mode 100644 (file)
index 0000000..99dea8f
--- /dev/null
@@ -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 <IGNode *> 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
+
index fbb3106810dda1d33172aa3e1622fe9271936bef..949c1832d1bfa5bd482947f30924127fe70c6c8a 100644 (file)
@@ -135,6 +135,17 @@ private:
   friend class MachineInstr;
   friend class ValOpIterator<const MachineInstr, const Value>;
   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<const MachineInstr*> {
+class MachineCodeForBasicBlock: public vector<MachineInstr*> {
 public:
-  typedef vector<const MachineInstr*>::iterator iterator;
-  typedef vector<const MachineInstr*>::const_iterator const_iterator;
+  typedef vector<MachineInstr*>::iterator iterator;
+  typedef vector<MachineInstr*>::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 (file)
index 0000000..64fd29e
--- /dev/null
@@ -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<const MachineRegClass *> 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 (file)
index 0000000..2e3286a
--- /dev/null
@@ -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 (file)
index 0000000..1d08502
--- /dev/null
@@ -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 <stack>
+
+
+typedef vector<unsigned int> 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 <IGNode *> 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 (file)
index 0000000..10987a5
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef REG_COLOR_MAP
+#define REG_COLOR_MAP
+
+#include <hash_map>
+
+
+#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 <const Value *, RegColorType, hashFuncValue> 
+{
+
+ public:
+
+  inline void setRegColor(const Value *const Val, RegColorType Col) {
+    (*this)[Val] = Col;
+  }
+
+
+  inline RegColorType getRegColor(const Value *const Val) {
+    return (*this)[Val];
+  }
+    
+
+};
+
+#endif
index 776dc84491e755f048bfbb1a6f74d4b0dc4023f7..8c964fe8117e2445cea511ad0474a16a33e31afc 100644 (file)
@@ -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<const Instruction *> & 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");
+  }
+
 
 };
 
index c97eb9d7e38197c23e7759757e1a7af6e4f6e9e2..41a6d00a0818b567578986c0b21659933038235e 100644 (file)
@@ -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) {
index cf449702b7b6d69957b8eb89fd038bf6a4e81721..c5675a8c431d6b0142048a32bee72867ef8de302 100644 (file)
@@ -14,6 +14,7 @@
 #define LLVM_CODEGEN_TARGETDATA_H
 
 #include "llvm/Type.h"
+#include "llvm/Annotation.h"
 #include <vector>
 
 class StructType;
index 7682ad955ad1b70c12ba62094ee5f894eeefb3ee..c35e51b1ae890bcb06dd3b5efb6cba7a5fc75e63 100644 (file)
@@ -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<const MachineInstr *, AddedInstrns *> AddedInstrMapType;
 
 // A vector of all machine register classes
 typedef vector<const MachineRegClassInfo *> MachineRegClassArrayType;
@@ -715,8 +723,14 @@ public:
                         LiveRangeInfo & LRI) const = 0;
 
   virtual void colorCallArgs(vector<const Instruction *> & 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 (file)
index 0000000..99dea8f
--- /dev/null
@@ -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 <IGNode *> 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 (file)
index 0000000..bcb8aa5
--- /dev/null
@@ -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<const MachineInstr *> InstrnsBefore;
+  vector<const MachineInstr *> InstrnsAfter;
+
+  AddedInstrns() : InstrnsBefore(), InstrnsAfter() { }
+};
+
+typedef hash_map<const MachineInstr *, AddedInstrns *> AddedInstrMapType;
+
+
+
+class PhyRegAlloc
+{
+
+  vector<RegClass *> 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<const Instruction *> 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 (file)
index 0000000..2e3286a
--- /dev/null
@@ -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 (file)
index 0000000..1d08502
--- /dev/null
@@ -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 <stack>
+
+
+typedef vector<unsigned int> 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 <IGNode *> 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 (file)
index 0000000..99dea8f
--- /dev/null
@@ -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 <IGNode *> 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 (file)
index 0000000..bcb8aa5
--- /dev/null
@@ -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<const MachineInstr *> InstrnsBefore;
+  vector<const MachineInstr *> InstrnsAfter;
+
+  AddedInstrns() : InstrnsBefore(), InstrnsAfter() { }
+};
+
+typedef hash_map<const MachineInstr *, AddedInstrns *> AddedInstrMapType;
+
+
+
+class PhyRegAlloc
+{
+
+  vector<RegClass *> 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<const Instruction *> 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 (file)
index 0000000..2e3286a
--- /dev/null
@@ -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 (file)
index 0000000..1d08502
--- /dev/null
@@ -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 <stack>
+
+
+typedef vector<unsigned int> 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 <IGNode *> 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