*** empty log message ***
authorRuchira Sasanka <sasanka@students.uiuc.edu>
Fri, 31 Aug 2001 20:59:58 +0000 (20:59 +0000)
committerRuchira Sasanka <sasanka@students.uiuc.edu>
Fri, 31 Aug 2001 20:59:58 +0000 (20:59 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@412 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/RegAlloc/IGNode.h [new file with mode: 0644]
lib/CodeGen/TargetMachine/Sparc/Sparc.cpp
lib/CodeGen/TargetMachine/Sparc/SparcRegInfo.cpp [new file with mode: 0644]
lib/Target/SparcV9/RegAlloc/IGNode.h [new file with mode: 0644]

diff --git a/lib/CodeGen/RegAlloc/IGNode.h b/lib/CodeGen/RegAlloc/IGNode.h
new file mode 100644 (file)
index 0000000..03bcfc0
--- /dev/null
@@ -0,0 +1,152 @@
+/* Title:   IGNode.h
+   Author:  Ruchira Sasanka
+   Date:    July 25, 01
+   Purpose: Represents a node in an interference graph. 
+   Notes:
+
+   For efficiency, the AdjList is updated only once - ie. we can add but not
+   remove nodes from AdjList. 
+
+   The removal of nodes from IG is simulated by decrementing the CurDegree.
+   If this node is put on stack (that is removed from IG), the CurDegree of all
+   the neighbors are decremented and this node is marked OnSack. Hence
+   the effective neighbors in the AdjList are the ones that do not have the
+   OnStack flag set (therefore, they are in the IG).
+
+   The methods that modify/use the CurDegree Must be called only
+   fter all modifications to the IG are over (i.e., all neighbors are fixed).
+
+   The vector representation the most efficient one for adj list.
+   Though nodes are removed when coalsing is done, we access it in sequence
+   for far many times when coloring (colorNode()).
+
+*/
+
+#ifndef IG_NODE_H
+#define IG_NODE_H
+
+
+#include "llvm/CodeGen/RegAllocCommon.h"
+#include "llvm/CodeGen/LiveRange.h"
+
+class IGNode
+{
+ private:
+
+  const int Index;            // index within IGNodeList 
+
+  bool OnStack;               // this has been pushed on to stack for coloring
+
+  vector<IGNode *> AdjList;   // adjacency list for this live range
+
+
+  // set by InterferenceGraph::setCurDegreeOfIGNodes() after calculating
+  // all adjacency lists.
+  // Decremented when a neighbor is pushed on to the stack. 
+  // After that, never incremented/set again nor used.
+  int CurDegree;     
+
+  LiveRange *const ParentLR;            // parent LR (cannot be a const)
+
+
+ public:
+
+  inline unsigned int getIndex() const 
+    { return Index; }
+
+  // adjLists must be updated only once.  However, the CurDegree can be changed
+  inline void addAdjIGNode( IGNode *const AdjNode) 
+    { AdjList.push_back(AdjNode);  } 
+
+  inline IGNode * getAdjIGNode(unsigned int ind) const 
+    { assert ( ind < AdjList.size()); return AdjList[ ind ]; }
+
+  // delete a node in AdjList - node must be in the list
+  // should not be called often
+  void delAdjIGNode(const IGNode *const Node); 
+
+  inline unsigned int getNumOfNeighbors() const 
+    { return AdjList.size() ; }
+
+
+  inline bool isOnStack() const 
+    { return OnStack; }
+
+  // remove form IG and pushes on to stack (reduce the degree of neighbors)
+  void pushOnStack(); 
+
+  // CurDegree is the effective number of neighbors when neighbors are
+  // pushed on to the stack during the coloring phase. Must be called
+  // after all modifications to the IG are over (i.e., all neighbors are
+  // fixed).
+
+  inline void setCurDegree() 
+    { assert( CurDegree == -1);   CurDegree = AdjList.size(); }
+
+  inline int getCurDegree() const 
+    { return CurDegree; }
+
+  // called when a neigh is pushed on to stack
+  inline void decCurDegree() 
+    { assert( CurDegree > 0 ); --CurDegree; }
+
+
+  // The following methods call the methods in ParentLR
+  // They are added to this class for convenience
+  // If many of these are called within a single scope,
+  // consider calling the methods directly on LR
+
+
+  inline void setRegClass(RegClass *const RC) 
+    { ParentLR->setRegClass(RC);  }
+
+  inline RegClass *const getRegClass() const 
+    { return ParentLR->getRegClass(); } 
+
+  inline bool hasColor() const 
+    { return ParentLR->hasColor();  }
+
+  inline unsigned int getColor() const 
+    { return ParentLR->getColor();  }
+
+  inline void setColor(unsigned int Col) 
+    { ParentLR->setColor(Col);  }
+
+  inline void markForSpill() 
+    { ParentLR->markForSpill();  }
+
+  inline void markForSaveAcrossCalls() 
+    { ParentLR->markForSaveAcrossCalls();  }
+
+  // inline void markForLoadFromStack() 
+  //  { ParentLR->markForLoadFromStack();  }
+
+
+  inline unsigned int getNumOfCallInterferences() const 
+    { return ParentLR->getNumOfCallInterferences(); } 
+
+  inline LiveRange *getParentLR() const 
+    { return ParentLR; }
+
+  inline Type::PrimitiveID getTypeID() const 
+    { return ParentLR->getTypeID(); }
+
+
+
+  //---- constructor and destructor ----
+
+
+  IGNode(LiveRange *const LR, unsigned int index);
+
+  ~IGNode() { }                         // an empty destructor
+
+
+};
+
+
+
+
+
+
+
+#endif
index f66d10e74948330f5b66d9f11271eaae3d18dc61..372b7e0dca92d1c4ad726dae24d3929418eb19f1 100644 (file)
 //     7/15/01  -  Vikram Adve  -  Created
 //**************************************************************************/
 
+#include "llvm/Method.h"
+#include "llvm/Instruction.h"
+
+#include "llvm/CodeGen/LiveRange.h"
+#include "llvm/CodeGen/LiveRangeInfo.h"
 #include "llvm/CodeGen/Sparc.h"
+#include "llvm/CodeGen/SparcRegInfo.h"
 
 //************************ Class Implementations **************************/
 
 
+
+
+
+//---------------------------------------------------------------------------
+// UltraSparcRegInfo
+// Purpose:
+//   This method will color incoming args to a method. If there are more
+//   args than that can fit in regs, code will be inserted to pop them from
+//   stack
+//---------------------------------------------------------------------------
+
+
+void UltraSparcRegInfo::colorArgs(const Method *const Meth, 
+                                 LiveRangeInfo& LRI) const 
+{
+
+                                                 // get the argument list
+  const Method::ArgumentListType& ArgList = Meth->getArgumentList();           
+                                                 // get an iterator to arg list
+  Method::ArgumentListType::const_iterator ArgIt = ArgList.begin(); 
+  unsigned intArgNo=0;
+
+  // to keep track of which float regs are allocated for argument passing
+  bool FloatArgUsedArr[NumOfFloatArgRegs];
+
+  // init float arg used array
+  for(unsigned i=0; i < NumOfFloatArgRegs; ++i) 
+    FloatArgUsedArr[i] = false;
+
+  // for each argument
+  for( ; ArgIt != ArgList.end() ; ++ArgIt) {    
+
+    // get the LR of arg
+    LiveRange *const LR = LRI.getLiveRangeForValue((const Value *) *ArgIt); 
+    unsigned RegClassID = (LR->getRegClass())->getID();
+
+    // if the arg is in int class - allocate a reg for an int arg
+    if( RegClassID == IntRegClassID ) {
+
+      if( intArgNo < NumOfIntArgRegs) {
+       LR->setColor( SparcIntRegOrder::i0 + intArgNo );
+
+       if( DEBUG_RA) printReg( LR );
+      }
+  
+      else {
+       // TODO: Insert push code here
+       assert( 0 && "Insert push code here!");
+      }
+      ++intArgNo;
+    }
+
+    // if the arg is float/double 
+    else if ( RegClassID == FloatRegClassID) {
+
+      if( LR->getTypeID() == Type::DoubleTyID ) {
+
+       // find the first reg # we can pass a double arg
+       for(unsigned i=0; i < NumOfFloatArgRegs; i+= 2) {
+         if ( !FloatArgUsedArr[i] && !FloatArgUsedArr[i+1] ) {
+           LR->setColor( SparcFloatRegOrder::f0 + i );
+           FloatArgUsedArr[i] = true;
+           FloatArgUsedArr[i+1] = true;
+           if( DEBUG_RA) printReg( LR );
+           break;
+         }
+       }
+       if( ! LR->hasColor() ) { // if LR was not colored above
+
+         assert(0 && "insert push code here for a double");
+
+       }
+
+      }
+      else if( LR->getTypeID() == Type::FloatTyID ) { 
+
+       // find the first reg # we can pass a float arg
+       for(unsigned i=0; i < NumOfFloatArgRegs; ++i) {
+         if ( !FloatArgUsedArr[i] ) {
+           LR->setColor( SparcFloatRegOrder::f0 + i );
+           FloatArgUsedArr[i] = true;
+           if( DEBUG_RA) printReg( LR );
+           break;
+         }
+       }
+       if( ! LR->hasColor() ) { // if LR was not colored above
+         assert(0 && "insert push code here for a float");
+       }
+
+      }
+      else 
+       assert(0 && "unknown float type in method arg");
+
+    } // float register class
+
+    else 
+      assert(0 && "Unknown RegClassID");
+  }
+  
+}
+
+
+
+
+
+
+void UltraSparcRegInfo::printReg(const LiveRange *const LR) {
+
+  unsigned RegClassID = (LR->getRegClass())->getID();
+
+  cout << " *Node " << (LR->getUserIGNode())->getIndex();
+
+  if( ! LR->hasColor() ) {
+    cout << " - could not find a color" << endl;
+    return;
+  }
+  
+  // if a color is found
+
+  cout << " colored with color "<< LR->getColor();
+
+  if( RegClassID == IntRegClassID ) {
+
+    cout<< " [" << SparcIntRegOrder::getRegName(LR->getColor()) ;
+    cout << "]" << endl;
+  }
+  else if ( RegClassID == FloatRegClassID) {
+    cout << "[" << SparcFloatRegOrder::getRegName(LR->getColor());
+    if( LR->getTypeID() == Type::DoubleTyID )
+      cout << "+" << SparcFloatRegOrder::getRegName(LR->getColor()+1);
+    cout << "]" << endl;
+  }
+
+
+}
+
+
+
+
+
+void UltraSparcRegInfo::colorCallArgs(vector<const Instruction *> & 
+                                     CallInstrList, LiveRangeInfo& LRI ) const
+{
+
+  vector<const Instruction *>::const_iterator InstIt = CallInstrList.begin();
+
+  for( ; InstIt != CallInstrList.end(); ++InstIt) {
+
+    // Inst = LLVM call instruction
+    const Instruction *const CallI = *InstIt;
+
+    MachineCodeForVMInstr &  MInstVec = CallI->getMachineInstrVec();
+    MachineCodeForVMInstr::const_iterator MIIt = MInstVec.begin();
+
+    // find the CALL/JMMPL machine instruction
+    for( ; MIIt != MInstVec.end() && 
+          ! getUltraSparcInfo().getInstrInfo().isCall((*MIIt)->getOpCode()); 
+        ++MIIt );
+
+    assert( (MIIt != MInstVec.end())  && "CALL/JMPL not found");
+
+    // CallMI = CALL/JMPL machine isntruction
+    const MachineInstr *const CallMI = *MIIt;
+
+    Instruction::op_const_iterator OpIt = CallI->op_begin();
+
+    unsigned intArgNo=0;
+    //unsigned NumOfCallInterfs = LR->getNumOfCallInterferences();
+
+    // to keep track of which float regs are allocated for argument passing
+    bool FloatArgUsedArr[NumOfFloatArgRegs];
+
+    // init float arg used array
+    for(unsigned i=0; i < NumOfFloatArgRegs; ++i) 
+      FloatArgUsedArr[i] = false;
+
+    // go thru all the operands of LLVM instruction
+    for( ; OpIt != CallI->op_end(); ++OpIt ) {
+
+      // get the LR of call operand (parameter)
+      LiveRange *const LR = LRI.getLiveRangeForValue((const Value *) *OpIt); 
+
+      if ( !LR ) {
+       cout << " Warning: In call instr, no LR for arg: " ;
+       printValue(*OpIt);
+       cout << endl;
+       continue;
+      }
+
+      unsigned RegClassID = (LR->getRegClass())->getID();
+      
+      // if the arg is in int class - allocate a reg for an int arg
+      if( RegClassID == IntRegClassID ) {
+       
+       if( intArgNo < NumOfIntArgRegs) {
+         setCallArgColor( LR, SparcIntRegOrder::o0 + intArgNo );
+       }
+       
+       else {
+         // TODO: Insert push code here
+         assert( 0 && "Insert push code here!");
+       }
+       ++intArgNo;
+      }
+      
+      // if the arg is float/double 
+      else if ( RegClassID == FloatRegClassID) {
+       
+       if( LR->getTypeID() == Type::DoubleTyID ) {
+         
+         // find the first reg # we can pass a double arg
+         for(unsigned i=0; i < NumOfFloatArgRegs; i+= 2) {
+           if ( !FloatArgUsedArr[i] && !FloatArgUsedArr[i+1] ) {
+             setCallArgColor(LR, SparcFloatRegOrder::f0 + i );             
+             FloatArgUsedArr[i] = true;
+             FloatArgUsedArr[i+1] = true;
+             //if( DEBUG_RA) printReg( LR );
+             break;
+           }
+         }
+         if( ! LR->hasColor() ) { // if LR was not colored above
+           
+           assert(0 && "insert push code here for a double");
+           
+         }
+         
+       }
+       else if( LR->getTypeID() == Type::FloatTyID ) { 
+         
+         // find the first reg # we can pass a float arg
+         for(unsigned i=0; i < NumOfFloatArgRegs; ++i) {
+           if ( !FloatArgUsedArr[i] ) {
+             setCallArgColor(LR, SparcFloatRegOrder::f0 + i );
+             FloatArgUsedArr[i] = true;
+             // LR->setColor( SparcFloatRegOrder::f0 + i );
+             // if( DEBUG_RA) printReg( LR );
+             break;
+           }
+         }
+         if( ! LR->hasColor() ) { // if LR was not colored above
+           assert(0 && "insert push code here for a float");
+         }
+         
+       }
+       else 
+         assert(0 && "unknown float type in method arg");
+       
+      } // float register class
+      
+      else 
+       assert(0 && "Unknown RegClassID");
+
+
+    } // for each operand in a call instruction
+
+    
+
+
+  } // for all call instrctions in CallInstrList
+
+}
+
+
+void UltraSparcRegInfo::setCallArgColor(LiveRange *const LR, 
+                                       const unsigned RegNo) const {
+
+  // if no call interference and LR is NOT previously colored (e.g., as an 
+  // incoming arg)
+  if( ! LR->getNumOfCallInterferences() && ! LR->hasColor() ) { 
+    // we can directly allocate a %o register
+    LR->setColor( RegNo);
+    if( DEBUG_RA) printReg( LR );
+  }
+  else {                        // there are call interferences
+    
+    /* 
+    // insert a copy machine instr to copy from LR to %o(reg)
+    PreMInstrMap[ CallMI ] = 
+    getNewCopyMInstr( LR->,  SparcIntRegOrder::o0 + intArgNo );
+    */
+    cout << " $$$ TODO: Insert a copy for call argument!: " << endl;
+
+    // We don't color LR here. It's colored as any other normal LR
+  }
+
+}
+
+   
+
+
 //---------------------------------------------------------------------------
 // class UltraSparcInstrInfo 
 // 
@@ -79,6 +375,11 @@ UltraSparcSchedInfo::initializeResources()
 }
 
 
+
+
+
+
+
 //---------------------------------------------------------------------------
 // class UltraSparcMachine 
 // 
@@ -91,10 +392,12 @@ UltraSparcSchedInfo::initializeResources()
 //---------------------------------------------------------------------------
 
 UltraSparc::UltraSparc()
+
   : TargetMachine("UltraSparc-Native")
 {
   machineInstrInfo = new UltraSparcInstrInfo;
   machineSchedInfo = new UltraSparcSchedInfo(machineInstrInfo); 
+  machineRegInfo = new UltraSparcRegInfo(this);
   
   optSizeForSubWordData = 4;
   minMemOpWordSize = 8; 
@@ -105,6 +408,7 @@ UltraSparc::UltraSparc()
 UltraSparc::~UltraSparc()
 {
   delete (UltraSparcInstrInfo*) machineInstrInfo;
+  delete (UltraSparcRegInfo*) machineRegInfo;
   delete (UltraSparcSchedInfo*) machineSchedInfo;
 }
 
diff --git a/lib/CodeGen/TargetMachine/Sparc/SparcRegInfo.cpp b/lib/CodeGen/TargetMachine/Sparc/SparcRegInfo.cpp
new file mode 100644 (file)
index 0000000..2cda2d7
--- /dev/null
@@ -0,0 +1,302 @@
+#include "llvm/CodeGen/IGNode.h"
+#include "llvm/CodeGen/SparcRegInfo.h"
+
+#include "llvm/CodeGen/Sparc.h"
+
+//-----------------------------------------------------------------------------
+// Int Register Class
+//-----------------------------------------------------------------------------
+
+void SparcIntRegClass::colorIGNode(IGNode * Node, bool IsColorUsedArr[]) const 
+{
+
+  /* Algorithm:
+  Record the color of all neighbors.
+
+  If there is no call interf, try to allocate volatile, then non volatile
+  If there is call interf, try to allocate non-volatile. If that fails
+     try to allocate a volatile and insert save across calls
+  If both above fail, spill.
+
+  */
+
+  unsigned NumNeighbors =  Node->getNumOfNeighbors();   // total # of neighbors
+
+  for(unsigned n=0; n < NumNeighbors; n++) {            // for each neigh 
+    IGNode *NeighIGNode = Node->getAdjIGNode(n);
+    if( NeighIGNode->hasColor() ) {                     // if neigh has a color
+      IsColorUsedArr[ NeighIGNode->getColor() ] = true; // record that color
+    }
+  }
+
+
+
+  unsigned SearchStart;                 // start pos of color in pref-order
+  bool ColorFound= false;               // have we found a color yet?
+
+  //if this Node is between calls
+  if( Node->getNumOfCallInterferences() == 0) { 
+
+    // start with volatiles (we can  allocate volatiles safely)
+    SearchStart = SparcIntRegOrder::StartOfAllRegs;  
+  }
+  else {           
+    // start with non volatiles (no non-volatiles)
+    SearchStart =  SparcIntRegOrder::StartOfNonVolatileRegs;  
+  }
+
+  unsigned c=0;                         // color
+  // find first unused color
+  for( c=SearchStart; c < SparcIntRegOrder::NumOfAvailRegs; c++) { 
+    if( ! IsColorUsedArr[ c ] ) { ColorFound = true; break; }
+  }
+
+  if( ColorFound) 
+    Node->setColor(c);                  // first color found in preffered order
+
+  // if color is not found because of call interference
+  // try even finding a volatile color and insert save across calls
+  else if( Node->getNumOfCallInterferences() ) 
+  { 
+    // start from 0 - try to find even a volatile this time
+    SearchStart = SparcIntRegOrder::StartOfAllRegs;  
+
+    // find first unused volatile color
+    for(c=SearchStart; c < SparcIntRegOrder::StartOfNonVolatileRegs; c++) { 
+      if( ! IsColorUsedArr[ c ] ) { ColorFound = true; break; }
+    }
+
+    if( ColorFound) { 
+      Node->setColor(c);  
+      // since LR span across calls, must save across calls 
+      Node->markForSaveAcrossCalls();       
+    }
+
+  }
+
+  // If we couldn't find a color regardless of call interference - i.e., we
+  // don't have either a volatile or non-volatile color left
+  if( !ColorFound )  
+    Node->markForSpill();               // no color found - must spill
+
+
+  if( DEBUG_RA)                  
+    UltraSparcRegInfo::printReg( Node->getParentLR() );
+
+}
+
+
+
+
+
+
+//-----------------------------------------------------------------------------
+// Float Register Class
+//-----------------------------------------------------------------------------
+
+// find the first available color in the range [Start,End] depending on the
+// type of the Node (i.e., float/double)
+
+int SparcFloatRegClass::findFloatColor(const IGNode *const Node, unsigned Start,
+                                      unsigned End, 
+                                      bool IsColorUsedArr[] ) const
+{
+
+  bool ColorFound = false;
+  unsigned c;
+
+  if( Node->getTypeID() == Type::DoubleTyID ) { 
+      
+    // find first unused color for a double 
+    for( c=Start; c < End ;c+= 2){
+      if( ! IsColorUsedArr[ c ] &&  ! IsColorUsedArr[ c+1 ]) 
+       { ColorFound=true;  break; }
+    }
+    
+  } else {
+    
+    // find first unused color for a single
+    for( c=Start; c < End; c++) { 
+      if( ! IsColorUsedArr[ c ] ) { ColorFound=true;  break; }
+    }
+  }
+  
+  if( ColorFound ) return c;
+  else return -1;
+}
+
+
+
+
+
+void SparcFloatRegClass::colorIGNode(IGNode * Node,bool IsColorUsedArr[]) const
+{
+
+  /* Algorithm:
+
+     If the LR is a double try to allocate f32 - f63
+     If the above fails or LR is single precision
+        If the LR does not interfere with a call
+          start allocating from f0
+       Else start allocating from f6
+     If a color is still not found because LR interferes with a call
+        Search in f0 - f6. If found mark for spill across calls.
+     If a color is still not fond, mark for spilling
+  */
+
+
+  unsigned NumNeighbors =  Node->getNumOfNeighbors();   // total # of neighbors
+
+  for(unsigned n=0; n < NumNeighbors; n++) {            // for each neigh 
+    IGNode *NeighIGNode = Node->getAdjIGNode(n);
+    if( NeighIGNode->hasColor() ) {                     // if neigh has a color
+      IsColorUsedArr[ NeighIGNode->getColor() ] = true; // record that color
+      if( NeighIGNode->getTypeID() == Type::DoubleTyID )
+       IsColorUsedArr[ (NeighIGNode->getColor()) + 1 ] = true;  
+    }
+  }
+
+  int ColorFound = -1;               // have we found a color yet?
+  unsigned NumOfCallInterf = Node->getNumOfCallInterferences();
+
+  // if value is a double - search the double only reigon (f32 - f63)
+  if( Node->getTypeID() == Type::DoubleTyID )       
+    ColorFound = findFloatColor( Node, 32, 64, IsColorUsedArr );
+    
+
+  if( ColorFound >= 0 ) {
+    Node->setColor(ColorFound);                
+    if( DEBUG_RA) UltraSparcRegInfo::printReg( Node->getParentLR() );
+    return;
+  }
+
+  else { // the above fails or LR is single precision
+
+    unsigned SearchStart;                 // start pos of color in pref-order
+
+    //if this Node is between calls (i.e., no call interferences )
+    if( ! NumOfCallInterf ) {
+      // start with volatiles (we can  allocate volatiles safely)
+      SearchStart = SparcFloatRegOrder::StartOfAllRegs;  
+    }
+    else {           
+      // start with non volatiles (no non-volatiles)
+      SearchStart =  SparcFloatRegOrder::StartOfNonVolatileRegs;  
+    }
+    
+    ColorFound = findFloatColor( Node, SearchStart, 32, IsColorUsedArr );
+
+  }
+
+  if( ColorFound >= 0 ) {
+    Node->setColor(ColorFound);                  
+    if( DEBUG_RA) UltraSparcRegInfo::printReg( Node->getParentLR() );
+    return;
+  }
+
+  else if( NumOfCallInterf ) { 
+
+    // We are here because there is a call interference and no non-volatile
+    // color could be found.
+    // Now try to allocate even a volatile color
+
+    ColorFound = findFloatColor( Node, SparcFloatRegOrder::StartOfAllRegs, 
+                               SparcFloatRegOrder::StartOfNonVolatileRegs,
+                               IsColorUsedArr);
+  }
+
+  if( ColorFound >= 0 ) {
+    Node->setColor(ColorFound);         // first color found in preffered order
+    Node->markForSaveAcrossCalls();  
+    if( DEBUG_RA) UltraSparcRegInfo::printReg( Node->getParentLR() );
+    return;
+  }
+
+  else {
+    Node->markForSpill();               // no color found - must spill
+    if( DEBUG_RA) UltraSparcRegInfo::printReg( Node->getParentLR() );
+  }
+  
+
+}
+
+
+
+
+
+
+#if 0
+
+//-----------------------------------------------------------------------------
+// Float Register Class
+//-----------------------------------------------------------------------------
+
+void SparcFloatRegClass::colorIGNode(IGNode * Node,bool IsColorUsedArr[]) const
+{
+
+  /* Algorithm:
+  Record the color of all neighbors.
+
+  Single precision can use f0 - f31
+  Double precision can use f0 - f63
+
+  if LR is a double, try to allocate f32 - f63.
+  if the above attempt fails, or Value is single presion, try to allcoate 
+    f0 - f31.
+
+      */
+
+  unsigned NumNeighbors =  Node->getNumOfNeighbors();   // total # of neighbors
+
+  for(unsigned n=0; n < NumNeighbors; n++) {            // for each neigh 
+    IGNode *NeighIGNode = Node->getAdjIGNode(n);
+    if( NeighIGNode->hasColor() ) {                     // if neigh has a color
+      IsColorUsedArr[ NeighIGNode->getColor() ] = true; // record that color
+      if( NeighIGNode->getTypeID() == Type::DoubleTyID )
+       IsColorUsedArr[ (NeighIGNode->getColor()) + 1 ] = true;  
+    }
+  }
+
+
+  unsigned SearchStart;                 // start pos of color in pref-order
+  bool ColorFound= false;               // have we found a color yet?
+  unsigned c;    
+
+
+  if( Node->getTypeID() == Type::DoubleTyID ) {        // if value is a double
+
+    // search the double only reigon (f32 - f63)
+     for( c=32; c < 64; c+= 2) { 
+      if( ! IsColorUsedArr[ c ] ) { ColorFound = true; break; }
+    }
+
+     // search f0 - f31 region
+    if( ! ColorFound )  {                // if color not found
+     for( c=0; c < 32; c+= 2) { 
+      if( ! IsColorUsedArr[ c ] ) { ColorFound = true; break; }
+     }
+    }
+
+  }
+
+  else {  // value is Single
+
+    for( c=0; c < 32; c++) { 
+      if( ! IsColorUsedArr[ c ] ) { ColorFound = true; break; }
+    }
+  }
+  
+
+  if( ColorFound) 
+    Node->setColor(c);                  // first color found in preferred order
+  else
+    Node->markForSpill();               // no color found - must spill
+
+
+  if( DEBUG_RA)                  
+    UltraSparcRegInfo::printReg( Node->getParentLR() );
+
+}
+
+#endif
diff --git a/lib/Target/SparcV9/RegAlloc/IGNode.h b/lib/Target/SparcV9/RegAlloc/IGNode.h
new file mode 100644 (file)
index 0000000..03bcfc0
--- /dev/null
@@ -0,0 +1,152 @@
+/* Title:   IGNode.h
+   Author:  Ruchira Sasanka
+   Date:    July 25, 01
+   Purpose: Represents a node in an interference graph. 
+   Notes:
+
+   For efficiency, the AdjList is updated only once - ie. we can add but not
+   remove nodes from AdjList. 
+
+   The removal of nodes from IG is simulated by decrementing the CurDegree.
+   If this node is put on stack (that is removed from IG), the CurDegree of all
+   the neighbors are decremented and this node is marked OnSack. Hence
+   the effective neighbors in the AdjList are the ones that do not have the
+   OnStack flag set (therefore, they are in the IG).
+
+   The methods that modify/use the CurDegree Must be called only
+   fter all modifications to the IG are over (i.e., all neighbors are fixed).
+
+   The vector representation the most efficient one for adj list.
+   Though nodes are removed when coalsing is done, we access it in sequence
+   for far many times when coloring (colorNode()).
+
+*/
+
+#ifndef IG_NODE_H
+#define IG_NODE_H
+
+
+#include "llvm/CodeGen/RegAllocCommon.h"
+#include "llvm/CodeGen/LiveRange.h"
+
+class IGNode
+{
+ private:
+
+  const int Index;            // index within IGNodeList 
+
+  bool OnStack;               // this has been pushed on to stack for coloring
+
+  vector<IGNode *> AdjList;   // adjacency list for this live range
+
+
+  // set by InterferenceGraph::setCurDegreeOfIGNodes() after calculating
+  // all adjacency lists.
+  // Decremented when a neighbor is pushed on to the stack. 
+  // After that, never incremented/set again nor used.
+  int CurDegree;     
+
+  LiveRange *const ParentLR;            // parent LR (cannot be a const)
+
+
+ public:
+
+  inline unsigned int getIndex() const 
+    { return Index; }
+
+  // adjLists must be updated only once.  However, the CurDegree can be changed
+  inline void addAdjIGNode( IGNode *const AdjNode) 
+    { AdjList.push_back(AdjNode);  } 
+
+  inline IGNode * getAdjIGNode(unsigned int ind) const 
+    { assert ( ind < AdjList.size()); return AdjList[ ind ]; }
+
+  // delete a node in AdjList - node must be in the list
+  // should not be called often
+  void delAdjIGNode(const IGNode *const Node); 
+
+  inline unsigned int getNumOfNeighbors() const 
+    { return AdjList.size() ; }
+
+
+  inline bool isOnStack() const 
+    { return OnStack; }
+
+  // remove form IG and pushes on to stack (reduce the degree of neighbors)
+  void pushOnStack(); 
+
+  // CurDegree is the effective number of neighbors when neighbors are
+  // pushed on to the stack during the coloring phase. Must be called
+  // after all modifications to the IG are over (i.e., all neighbors are
+  // fixed).
+
+  inline void setCurDegree() 
+    { assert( CurDegree == -1);   CurDegree = AdjList.size(); }
+
+  inline int getCurDegree() const 
+    { return CurDegree; }
+
+  // called when a neigh is pushed on to stack
+  inline void decCurDegree() 
+    { assert( CurDegree > 0 ); --CurDegree; }
+
+
+  // The following methods call the methods in ParentLR
+  // They are added to this class for convenience
+  // If many of these are called within a single scope,
+  // consider calling the methods directly on LR
+
+
+  inline void setRegClass(RegClass *const RC) 
+    { ParentLR->setRegClass(RC);  }
+
+  inline RegClass *const getRegClass() const 
+    { return ParentLR->getRegClass(); } 
+
+  inline bool hasColor() const 
+    { return ParentLR->hasColor();  }
+
+  inline unsigned int getColor() const 
+    { return ParentLR->getColor();  }
+
+  inline void setColor(unsigned int Col) 
+    { ParentLR->setColor(Col);  }
+
+  inline void markForSpill() 
+    { ParentLR->markForSpill();  }
+
+  inline void markForSaveAcrossCalls() 
+    { ParentLR->markForSaveAcrossCalls();  }
+
+  // inline void markForLoadFromStack() 
+  //  { ParentLR->markForLoadFromStack();  }
+
+
+  inline unsigned int getNumOfCallInterferences() const 
+    { return ParentLR->getNumOfCallInterferences(); } 
+
+  inline LiveRange *getParentLR() const 
+    { return ParentLR; }
+
+  inline Type::PrimitiveID getTypeID() const 
+    { return ParentLR->getTypeID(); }
+
+
+
+  //---- constructor and destructor ----
+
+
+  IGNode(LiveRange *const LR, unsigned int index);
+
+  ~IGNode() { }                         // an empty destructor
+
+
+};
+
+
+
+
+
+
+
+#endif