*** empty log message ***
authorRuchira Sasanka <sasanka@students.uiuc.edu>
Fri, 14 Sep 2001 21:18:34 +0000 (21:18 +0000)
committerRuchira Sasanka <sasanka@students.uiuc.edu>
Fri, 14 Sep 2001 21:18:34 +0000 (21:18 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@580 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/RegAlloc/IGNode.cpp [new file with mode: 0644]
lib/CodeGen/RegAlloc/InterferenceGraph.cpp [new file with mode: 0644]
lib/CodeGen/RegAlloc/LiveRangeInfo.cpp [new file with mode: 0644]
lib/CodeGen/RegAlloc/PhyRegAloc.cpp [new file with mode: 0644]
lib/CodeGen/RegAlloc/RegClass.cpp [new file with mode: 0644]
lib/Target/SparcV9/RegAlloc/IGNode.cpp [new file with mode: 0644]
lib/Target/SparcV9/RegAlloc/InterferenceGraph.cpp [new file with mode: 0644]
lib/Target/SparcV9/RegAlloc/LiveRangeInfo.cpp [new file with mode: 0644]
lib/Target/SparcV9/RegAlloc/PhyRegAloc.cpp [new file with mode: 0644]
lib/Target/SparcV9/RegAlloc/RegClass.cpp [new file with mode: 0644]

diff --git a/lib/CodeGen/RegAlloc/IGNode.cpp b/lib/CodeGen/RegAlloc/IGNode.cpp
new file mode 100644 (file)
index 0000000..0e8a124
--- /dev/null
@@ -0,0 +1,31 @@
+#include "llvm/CodeGen/IGNode.h"
+
+
+IGNode::IGNode(LiveRange *const PLR, unsigned int Ind): Index(Ind),
+                                                        ParentLR(PLR)
+{
+  OnStack = false;
+  CurDegree = -1 ;
+  ParentLR->setUserIGNode( this );
+}
+
+
+
+void IGNode::pushOnStack()            // sets on to stack and 
+{                                     // reduce the degree of neighbors  
+  OnStack = true; 
+  unsigned int neighs = AdjList.size();
+
+  for(unsigned int i=0; i < neighs; i++)  (AdjList[i])->decCurDegree();
+}
+
+void IGNode::delAdjIGNode(const IGNode *const Node) {
+  vector <IGNode *>::iterator It = AdjList.begin();
+    
+  // find Node
+  for( ; It != AdjList.end() && (*It != Node); It++ ) ;
+  assert( It != AdjList.end() );      // the node must be there
+  
+  AdjList.erase( It );
+}
diff --git a/lib/CodeGen/RegAlloc/InterferenceGraph.cpp b/lib/CodeGen/RegAlloc/InterferenceGraph.cpp
new file mode 100644 (file)
index 0000000..d8ec247
--- /dev/null
@@ -0,0 +1,226 @@
+#include "llvm/CodeGen/InterferenceGraph.h"
+
+
+InterferenceGraph::InterferenceGraph(RegClass *const RC) : RegCl(RC), 
+                                                          IGNodeList() 
+{   
+  IG = NULL;         
+  Size = 0;            
+  if( DEBUG_RA) {
+    cout << "Interference graph created!" << endl;
+  }
+}
+
+InterferenceGraph:: ~InterferenceGraph() {                // destructor
+    if( IG )
+      delete []IG;
+  }
+
+
+
+
+void InterferenceGraph::createGraph()   
+{ 
+    Size = IGNodeList.size();
+    IG = (char **) new char *[Size]; 
+    for( unsigned int r=0; r < Size; ++r)
+      IG[r] = new char[Size];
+
+    // init IG matrix
+    for(unsigned int i=0; i < Size; i++)     
+      for( unsigned int j=0; j < Size ; j++)
+       IG[i][j] = 0;
+}
+
+
+
+void InterferenceGraph::addLRToIG(LiveRange *const LR)
+{
+  IGNode *Node = new IGNode(LR,  IGNodeList.size() );
+  IGNodeList.push_back( Node );
+  //Node->setRegClass( RegCl );
+}
+
+
+// update both the matrix and AdjLists of nodes.
+// If there is already an interference between LR1 and LR2, adj lists
+// are not updated. LR1 and LR2 must be distinct since if not, it suggests
+// that there is some wrong logic in some other method.
+
+void InterferenceGraph::setInterference(const LiveRange *const LR1,
+                                       const LiveRange *const LR2 ) {
+  assert(LR1 != LR2);   
+
+  IGNode *const IGNode1 = LR1->getUserIGNode();
+  IGNode *const IGNode2 = LR2->getUserIGNode();
+
+  if( DEBUG_RA) {
+    assertIGNode( IGNode1 );   
+    assertIGNode( IGNode2 );
+  }
+  
+  const unsigned int row = IGNode1->getIndex();
+  const unsigned int col = IGNode2->getIndex();
+
+  char *val;
+
+  if( DEBUG_RA > 1) 
+    cout << "setting intf for: [" << row << "][" <<  col << "]" << endl; 
+
+  ( row > col) ?  val = &IG[row][col]: val = &IG[col][row]; 
+
+  if( ! (*val) ) {                      // if this interf is not previously set
+
+    *val = 1;                           // add edges between nodes 
+    IGNode1->addAdjIGNode( IGNode2 );   
+    IGNode2->addAdjIGNode( IGNode1 );
+  }
+
+}
+
+
+
+unsigned InterferenceGraph::getInterference(const LiveRange *const LR1,
+                                          const LiveRange *const LR2 ) const {
+
+  assert(LR1 != LR2);
+
+  if( DEBUG_RA) {
+    assertIGNode( LR1->getUserIGNode() );  
+    assertIGNode( LR2->getUserIGNode() );
+  }
+
+  const unsigned int row = LR1->getUserIGNode()->getIndex();
+  const unsigned int col = LR2->getUserIGNode()->getIndex();
+
+  char ret; 
+  ( row > col) ?  (ret = IG[row][col]) : (ret = IG[col][row]) ; 
+  return ret;
+
+}
+
+
+
+// Merge 2 IGNodes. The neighbors of the SrcNode will be added to the DestNode.
+// Then the IGNode2L  will be deleted. Necessary for coalescing.
+// IMPORTANT: The live ranges are NOT merged by this method. Use 
+//            LiveRangeInfo::unionAndUpdateLRs for that purpose.
+
+void InterferenceGraph::mergeIGNodesOfLRs(const LiveRange *const LR1, 
+                                         LiveRange *const LR2 ) {
+
+  assert( LR1 != LR2);                  // cannot merge the same live range
+
+  IGNode *const DestNode = LR1->getUserIGNode();
+  IGNode *SrcNode = LR2->getUserIGNode();
+
+  assertIGNode( DestNode );
+  assertIGNode( SrcNode );
+
+  if( DEBUG_RA > 1) {
+    cout << "Merging LRs: \""; LR1->printSet(); 
+    cout << "\" and \""; LR2->printSet();
+    cout << "\"" << endl;
+  }
+
+  unsigned SrcDegree = SrcNode->getNumOfNeighbors();
+  const unsigned SrcInd = SrcNode->getIndex();
+
+
+  // for all neighs of SrcNode
+  for(unsigned i=0; i < SrcDegree; i++) {        
+    IGNode *NeighNode = SrcNode->getAdjIGNode(i); 
+
+    LiveRange *const LROfNeigh = NeighNode->getParentLR();
+
+    // delete edge between src and neigh - even neigh == dest
+    NeighNode->delAdjIGNode(SrcNode);  
+
+    // set the matrix posn to 0 betn src and neigh - even neigh == dest
+    const unsigned NInd = NeighNode->getIndex();
+    ( SrcInd > NInd) ?  (IG[SrcInd][NInd]=0) : (IG[NInd][SrcInd]=0) ; 
+
+
+    if( LR1 != LROfNeigh) {             // if the neigh != dest 
+     
+      // add edge betwn Dest and Neigh - if there is no current edge
+      setInterference(LR1, LROfNeigh );  
+    }
+    
+    //cout<< "  #Neighs - Neigh: ["<< NeighNode->getIndex()<< "] ";
+    //cout << NeighNode->getNumOfNeighbors();
+    //cout << " Dest: [" << DestNode->getIndex() << "] ";
+    //cout << DestNode->getNumOfNeighbors()  << endl;
+
+  }
+
+  IGNodeList[ SrcInd ] = NULL;
+
+  // SrcNode is no longer necessary - LR2 must be deleted by the caller
+  delete( SrcNode );    
+
+}
+
+
+
+// must be called after modifications to the graph are over but before
+// pushing IGNodes on to the stack for coloring.
+
+void InterferenceGraph::setCurDegreeOfIGNodes()
+{
+  unsigned Size = IGNodeList.size();
+
+  for( unsigned i=0; i < Size; i++) {
+    IGNode *Node = IGNodeList[i];
+    if( Node )
+      Node->setCurDegree();
+  }
+}
+
+
+
+
+
+//--------------------- debugging (Printing) methods -----------------------
+
+
+void InterferenceGraph::printIG() const
+{
+
+  for(unsigned int i=0; i < Size; i++) {   
+
+    const IGNode *const Node = IGNodeList[i];
+    if( ! Node )
+      continue;                         // skip empty rows
+
+    cout << " [" << i << "] ";
+
+      for( unsigned int j=0; j < Size; j++) {
+       if( j >= i) break;
+       if( IG[i][j] ) cout << "(" << i << "," << j << ") ";
+      }
+      cout << endl;
+    }
+}
+
+
+void InterferenceGraph::printIGNodeList() const
+{
+  vector<IGNode *>::const_iterator IGIt = IGNodeList.begin(); // hash map iter
+
+  for(unsigned i=0; i < IGNodeList.size() ; ++i) {
+
+    const IGNode *const Node = IGNodeList[i];
+
+    if( ! Node )
+      continue;
+
+    cout << " [" << Node->getIndex() << "] ";
+    (Node->getParentLR())->printSet(); 
+    //int Deg = Node->getCurDegree();
+    cout << "\t <# of Neighs: " << Node->getNumOfNeighbors() << ">" << endl;
+    
+  }
+}
+
+
diff --git a/lib/CodeGen/RegAlloc/LiveRangeInfo.cpp b/lib/CodeGen/RegAlloc/LiveRangeInfo.cpp
new file mode 100644 (file)
index 0000000..5ef3502
--- /dev/null
@@ -0,0 +1,283 @@
+#include "llvm/CodeGen/LiveRangeInfo.h"
+
+LiveRangeInfo::LiveRangeInfo(const Method *const M, 
+                            const TargetMachine& tm,
+                            vector<RegClass *> &RCL) 
+                             : Meth(M), LiveRangeMap(), 
+                              TM(tm), RegClassList(RCL)
+{ }
+
+
+// union two live ranges into one. The 2nd LR is deleted. Used for coalescing.
+// Note: the caller must make sure that L1 and L2 are distinct
+
+void LiveRangeInfo::unionAndUpdateLRs(LiveRange *const L1, LiveRange *L2)
+{
+  assert( L1 != L2);
+  L1->setUnion( L2 );             // add elements of L2 to L1
+  ValueSet::iterator L2It;
+
+  for( L2It = L2->begin() ; L2It != L2->end(); ++L2It) {
+
+    //assert(( L1->getTypeID() == L2->getTypeID()) && "Merge:Different types");
+
+    L1->add( *L2It );            // add the var in L2 to L1
+    LiveRangeMap[ *L2It ] = L1;  // now the elements in L2 should map to L1    
+  }
+  delete ( L2 );                 // delete L2 as it is no longer needed
+}
+
+
+
+                                 
+void LiveRangeInfo::constructLiveRanges()
+{  
+
+  if( DEBUG_RA) 
+    cout << "Consturcting Live Ranges ..." << endl;
+
+  // first find the live ranges for all incoming args of the method since
+  // those LRs start from the start of the method
+      
+                                                 // get the argument list
+  const Method::ArgumentListType& ArgList = Meth->getArgumentList();           
+                                                 // get an iterator to arg list
+  Method::ArgumentListType::const_iterator ArgIt = ArgList.begin(); 
+
+             
+  for( ; ArgIt != ArgList.end() ; ++ArgIt) {     // for each argument
+
+    LiveRange * ArgRange = new LiveRange();      // creates a new LR and 
+    const Value *const Val = (const Value *) *ArgIt;
+
+    assert( Val);
+
+    ArgRange->add( Val );     // add the arg (def) to it
+    LiveRangeMap[ Val ] = ArgRange;
+
+    // create a temp machine op to find the register class of value
+    //const MachineOperand Op(MachineOperand::MO_VirtualRegister);
+
+    unsigned rcid = (TM.getRegInfo()).getRegClassIDOfValue( Val );
+    ArgRange->setRegClass(RegClassList[ rcid ] );
+
+                          
+    if( DEBUG_RA > 1) {     
+      cout << " adding LiveRange for argument ";    
+      printValue( (const Value *) *ArgIt); cout  << endl;
+    }
+  }
+
+
+  // Now find all LRs for machine the instructions. A new LR will be created 
+  // only for defs in the machine instr since, we assume that all Values are
+  // defined before they are used. However, there can be multiple defs for
+  // the same Value in machine instructions.
+
+  Method::const_iterator BBI = Meth->begin();    // random iterator for BBs   
+
+  for( ; BBI != Meth->end(); ++BBI) {            // go thru BBs in random order
+
+    // get the iterator for machine instructions
+    const MachineCodeForBasicBlock& MIVec = (*BBI)->getMachineInstrVec();
+    MachineCodeForBasicBlock::const_iterator 
+      MInstIterator = MIVec.begin();
+
+    // iterate over all the machine instructions in BB
+    for( ; MInstIterator != MIVec.end(); MInstIterator++) {  
+      
+      const MachineInstr * MInst = *MInstIterator; 
+      
+      // iterate over  MI operands to find defs
+      for( MachineInstr::val_op_const_iterator OpI(MInst);!OpI.done(); OpI++) {
+       
+       // create a new LR iff this operand is a def
+       if( OpI.isDef() ) {     
+         
+         const Value *const Def = *OpI;
+         LiveRange *DefRange = LiveRangeMap[Def]; 
+
+         // see LR already there (because of multiple defs)
+         
+         if( !DefRange) {                  // if it is not in LiveRangeMap
+           
+           DefRange = new LiveRange();     // creates a new live range and 
+           DefRange->add( Def );           // add the instruction (def) to it
+           LiveRangeMap[ Def ] = DefRange; // update the map
+
+           if( DEBUG_RA > 1) {             
+             cout << "  creating a LR for def: ";    
+             printValue(Def); cout  << endl;
+           }
+
+           // set the register class of the new live range
+           //assert( RegClassList.size() );
+           MachineOperand::MachineOperandType OpTy = 
+             OpI.getMachineOperand().getOperandType();
+
+           bool isCC = ( OpTy == MachineOperand::MO_CCRegister);
+           unsigned rcid = (TM.getRegInfo()).getRegClassIDOfValue( 
+                           OpI.getMachineOperand().getVRegValue(), isCC );
+
+
+           if(isCC )
+             cout << "\a" << "**created a LR for a CC reg**" << cout;
+
+           DefRange->setRegClass( RegClassList[ rcid ] );
+
+         }
+         else {
+           DefRange->add( Def );           // add the opearand to def range
+                                            // update the map - Operand points 
+                                           // to the merged set
+           LiveRangeMap[ Def ] = DefRange; 
+
+           if( DEBUG_RA > 1) { 
+             cout << "   added to an existing LR for def: ";  
+             printValue( Def ); cout  << endl;
+           }
+         }
+
+
+
+
+       } // if isDef()
+       
+      } // for all opereands in machine instructions
+
+    } // for all machine instructions in the BB
+
+  } // for all BBs in method
+
+  if( DEBUG_RA) 
+    cout << "Initial Live Ranges constructed!" << endl;
+
+}
+
+
+
+void LiveRangeInfo::coalesceLRs()  
+{
+
+/* Algorithm:
+   for each BB in method
+     for each machine instruction (inst)
+       for each definition (def) in inst
+         for each operand (op) of inst that is a use
+           if the def and op are of the same type
+            if the def and op do not interfere //i.e., not simultaneously live
+              if (degree(LR of def) + degree(LR of op)) <= # avail regs
+                merge2IGNodes(def, op) // i.e., merge 2 LRs 
+
+*/
+
+  if( DEBUG_RA) 
+    cout << endl << "Coalscing LRs ..." << endl;
+
+  Method::const_iterator BBI = Meth->begin();  // random iterator for BBs   
+
+  for( ; BBI != Meth->end(); ++BBI) {          // traverse BBs in random order
+
+    // get the iterator for machine instructions
+    const MachineCodeForBasicBlock& MIVec = (*BBI)->getMachineInstrVec();
+    MachineCodeForBasicBlock::const_iterator 
+      MInstIterator = MIVec.begin();
+
+    // iterate over all the machine instructions in BB
+    for( ; MInstIterator != MIVec.end(); ++MInstIterator) {  
+      
+      const MachineInstr * MInst = *MInstIterator; 
+
+      if( DEBUG_RA > 1) {
+       cout << " *Iterating over machine instr ";
+       MInst->dump();
+       cout << endl;
+      }
+
+
+      // iterate over  MI operands to find defs
+      for(MachineInstr::val_op_const_iterator DefI(MInst);!DefI.done();++DefI){
+       
+       if( DefI.isDef() ) {            // iff this operand is a def
+
+         LiveRange *const LROfDef = getLiveRangeForValue( *DefI );
+         assert( LROfDef );
+         RegClass *const RCOfDef = LROfDef->getRegClass();
+
+         MachineInstr::val_op_const_iterator UseI(MInst);
+         for( ; !UseI.done(); ++UseI){ // for all uses
+
+           LiveRange *const LROfUse = getLiveRangeForValue( *UseI );
+
+           if( ! LROfUse ) {           // if LR of use is not found
+
+             //don't warn about labels
+             if (!((*UseI)->getType())->isLabelType() && DEBUG_RA) {
+               cout<<" !! Warning: No LR for use "; printValue(*UseI);
+               cout << endl;
+             }
+             continue;                 // ignore and continue
+           }
+
+           if( LROfUse == LROfDef)     // nothing to merge if they are same
+             continue;
+
+           // RegClass *const RCOfUse = LROfUse->getRegClass();
+
+           //if( RCOfDef == RCOfUse ) {  // if the reg classes are the same
+
+
+           if( LROfUse->getTypeID() == LROfDef->getTypeID() ) { 
+
+             if( ! RCOfDef->getInterference(LROfDef, LROfUse) ) {
+
+               unsigned CombinedDegree =
+                 LROfDef->getUserIGNode()->getNumOfNeighbors() + 
+                 LROfUse->getUserIGNode()->getNumOfNeighbors();
+
+               if( CombinedDegree <= RCOfDef->getNumOfAvailRegs() ) {
+
+                 RCOfDef->mergeIGNodesOfLRs(LROfDef, LROfUse);
+                 unionAndUpdateLRs(LROfDef, LROfUse);
+
+               } // if combined degree is less than # of regs
+
+             } // if def and use do not interfere
+
+           } // if reg classes are the same
+
+         } // for all uses
+
+       } // if def
+
+      } // for all defs
+
+    } // for all machine instructions
+
+  } // for all BBs
+
+  if( DEBUG_RA) 
+    cout << endl << "Coalscing Done!" << endl;
+
+}
+
+
+
+
+
+/*--------------------------- Debug code for printing ---------------*/
+
+
+void LiveRangeInfo::printLiveRanges()
+{
+  LiveRangeMapType::iterator HMI = LiveRangeMap.begin();   // hash map iterator
+  cout << endl << "Printing Live Ranges from Hash Map:" << endl;
+  for( ; HMI != LiveRangeMap.end() ; HMI ++ ) {
+    if( (*HMI).first ) {
+      cout <<" "; printValue((*HMI).first);  cout  << "\t: "; 
+      ((*HMI).second)->printSet(); cout << endl;
+    }
+  }
+}
+
+
diff --git a/lib/CodeGen/RegAlloc/PhyRegAloc.cpp b/lib/CodeGen/RegAlloc/PhyRegAloc.cpp
new file mode 100644 (file)
index 0000000..c2c7c64
--- /dev/null
@@ -0,0 +1,343 @@
+#include "llvm/CodeGen/PhyRegAlloc.h"
+
+
+PhyRegAlloc::PhyRegAlloc(const Method *const M, 
+                        const TargetMachine& tm, 
+                        MethodLiveVarInfo *const Lvi) 
+                        : RegClassList(),
+                         Meth(M), TM(tm), LVI(Lvi), LRI(M, tm, RegClassList), 
+                         MRI( tm.getRegInfo() ),
+                          NumOfRegClasses(MRI.getNumOfRegClasses()),
+                         CallInstrList(),
+                         AddedInstrMap()
+
+{
+  // **TODO: use an actual reserved color list 
+  ReservedColorListType *RCL = new ReservedColorListType();
+
+  // create each RegisterClass and put in RegClassList
+  for( unsigned int rc=0; rc < NumOfRegClasses; rc++)  
+    RegClassList.push_back( new RegClass(M, MRI.getMachineRegClass(rc), RCL) );
+
+}
+
+
+
+
+
+
+void PhyRegAlloc::createIGNodeListsAndIGs()
+{
+  cout << "Creating LR lists ..." << endl;
+
+  // hash map iterator
+  LiveRangeMapType::const_iterator HMI = (LRI.getLiveRangeMap())->begin();   
+
+  // hash map end
+  LiveRangeMapType::const_iterator HMIEnd = (LRI.getLiveRangeMap())->end();   
+
+    for(  ; HMI != HMIEnd ; ++HMI ) {
+
+     LiveRange *L = (*HMI).second;      // get the LiveRange
+
+     if( (*HMI).first ) { 
+                                        // if the Value * is not null, and LR  
+                                        // is not yet written to the IGNodeList
+       if( !(L->getUserIGNode())  ) {  
+                                  
+        RegClass *const RC =           // RegClass of first value in the LR
+          //RegClassList [MRI.getRegClassIDOfValue(*(L->begin()))];
+          RegClassList[ L->getRegClass()->getID() ];
+
+        RC-> addLRToIG( L );           // add this LR to an IG
+       }
+    }
+  }
+
+                                        // init RegClassList
+  for( unsigned int rc=0; rc < NumOfRegClasses ; rc++)  
+    RegClassList[ rc ]->createInterferenceGraph();
+
+  if( DEBUG_RA)
+    cout << "LRLists Created!" << endl;
+}
+
+
+
+
+// Interence occurs only if the LR of Def (Inst or Arg) is of the same reg 
+// class as that of live var. The live var passed to this function is the 
+// LVset AFTER the instruction
+
+
+void PhyRegAlloc::addInterference(const Value *const Def, 
+                                 const LiveVarSet *const LVSet,
+                                 const bool isCallInst) {
+
+  LiveVarSet::const_iterator LIt = LVSet->begin();
+
+  // get the live range of instruction
+  const LiveRange *const LROfDef = LRI.getLiveRangeForValue( Def );   
+
+  IGNode *const IGNodeOfDef = LROfDef->getUserIGNode();
+  assert( IGNodeOfDef );
+
+  RegClass *const RCOfDef = LROfDef->getRegClass(); 
+
+  // for each live var in live variable set
+  for( ; LIt != LVSet->end(); ++LIt) {
+
+    if( DEBUG_RA > 1) {
+      cout << "< Def="; printValue(Def);     
+      cout << ", Lvar=";  printValue( *LIt); cout  << "> ";
+    }
+
+    //  get the live range corresponding to live var
+    LiveRange *const LROfVar = LRI.getLiveRangeForValue(*LIt );    
+
+    // LROfVar can be null if it is a const since a const 
+    // doesn't have a dominating def - see Assumptions above
+    if( LROfVar)   {  
+
+      if(LROfDef == LROfVar)            // do not set interf for same LR
+       continue;
+
+      // if 2 reg classes are the same set interference
+      if( RCOfDef == LROfVar->getRegClass() ){ 
+       RCOfDef->setInterference( LROfDef, LROfVar);  
+
+      }
+
+      //the live range of this var interferes with this call
+      if( isCallInst ) 
+       LROfVar->addCallInterference( (const Instruction *const) Def );   
+      
+    }
+    else if(DEBUG_RA)  { 
+      // we will not have LRs for values not explicitly allocated in the
+      // instruction stream (e.g., constants)
+      cout << " warning: no live range for " ; 
+      printValue( *LIt); cout << endl; }
+    
+  }
+}
+
+
+
+void PhyRegAlloc::buildInterferenceGraphs()
+{
+
+  if(DEBUG_RA) cout << "Creating interference graphs ..." << endl;
+
+  Method::const_iterator BBI = Meth->begin();  // random iterator for BBs   
+
+  for( ; BBI != Meth->end(); ++BBI) {          // traverse BBs in random order
+
+    // get the iterator for machine instructions
+    const MachineCodeForBasicBlock& MIVec = (*BBI)->getMachineInstrVec();
+    MachineCodeForBasicBlock::const_iterator 
+      MInstIterator = MIVec.begin();
+
+    // iterate over all the machine instructions in BB
+    for( ; MInstIterator != MIVec.end(); ++MInstIterator) {  
+      
+      const MachineInstr *const MInst = *MInstIterator; 
+
+      // get the LV set after the instruction
+      const LiveVarSet *const LVSetAI = 
+       LVI->getLiveVarSetAfterMInst(MInst, *BBI);
+    
+      const bool isCallInst = TM.getInstrInfo().isCall(MInst->getOpCode());
+
+      // iterate over  MI operands to find defs
+      for( MachineInstr::val_op_const_iterator OpI(MInst);!OpI.done(); ++OpI) {
+       
+       if( OpI.isDef() ) {     
+         // create a new LR iff this operand is a def
+         addInterference(*OpI, LVSetAI, isCallInst );
+
+       } //if this is a def
+
+      } // for all operands
+
+    } // for all machine instructions in BB
+
+
+    // go thru LLVM instructions in the basic block and record all CALL
+    // instructions in the CallInstrList
+    BasicBlock::const_iterator InstIt = (*BBI)->begin();
+
+    for( ; InstIt != (*BBI)->end() ; ++ InstIt) {
+
+      if( (*InstIt)->getOpcode() == Instruction::Call )
+       CallInstrList.push_back( *InstIt );
+   }
+    
+  } // for all BBs in method
+
+
+  // add interferences for method arguments. Since there are no explict 
+  // defs in method for args, we have to add them manually
+          
+  addInterferencesForArgs();            // add interference for method args
+
+  if( DEBUG_RA)
+    cout << "Interference graphs calculted!" << endl;
+
+}
+
+
+
+
+void PhyRegAlloc::addInterferencesForArgs()
+{
+                                              // get the InSet of root BB
+  const LiveVarSet *const InSet = LVI->getInSetOfBB( Meth->front() );  
+
+                                              // get the argument list
+  const Method::ArgumentListType& ArgList = Meth->getArgumentList();  
+
+                                              // get an iterator to arg list
+  Method::ArgumentListType::const_iterator ArgIt = ArgList.begin();          
+
+
+  for( ; ArgIt != ArgList.end() ; ++ArgIt) {  // for each argument
+    addInterference( *ArgIt, InSet, false );  // add interferences between 
+                                              // args and LVars at start
+    if( DEBUG_RA > 1) {
+      cout << " - %% adding interference for  argument ";    
+      printValue( (const Value *) *ArgIt); cout  << endl;
+    }
+  }
+}
+
+
+
+void PhyRegAlloc::updateMachineCode()
+{
+
+  Method::const_iterator BBI = Meth->begin();  // random iterator for BBs   
+
+  for( ; BBI != Meth->end(); ++BBI) {          // traverse BBs in random order
+
+    cout << endl << "BB "; printValue( *BBI); cout << ": ";
+
+    // get the iterator for machine instructions
+    MachineCodeForBasicBlock& MIVec = (*BBI)->getMachineInstrVec();
+    MachineCodeForBasicBlock::iterator MInstIterator = MIVec.begin();
+
+    // iterate over all the machine instructions in BB
+    for( ; MInstIterator != MIVec.end(); ++MInstIterator) {  
+      
+      MachineInstr *const MInst = *MInstIterator; 
+
+      cout << endl << "\t";
+      cout << TargetInstrDescriptors[MInst->getOpCode()].opCodeString;
+
+      //for(MachineInstr::val_op_const_iterator OpI(MInst);!OpI.done();++OpI) {
+
+      for(unsigned OpNum=0; OpNum < MInst->getNumOperands(); ++OpNum) {
+
+       MachineOperand& Op = MInst->getOperand(OpNum);
+
+       if( Op.getOperandType() ==  MachineOperand::MO_VirtualRegister || 
+           Op.getOperandType() ==  MachineOperand::MO_CCRegister) {
+
+         const Value *const Val =  Op.getVRegValue();
+
+         if( !Val ) { 
+           cout << "\t<** Value is NULL!!!**>";
+           continue;
+         }
+         assert( Val && "Value is NULL");
+
+         const LiveRange *const LR = LRI.getLiveRangeForValue(Val);
+
+         if ( !LR ) {
+           if( ! ( (Val->getType())->isLabelType() || 
+                   (Val->getValueType() == Value::ConstantVal) ) ) {
+             cout <<  "\t" << "<*No LiveRange for: ";
+             printValue( Val); cout << "*>";
+           }
+
+
+           //assert( LR && "No LR found for Value");
+           continue;
+         }
+       
+         unsigned RCID = (LR->getRegClass())->getID();
+
+         //cout << "Setting reg for value: "; printValue( Val );
+         //cout << endl;
+
+         //Op.setRegForValue( MRI.getUnifiedRegNum(RCID, LR->getColor()) );
+
+         int RegNum = MRI.getUnifiedRegNum(RCID, LR->getColor());
+
+         cout << "\t" << "%" << MRI.getUnifiedRegName( RegNum );
+
+       } 
+       else 
+         cout << "\t" << Op;      // use dump field
+
+      }
+
+    }
+  }
+}
+
+
+
+
+
+
+
+void PhyRegAlloc::allocateRegisters()
+{
+  constructLiveRanges();                // create LR info
+
+  if( DEBUG_RA)
+    LRI.printLiveRanges();
+
+  createIGNodeListsAndIGs();            // create IGNode list and IGs
+
+  buildInterferenceGraphs();            // build IGs in all reg classes
+
+  
+  if( DEBUG_RA) {
+    // print all LRs in all reg classes
+    for( unsigned int rc=0; rc < NumOfRegClasses  ; rc++)  
+      RegClassList[ rc ]->printIGNodeList(); 
+
+    // print IGs in all register classes
+    for( unsigned int rc=0; rc < NumOfRegClasses ; rc++)  
+      RegClassList[ rc ]->printIG();       
+  }
+
+  LRI.coalesceLRs();                    // coalesce all live ranges
+
+  if( DEBUG_RA) {
+    // print all LRs in all reg classes
+    for( unsigned int rc=0; rc < NumOfRegClasses  ; rc++)  
+      RegClassList[ rc ]->printIGNodeList(); 
+
+    // print IGs in all register classes
+    for( unsigned int rc=0; rc < NumOfRegClasses ; rc++)  
+      RegClassList[ rc ]->printIG();       
+  }
+
+  MRI.colorArgs(Meth, LRI);             // color method args
+  MRI.colorCallArgs(CallInstrList, LRI, AddedInstrMap); // color call args of call instrns
+
+                                        // color all register classes
+  for( unsigned int rc=0; rc < NumOfRegClasses ; rc++)  
+    RegClassList[ rc ]->colorAllRegs();    
+
+  updateMachineCode(); 
+  //PrintMachineInstructions(Meth);
+}
+
+
+
+
diff --git a/lib/CodeGen/RegAlloc/RegClass.cpp b/lib/CodeGen/RegAlloc/RegClass.cpp
new file mode 100644 (file)
index 0000000..90ad960
--- /dev/null
@@ -0,0 +1,202 @@
+#include "llvm/CodeGen/RegClass.h"
+
+
+
+RegClass::RegClass(const Method *const M, 
+                  const MachineRegClassInfo *const Mrc, 
+                  const ReservedColorListType *const RCL)
+                  :  Meth(M), MRC(Mrc), RegClassID( Mrc->getRegClassID() ),
+                     IG(this), IGNodeStack(), ReservedColorList(RCL)
+{
+  if( DEBUG_RA)
+    cout << "Created Reg Class: " << RegClassID << endl;
+
+  // This constructor inits IG. The actual matrix is created by a call to 
+  // createInterferenceGraph() above.
+
+  IsColorUsedArr = new bool[ Mrc->getNumOfAllRegs() ];
+}
+
+
+
+void RegClass::colorAllRegs()
+{
+  if(DEBUG_RA) cout << "Coloring IGs ..." << endl;
+
+  //preColorIGNodes();                    // pre-color IGNodes
+  pushAllIGNodes();                     // push all IG Nodes
+
+  unsigned int StackSize = IGNodeStack.size();    
+  IGNode *CurIGNode;
+
+  // for all LRs on stack
+  for( unsigned int IGN=0; IGN < StackSize; IGN++) {  
+  
+    CurIGNode = IGNodeStack.top();      // pop the IGNode on top of stack
+    IGNodeStack.pop();
+    colorIGNode (CurIGNode);            // color it
+  }
+
+
+  // InsertSpillCode;  ********* TODO ********
+
+}
+
+
+
+void RegClass::pushAllIGNodes()
+{
+  bool NeedMoreSpills;          
+  IGNode *IGNodeSpill, *IGNode;
+
+  IG.setCurDegreeOfIGNodes();           // calculate degree of IGNodes
+
+  // push non-constrained IGNodes
+  bool PushedAll  = pushUnconstrainedIGNodes(); 
+
+  if( DEBUG_RA) {
+    cout << " Puhsed all-unconstrained IGNodes. ";
+    if( PushedAll ) cout << " No constrained nodes left.";
+    cout << endl;
+  }
+
+  if( PushedAll )                       // if NO constrained nodes left
+    return;
+
+
+  // now, we have constrained nodes. So, push one of them (the one with min 
+  // spill cost) and try to push the others as unConstrained nodes. 
+  // Repeat this.
+
+  do{
+
+    //get IGNode with min spill cost
+    IGNodeSpill = getIGNodeWithMinSpillCost(); 
+
+    //  push IGNode on to stack
+    IGNodeStack.push( IGNodeSpill ); 
+
+    // set OnStack flag and decrement degree of neighs 
+    IGNode->pushOnStack(); 
+   
+    // now push NON-constrined ones, if any
+    NeedMoreSpills = ! pushUnconstrainedIGNodes(); 
+
+  } while( NeedMoreSpills );            // repeat until we have pushed all 
+
+}
+
+
+
+
+
+
+bool  RegClass::pushUnconstrainedIGNodes()  
+{
+  // # of LRs for this reg class 
+  unsigned int IGNodeListSize = IG.getIGNodeList().size(); 
+  bool pushedall = true;
+
+  // a pass over IGNodeList
+  for( unsigned i =0; i  < IGNodeListSize; i++) {
+
+    // get IGNode i from IGNodeList
+    IGNode *IGNode = IG.getIGNodeList()[i]; 
+
+    if( ! IGNode )                      // can be null due to merging
+       continue;
+
+                                        // if the degree of IGNode is lower
+    if( (unsigned) IGNode->getCurDegree()  < MRC->getNumOfAvailRegs() ) {   
+      IGNodeStack.push( IGNode );       // push IGNode on to the stack
+      IGNode->pushOnStack();            // set OnStack and dec deg of neighs
+
+      if (DEBUG_RA > 1) {
+       cout << " pushed un-constrained IGNode " << IGNode->getIndex() ;
+       cout << " on to stack" << endl;
+      }
+    }
+    else pushedall = false;             // we didn't push all live ranges
+    
+  } // for
+  
+  // returns true if we pushed all live ranges - else false
+  return pushedall; 
+}
+
+
+
+
+IGNode * RegClass::getIGNodeWithMinSpillCost()
+{
+  IGNode *IGNode=NULL;
+  unsigned int IGNodeListSize = IG.getIGNodeList().size(); 
+
+  // pass over IGNodeList
+  for( unsigned int i =0; i  < IGNodeListSize; i++) {
+    IGNode = IG.getIGNodeList()[i];
+    
+    if( ! IGNode )                      // can be null due to merging
+      continue;
+    
+    // return the first IGNode ########## Change this #######
+    if( ! IGNode->isOnStack() ) return IGNode;   
+  }
+  
+  assert(0);
+  return NULL;
+}
+
+
+
+
+void RegClass::colorIGNode(IGNode *const Node)
+{
+
+  if( ! Node->hasColor() )   {          // not colored as an arg etc.
+   
+
+    // init all elements to  false;
+    for( unsigned  i=0; i < MRC->getNumOfAllRegs(); i++) { 
+      IsColorUsedArr[ i ] = false;
+    }
+    
+    // init all reserved_regs to true - we can't use them
+    for( unsigned i=0; i < ReservedColorList->size() ; i++) {  
+      IsColorUsedArr[ (*ReservedColorList)[i] ] = true;
+    }
+
+    MRC->colorIGNode(Node, IsColorUsedArr);
+  }
+  else {
+    cout << " Node " << Node->getIndex();
+    cout << " already colored with color " << Node->getColor() << endl;
+  }
+
+
+  if( !Node->hasColor() ) {
+    cout << " Node " << Node->getIndex();
+    cout << " - could not find a color (needs spilling)" << endl;
+  }
+
+}
+
+
+#if 0
+
+  if( DEBUG_RA) {                       // printing code 
+    /*    cout << " Node " << Node->getIndex();
+    if( Node->hasColor() ) { 
+      cout << " colored with color " << Node->getColor() <<  " [" ;
+      cout << SparcFloatRegOrder::getRegName(Node->getColor());
+      if( Node->getTypeID() == Type::DoubleTyID )
+       cout << "+" << SparcFloatRegOrder::getRegName(Node->getColor()+1);
+      cout << "]" << endl;
+    }
+    */
+    // MRC->printReg( Node->getParentLR());
+    cout << " Node " << Node->getIndex();
+    if( Node->hasColor() ) 
+      cout << " colored with color " << Node->getColor() << endl;
+    
+#endif
diff --git a/lib/Target/SparcV9/RegAlloc/IGNode.cpp b/lib/Target/SparcV9/RegAlloc/IGNode.cpp
new file mode 100644 (file)
index 0000000..0e8a124
--- /dev/null
@@ -0,0 +1,31 @@
+#include "llvm/CodeGen/IGNode.h"
+
+
+IGNode::IGNode(LiveRange *const PLR, unsigned int Ind): Index(Ind),
+                                                        ParentLR(PLR)
+{
+  OnStack = false;
+  CurDegree = -1 ;
+  ParentLR->setUserIGNode( this );
+}
+
+
+
+void IGNode::pushOnStack()            // sets on to stack and 
+{                                     // reduce the degree of neighbors  
+  OnStack = true; 
+  unsigned int neighs = AdjList.size();
+
+  for(unsigned int i=0; i < neighs; i++)  (AdjList[i])->decCurDegree();
+}
+
+void IGNode::delAdjIGNode(const IGNode *const Node) {
+  vector <IGNode *>::iterator It = AdjList.begin();
+    
+  // find Node
+  for( ; It != AdjList.end() && (*It != Node); It++ ) ;
+  assert( It != AdjList.end() );      // the node must be there
+  
+  AdjList.erase( It );
+}
diff --git a/lib/Target/SparcV9/RegAlloc/InterferenceGraph.cpp b/lib/Target/SparcV9/RegAlloc/InterferenceGraph.cpp
new file mode 100644 (file)
index 0000000..d8ec247
--- /dev/null
@@ -0,0 +1,226 @@
+#include "llvm/CodeGen/InterferenceGraph.h"
+
+
+InterferenceGraph::InterferenceGraph(RegClass *const RC) : RegCl(RC), 
+                                                          IGNodeList() 
+{   
+  IG = NULL;         
+  Size = 0;            
+  if( DEBUG_RA) {
+    cout << "Interference graph created!" << endl;
+  }
+}
+
+InterferenceGraph:: ~InterferenceGraph() {                // destructor
+    if( IG )
+      delete []IG;
+  }
+
+
+
+
+void InterferenceGraph::createGraph()   
+{ 
+    Size = IGNodeList.size();
+    IG = (char **) new char *[Size]; 
+    for( unsigned int r=0; r < Size; ++r)
+      IG[r] = new char[Size];
+
+    // init IG matrix
+    for(unsigned int i=0; i < Size; i++)     
+      for( unsigned int j=0; j < Size ; j++)
+       IG[i][j] = 0;
+}
+
+
+
+void InterferenceGraph::addLRToIG(LiveRange *const LR)
+{
+  IGNode *Node = new IGNode(LR,  IGNodeList.size() );
+  IGNodeList.push_back( Node );
+  //Node->setRegClass( RegCl );
+}
+
+
+// update both the matrix and AdjLists of nodes.
+// If there is already an interference between LR1 and LR2, adj lists
+// are not updated. LR1 and LR2 must be distinct since if not, it suggests
+// that there is some wrong logic in some other method.
+
+void InterferenceGraph::setInterference(const LiveRange *const LR1,
+                                       const LiveRange *const LR2 ) {
+  assert(LR1 != LR2);   
+
+  IGNode *const IGNode1 = LR1->getUserIGNode();
+  IGNode *const IGNode2 = LR2->getUserIGNode();
+
+  if( DEBUG_RA) {
+    assertIGNode( IGNode1 );   
+    assertIGNode( IGNode2 );
+  }
+  
+  const unsigned int row = IGNode1->getIndex();
+  const unsigned int col = IGNode2->getIndex();
+
+  char *val;
+
+  if( DEBUG_RA > 1) 
+    cout << "setting intf for: [" << row << "][" <<  col << "]" << endl; 
+
+  ( row > col) ?  val = &IG[row][col]: val = &IG[col][row]; 
+
+  if( ! (*val) ) {                      // if this interf is not previously set
+
+    *val = 1;                           // add edges between nodes 
+    IGNode1->addAdjIGNode( IGNode2 );   
+    IGNode2->addAdjIGNode( IGNode1 );
+  }
+
+}
+
+
+
+unsigned InterferenceGraph::getInterference(const LiveRange *const LR1,
+                                          const LiveRange *const LR2 ) const {
+
+  assert(LR1 != LR2);
+
+  if( DEBUG_RA) {
+    assertIGNode( LR1->getUserIGNode() );  
+    assertIGNode( LR2->getUserIGNode() );
+  }
+
+  const unsigned int row = LR1->getUserIGNode()->getIndex();
+  const unsigned int col = LR2->getUserIGNode()->getIndex();
+
+  char ret; 
+  ( row > col) ?  (ret = IG[row][col]) : (ret = IG[col][row]) ; 
+  return ret;
+
+}
+
+
+
+// Merge 2 IGNodes. The neighbors of the SrcNode will be added to the DestNode.
+// Then the IGNode2L  will be deleted. Necessary for coalescing.
+// IMPORTANT: The live ranges are NOT merged by this method. Use 
+//            LiveRangeInfo::unionAndUpdateLRs for that purpose.
+
+void InterferenceGraph::mergeIGNodesOfLRs(const LiveRange *const LR1, 
+                                         LiveRange *const LR2 ) {
+
+  assert( LR1 != LR2);                  // cannot merge the same live range
+
+  IGNode *const DestNode = LR1->getUserIGNode();
+  IGNode *SrcNode = LR2->getUserIGNode();
+
+  assertIGNode( DestNode );
+  assertIGNode( SrcNode );
+
+  if( DEBUG_RA > 1) {
+    cout << "Merging LRs: \""; LR1->printSet(); 
+    cout << "\" and \""; LR2->printSet();
+    cout << "\"" << endl;
+  }
+
+  unsigned SrcDegree = SrcNode->getNumOfNeighbors();
+  const unsigned SrcInd = SrcNode->getIndex();
+
+
+  // for all neighs of SrcNode
+  for(unsigned i=0; i < SrcDegree; i++) {        
+    IGNode *NeighNode = SrcNode->getAdjIGNode(i); 
+
+    LiveRange *const LROfNeigh = NeighNode->getParentLR();
+
+    // delete edge between src and neigh - even neigh == dest
+    NeighNode->delAdjIGNode(SrcNode);  
+
+    // set the matrix posn to 0 betn src and neigh - even neigh == dest
+    const unsigned NInd = NeighNode->getIndex();
+    ( SrcInd > NInd) ?  (IG[SrcInd][NInd]=0) : (IG[NInd][SrcInd]=0) ; 
+
+
+    if( LR1 != LROfNeigh) {             // if the neigh != dest 
+     
+      // add edge betwn Dest and Neigh - if there is no current edge
+      setInterference(LR1, LROfNeigh );  
+    }
+    
+    //cout<< "  #Neighs - Neigh: ["<< NeighNode->getIndex()<< "] ";
+    //cout << NeighNode->getNumOfNeighbors();
+    //cout << " Dest: [" << DestNode->getIndex() << "] ";
+    //cout << DestNode->getNumOfNeighbors()  << endl;
+
+  }
+
+  IGNodeList[ SrcInd ] = NULL;
+
+  // SrcNode is no longer necessary - LR2 must be deleted by the caller
+  delete( SrcNode );    
+
+}
+
+
+
+// must be called after modifications to the graph are over but before
+// pushing IGNodes on to the stack for coloring.
+
+void InterferenceGraph::setCurDegreeOfIGNodes()
+{
+  unsigned Size = IGNodeList.size();
+
+  for( unsigned i=0; i < Size; i++) {
+    IGNode *Node = IGNodeList[i];
+    if( Node )
+      Node->setCurDegree();
+  }
+}
+
+
+
+
+
+//--------------------- debugging (Printing) methods -----------------------
+
+
+void InterferenceGraph::printIG() const
+{
+
+  for(unsigned int i=0; i < Size; i++) {   
+
+    const IGNode *const Node = IGNodeList[i];
+    if( ! Node )
+      continue;                         // skip empty rows
+
+    cout << " [" << i << "] ";
+
+      for( unsigned int j=0; j < Size; j++) {
+       if( j >= i) break;
+       if( IG[i][j] ) cout << "(" << i << "," << j << ") ";
+      }
+      cout << endl;
+    }
+}
+
+
+void InterferenceGraph::printIGNodeList() const
+{
+  vector<IGNode *>::const_iterator IGIt = IGNodeList.begin(); // hash map iter
+
+  for(unsigned i=0; i < IGNodeList.size() ; ++i) {
+
+    const IGNode *const Node = IGNodeList[i];
+
+    if( ! Node )
+      continue;
+
+    cout << " [" << Node->getIndex() << "] ";
+    (Node->getParentLR())->printSet(); 
+    //int Deg = Node->getCurDegree();
+    cout << "\t <# of Neighs: " << Node->getNumOfNeighbors() << ">" << endl;
+    
+  }
+}
+
+
diff --git a/lib/Target/SparcV9/RegAlloc/LiveRangeInfo.cpp b/lib/Target/SparcV9/RegAlloc/LiveRangeInfo.cpp
new file mode 100644 (file)
index 0000000..5ef3502
--- /dev/null
@@ -0,0 +1,283 @@
+#include "llvm/CodeGen/LiveRangeInfo.h"
+
+LiveRangeInfo::LiveRangeInfo(const Method *const M, 
+                            const TargetMachine& tm,
+                            vector<RegClass *> &RCL) 
+                             : Meth(M), LiveRangeMap(), 
+                              TM(tm), RegClassList(RCL)
+{ }
+
+
+// union two live ranges into one. The 2nd LR is deleted. Used for coalescing.
+// Note: the caller must make sure that L1 and L2 are distinct
+
+void LiveRangeInfo::unionAndUpdateLRs(LiveRange *const L1, LiveRange *L2)
+{
+  assert( L1 != L2);
+  L1->setUnion( L2 );             // add elements of L2 to L1
+  ValueSet::iterator L2It;
+
+  for( L2It = L2->begin() ; L2It != L2->end(); ++L2It) {
+
+    //assert(( L1->getTypeID() == L2->getTypeID()) && "Merge:Different types");
+
+    L1->add( *L2It );            // add the var in L2 to L1
+    LiveRangeMap[ *L2It ] = L1;  // now the elements in L2 should map to L1    
+  }
+  delete ( L2 );                 // delete L2 as it is no longer needed
+}
+
+
+
+                                 
+void LiveRangeInfo::constructLiveRanges()
+{  
+
+  if( DEBUG_RA) 
+    cout << "Consturcting Live Ranges ..." << endl;
+
+  // first find the live ranges for all incoming args of the method since
+  // those LRs start from the start of the method
+      
+                                                 // get the argument list
+  const Method::ArgumentListType& ArgList = Meth->getArgumentList();           
+                                                 // get an iterator to arg list
+  Method::ArgumentListType::const_iterator ArgIt = ArgList.begin(); 
+
+             
+  for( ; ArgIt != ArgList.end() ; ++ArgIt) {     // for each argument
+
+    LiveRange * ArgRange = new LiveRange();      // creates a new LR and 
+    const Value *const Val = (const Value *) *ArgIt;
+
+    assert( Val);
+
+    ArgRange->add( Val );     // add the arg (def) to it
+    LiveRangeMap[ Val ] = ArgRange;
+
+    // create a temp machine op to find the register class of value
+    //const MachineOperand Op(MachineOperand::MO_VirtualRegister);
+
+    unsigned rcid = (TM.getRegInfo()).getRegClassIDOfValue( Val );
+    ArgRange->setRegClass(RegClassList[ rcid ] );
+
+                          
+    if( DEBUG_RA > 1) {     
+      cout << " adding LiveRange for argument ";    
+      printValue( (const Value *) *ArgIt); cout  << endl;
+    }
+  }
+
+
+  // Now find all LRs for machine the instructions. A new LR will be created 
+  // only for defs in the machine instr since, we assume that all Values are
+  // defined before they are used. However, there can be multiple defs for
+  // the same Value in machine instructions.
+
+  Method::const_iterator BBI = Meth->begin();    // random iterator for BBs   
+
+  for( ; BBI != Meth->end(); ++BBI) {            // go thru BBs in random order
+
+    // get the iterator for machine instructions
+    const MachineCodeForBasicBlock& MIVec = (*BBI)->getMachineInstrVec();
+    MachineCodeForBasicBlock::const_iterator 
+      MInstIterator = MIVec.begin();
+
+    // iterate over all the machine instructions in BB
+    for( ; MInstIterator != MIVec.end(); MInstIterator++) {  
+      
+      const MachineInstr * MInst = *MInstIterator; 
+      
+      // iterate over  MI operands to find defs
+      for( MachineInstr::val_op_const_iterator OpI(MInst);!OpI.done(); OpI++) {
+       
+       // create a new LR iff this operand is a def
+       if( OpI.isDef() ) {     
+         
+         const Value *const Def = *OpI;
+         LiveRange *DefRange = LiveRangeMap[Def]; 
+
+         // see LR already there (because of multiple defs)
+         
+         if( !DefRange) {                  // if it is not in LiveRangeMap
+           
+           DefRange = new LiveRange();     // creates a new live range and 
+           DefRange->add( Def );           // add the instruction (def) to it
+           LiveRangeMap[ Def ] = DefRange; // update the map
+
+           if( DEBUG_RA > 1) {             
+             cout << "  creating a LR for def: ";    
+             printValue(Def); cout  << endl;
+           }
+
+           // set the register class of the new live range
+           //assert( RegClassList.size() );
+           MachineOperand::MachineOperandType OpTy = 
+             OpI.getMachineOperand().getOperandType();
+
+           bool isCC = ( OpTy == MachineOperand::MO_CCRegister);
+           unsigned rcid = (TM.getRegInfo()).getRegClassIDOfValue( 
+                           OpI.getMachineOperand().getVRegValue(), isCC );
+
+
+           if(isCC )
+             cout << "\a" << "**created a LR for a CC reg**" << cout;
+
+           DefRange->setRegClass( RegClassList[ rcid ] );
+
+         }
+         else {
+           DefRange->add( Def );           // add the opearand to def range
+                                            // update the map - Operand points 
+                                           // to the merged set
+           LiveRangeMap[ Def ] = DefRange; 
+
+           if( DEBUG_RA > 1) { 
+             cout << "   added to an existing LR for def: ";  
+             printValue( Def ); cout  << endl;
+           }
+         }
+
+
+
+
+       } // if isDef()
+       
+      } // for all opereands in machine instructions
+
+    } // for all machine instructions in the BB
+
+  } // for all BBs in method
+
+  if( DEBUG_RA) 
+    cout << "Initial Live Ranges constructed!" << endl;
+
+}
+
+
+
+void LiveRangeInfo::coalesceLRs()  
+{
+
+/* Algorithm:
+   for each BB in method
+     for each machine instruction (inst)
+       for each definition (def) in inst
+         for each operand (op) of inst that is a use
+           if the def and op are of the same type
+            if the def and op do not interfere //i.e., not simultaneously live
+              if (degree(LR of def) + degree(LR of op)) <= # avail regs
+                merge2IGNodes(def, op) // i.e., merge 2 LRs 
+
+*/
+
+  if( DEBUG_RA) 
+    cout << endl << "Coalscing LRs ..." << endl;
+
+  Method::const_iterator BBI = Meth->begin();  // random iterator for BBs   
+
+  for( ; BBI != Meth->end(); ++BBI) {          // traverse BBs in random order
+
+    // get the iterator for machine instructions
+    const MachineCodeForBasicBlock& MIVec = (*BBI)->getMachineInstrVec();
+    MachineCodeForBasicBlock::const_iterator 
+      MInstIterator = MIVec.begin();
+
+    // iterate over all the machine instructions in BB
+    for( ; MInstIterator != MIVec.end(); ++MInstIterator) {  
+      
+      const MachineInstr * MInst = *MInstIterator; 
+
+      if( DEBUG_RA > 1) {
+       cout << " *Iterating over machine instr ";
+       MInst->dump();
+       cout << endl;
+      }
+
+
+      // iterate over  MI operands to find defs
+      for(MachineInstr::val_op_const_iterator DefI(MInst);!DefI.done();++DefI){
+       
+       if( DefI.isDef() ) {            // iff this operand is a def
+
+         LiveRange *const LROfDef = getLiveRangeForValue( *DefI );
+         assert( LROfDef );
+         RegClass *const RCOfDef = LROfDef->getRegClass();
+
+         MachineInstr::val_op_const_iterator UseI(MInst);
+         for( ; !UseI.done(); ++UseI){ // for all uses
+
+           LiveRange *const LROfUse = getLiveRangeForValue( *UseI );
+
+           if( ! LROfUse ) {           // if LR of use is not found
+
+             //don't warn about labels
+             if (!((*UseI)->getType())->isLabelType() && DEBUG_RA) {
+               cout<<" !! Warning: No LR for use "; printValue(*UseI);
+               cout << endl;
+             }
+             continue;                 // ignore and continue
+           }
+
+           if( LROfUse == LROfDef)     // nothing to merge if they are same
+             continue;
+
+           // RegClass *const RCOfUse = LROfUse->getRegClass();
+
+           //if( RCOfDef == RCOfUse ) {  // if the reg classes are the same
+
+
+           if( LROfUse->getTypeID() == LROfDef->getTypeID() ) { 
+
+             if( ! RCOfDef->getInterference(LROfDef, LROfUse) ) {
+
+               unsigned CombinedDegree =
+                 LROfDef->getUserIGNode()->getNumOfNeighbors() + 
+                 LROfUse->getUserIGNode()->getNumOfNeighbors();
+
+               if( CombinedDegree <= RCOfDef->getNumOfAvailRegs() ) {
+
+                 RCOfDef->mergeIGNodesOfLRs(LROfDef, LROfUse);
+                 unionAndUpdateLRs(LROfDef, LROfUse);
+
+               } // if combined degree is less than # of regs
+
+             } // if def and use do not interfere
+
+           } // if reg classes are the same
+
+         } // for all uses
+
+       } // if def
+
+      } // for all defs
+
+    } // for all machine instructions
+
+  } // for all BBs
+
+  if( DEBUG_RA) 
+    cout << endl << "Coalscing Done!" << endl;
+
+}
+
+
+
+
+
+/*--------------------------- Debug code for printing ---------------*/
+
+
+void LiveRangeInfo::printLiveRanges()
+{
+  LiveRangeMapType::iterator HMI = LiveRangeMap.begin();   // hash map iterator
+  cout << endl << "Printing Live Ranges from Hash Map:" << endl;
+  for( ; HMI != LiveRangeMap.end() ; HMI ++ ) {
+    if( (*HMI).first ) {
+      cout <<" "; printValue((*HMI).first);  cout  << "\t: "; 
+      ((*HMI).second)->printSet(); cout << endl;
+    }
+  }
+}
+
+
diff --git a/lib/Target/SparcV9/RegAlloc/PhyRegAloc.cpp b/lib/Target/SparcV9/RegAlloc/PhyRegAloc.cpp
new file mode 100644 (file)
index 0000000..c2c7c64
--- /dev/null
@@ -0,0 +1,343 @@
+#include "llvm/CodeGen/PhyRegAlloc.h"
+
+
+PhyRegAlloc::PhyRegAlloc(const Method *const M, 
+                        const TargetMachine& tm, 
+                        MethodLiveVarInfo *const Lvi) 
+                        : RegClassList(),
+                         Meth(M), TM(tm), LVI(Lvi), LRI(M, tm, RegClassList), 
+                         MRI( tm.getRegInfo() ),
+                          NumOfRegClasses(MRI.getNumOfRegClasses()),
+                         CallInstrList(),
+                         AddedInstrMap()
+
+{
+  // **TODO: use an actual reserved color list 
+  ReservedColorListType *RCL = new ReservedColorListType();
+
+  // create each RegisterClass and put in RegClassList
+  for( unsigned int rc=0; rc < NumOfRegClasses; rc++)  
+    RegClassList.push_back( new RegClass(M, MRI.getMachineRegClass(rc), RCL) );
+
+}
+
+
+
+
+
+
+void PhyRegAlloc::createIGNodeListsAndIGs()
+{
+  cout << "Creating LR lists ..." << endl;
+
+  // hash map iterator
+  LiveRangeMapType::const_iterator HMI = (LRI.getLiveRangeMap())->begin();   
+
+  // hash map end
+  LiveRangeMapType::const_iterator HMIEnd = (LRI.getLiveRangeMap())->end();   
+
+    for(  ; HMI != HMIEnd ; ++HMI ) {
+
+     LiveRange *L = (*HMI).second;      // get the LiveRange
+
+     if( (*HMI).first ) { 
+                                        // if the Value * is not null, and LR  
+                                        // is not yet written to the IGNodeList
+       if( !(L->getUserIGNode())  ) {  
+                                  
+        RegClass *const RC =           // RegClass of first value in the LR
+          //RegClassList [MRI.getRegClassIDOfValue(*(L->begin()))];
+          RegClassList[ L->getRegClass()->getID() ];
+
+        RC-> addLRToIG( L );           // add this LR to an IG
+       }
+    }
+  }
+
+                                        // init RegClassList
+  for( unsigned int rc=0; rc < NumOfRegClasses ; rc++)  
+    RegClassList[ rc ]->createInterferenceGraph();
+
+  if( DEBUG_RA)
+    cout << "LRLists Created!" << endl;
+}
+
+
+
+
+// Interence occurs only if the LR of Def (Inst or Arg) is of the same reg 
+// class as that of live var. The live var passed to this function is the 
+// LVset AFTER the instruction
+
+
+void PhyRegAlloc::addInterference(const Value *const Def, 
+                                 const LiveVarSet *const LVSet,
+                                 const bool isCallInst) {
+
+  LiveVarSet::const_iterator LIt = LVSet->begin();
+
+  // get the live range of instruction
+  const LiveRange *const LROfDef = LRI.getLiveRangeForValue( Def );   
+
+  IGNode *const IGNodeOfDef = LROfDef->getUserIGNode();
+  assert( IGNodeOfDef );
+
+  RegClass *const RCOfDef = LROfDef->getRegClass(); 
+
+  // for each live var in live variable set
+  for( ; LIt != LVSet->end(); ++LIt) {
+
+    if( DEBUG_RA > 1) {
+      cout << "< Def="; printValue(Def);     
+      cout << ", Lvar=";  printValue( *LIt); cout  << "> ";
+    }
+
+    //  get the live range corresponding to live var
+    LiveRange *const LROfVar = LRI.getLiveRangeForValue(*LIt );    
+
+    // LROfVar can be null if it is a const since a const 
+    // doesn't have a dominating def - see Assumptions above
+    if( LROfVar)   {  
+
+      if(LROfDef == LROfVar)            // do not set interf for same LR
+       continue;
+
+      // if 2 reg classes are the same set interference
+      if( RCOfDef == LROfVar->getRegClass() ){ 
+       RCOfDef->setInterference( LROfDef, LROfVar);  
+
+      }
+
+      //the live range of this var interferes with this call
+      if( isCallInst ) 
+       LROfVar->addCallInterference( (const Instruction *const) Def );   
+      
+    }
+    else if(DEBUG_RA)  { 
+      // we will not have LRs for values not explicitly allocated in the
+      // instruction stream (e.g., constants)
+      cout << " warning: no live range for " ; 
+      printValue( *LIt); cout << endl; }
+    
+  }
+}
+
+
+
+void PhyRegAlloc::buildInterferenceGraphs()
+{
+
+  if(DEBUG_RA) cout << "Creating interference graphs ..." << endl;
+
+  Method::const_iterator BBI = Meth->begin();  // random iterator for BBs   
+
+  for( ; BBI != Meth->end(); ++BBI) {          // traverse BBs in random order
+
+    // get the iterator for machine instructions
+    const MachineCodeForBasicBlock& MIVec = (*BBI)->getMachineInstrVec();
+    MachineCodeForBasicBlock::const_iterator 
+      MInstIterator = MIVec.begin();
+
+    // iterate over all the machine instructions in BB
+    for( ; MInstIterator != MIVec.end(); ++MInstIterator) {  
+      
+      const MachineInstr *const MInst = *MInstIterator; 
+
+      // get the LV set after the instruction
+      const LiveVarSet *const LVSetAI = 
+       LVI->getLiveVarSetAfterMInst(MInst, *BBI);
+    
+      const bool isCallInst = TM.getInstrInfo().isCall(MInst->getOpCode());
+
+      // iterate over  MI operands to find defs
+      for( MachineInstr::val_op_const_iterator OpI(MInst);!OpI.done(); ++OpI) {
+       
+       if( OpI.isDef() ) {     
+         // create a new LR iff this operand is a def
+         addInterference(*OpI, LVSetAI, isCallInst );
+
+       } //if this is a def
+
+      } // for all operands
+
+    } // for all machine instructions in BB
+
+
+    // go thru LLVM instructions in the basic block and record all CALL
+    // instructions in the CallInstrList
+    BasicBlock::const_iterator InstIt = (*BBI)->begin();
+
+    for( ; InstIt != (*BBI)->end() ; ++ InstIt) {
+
+      if( (*InstIt)->getOpcode() == Instruction::Call )
+       CallInstrList.push_back( *InstIt );
+   }
+    
+  } // for all BBs in method
+
+
+  // add interferences for method arguments. Since there are no explict 
+  // defs in method for args, we have to add them manually
+          
+  addInterferencesForArgs();            // add interference for method args
+
+  if( DEBUG_RA)
+    cout << "Interference graphs calculted!" << endl;
+
+}
+
+
+
+
+void PhyRegAlloc::addInterferencesForArgs()
+{
+                                              // get the InSet of root BB
+  const LiveVarSet *const InSet = LVI->getInSetOfBB( Meth->front() );  
+
+                                              // get the argument list
+  const Method::ArgumentListType& ArgList = Meth->getArgumentList();  
+
+                                              // get an iterator to arg list
+  Method::ArgumentListType::const_iterator ArgIt = ArgList.begin();          
+
+
+  for( ; ArgIt != ArgList.end() ; ++ArgIt) {  // for each argument
+    addInterference( *ArgIt, InSet, false );  // add interferences between 
+                                              // args and LVars at start
+    if( DEBUG_RA > 1) {
+      cout << " - %% adding interference for  argument ";    
+      printValue( (const Value *) *ArgIt); cout  << endl;
+    }
+  }
+}
+
+
+
+void PhyRegAlloc::updateMachineCode()
+{
+
+  Method::const_iterator BBI = Meth->begin();  // random iterator for BBs   
+
+  for( ; BBI != Meth->end(); ++BBI) {          // traverse BBs in random order
+
+    cout << endl << "BB "; printValue( *BBI); cout << ": ";
+
+    // get the iterator for machine instructions
+    MachineCodeForBasicBlock& MIVec = (*BBI)->getMachineInstrVec();
+    MachineCodeForBasicBlock::iterator MInstIterator = MIVec.begin();
+
+    // iterate over all the machine instructions in BB
+    for( ; MInstIterator != MIVec.end(); ++MInstIterator) {  
+      
+      MachineInstr *const MInst = *MInstIterator; 
+
+      cout << endl << "\t";
+      cout << TargetInstrDescriptors[MInst->getOpCode()].opCodeString;
+
+      //for(MachineInstr::val_op_const_iterator OpI(MInst);!OpI.done();++OpI) {
+
+      for(unsigned OpNum=0; OpNum < MInst->getNumOperands(); ++OpNum) {
+
+       MachineOperand& Op = MInst->getOperand(OpNum);
+
+       if( Op.getOperandType() ==  MachineOperand::MO_VirtualRegister || 
+           Op.getOperandType() ==  MachineOperand::MO_CCRegister) {
+
+         const Value *const Val =  Op.getVRegValue();
+
+         if( !Val ) { 
+           cout << "\t<** Value is NULL!!!**>";
+           continue;
+         }
+         assert( Val && "Value is NULL");
+
+         const LiveRange *const LR = LRI.getLiveRangeForValue(Val);
+
+         if ( !LR ) {
+           if( ! ( (Val->getType())->isLabelType() || 
+                   (Val->getValueType() == Value::ConstantVal) ) ) {
+             cout <<  "\t" << "<*No LiveRange for: ";
+             printValue( Val); cout << "*>";
+           }
+
+
+           //assert( LR && "No LR found for Value");
+           continue;
+         }
+       
+         unsigned RCID = (LR->getRegClass())->getID();
+
+         //cout << "Setting reg for value: "; printValue( Val );
+         //cout << endl;
+
+         //Op.setRegForValue( MRI.getUnifiedRegNum(RCID, LR->getColor()) );
+
+         int RegNum = MRI.getUnifiedRegNum(RCID, LR->getColor());
+
+         cout << "\t" << "%" << MRI.getUnifiedRegName( RegNum );
+
+       } 
+       else 
+         cout << "\t" << Op;      // use dump field
+
+      }
+
+    }
+  }
+}
+
+
+
+
+
+
+
+void PhyRegAlloc::allocateRegisters()
+{
+  constructLiveRanges();                // create LR info
+
+  if( DEBUG_RA)
+    LRI.printLiveRanges();
+
+  createIGNodeListsAndIGs();            // create IGNode list and IGs
+
+  buildInterferenceGraphs();            // build IGs in all reg classes
+
+  
+  if( DEBUG_RA) {
+    // print all LRs in all reg classes
+    for( unsigned int rc=0; rc < NumOfRegClasses  ; rc++)  
+      RegClassList[ rc ]->printIGNodeList(); 
+
+    // print IGs in all register classes
+    for( unsigned int rc=0; rc < NumOfRegClasses ; rc++)  
+      RegClassList[ rc ]->printIG();       
+  }
+
+  LRI.coalesceLRs();                    // coalesce all live ranges
+
+  if( DEBUG_RA) {
+    // print all LRs in all reg classes
+    for( unsigned int rc=0; rc < NumOfRegClasses  ; rc++)  
+      RegClassList[ rc ]->printIGNodeList(); 
+
+    // print IGs in all register classes
+    for( unsigned int rc=0; rc < NumOfRegClasses ; rc++)  
+      RegClassList[ rc ]->printIG();       
+  }
+
+  MRI.colorArgs(Meth, LRI);             // color method args
+  MRI.colorCallArgs(CallInstrList, LRI, AddedInstrMap); // color call args of call instrns
+
+                                        // color all register classes
+  for( unsigned int rc=0; rc < NumOfRegClasses ; rc++)  
+    RegClassList[ rc ]->colorAllRegs();    
+
+  updateMachineCode(); 
+  //PrintMachineInstructions(Meth);
+}
+
+
+
+
diff --git a/lib/Target/SparcV9/RegAlloc/RegClass.cpp b/lib/Target/SparcV9/RegAlloc/RegClass.cpp
new file mode 100644 (file)
index 0000000..90ad960
--- /dev/null
@@ -0,0 +1,202 @@
+#include "llvm/CodeGen/RegClass.h"
+
+
+
+RegClass::RegClass(const Method *const M, 
+                  const MachineRegClassInfo *const Mrc, 
+                  const ReservedColorListType *const RCL)
+                  :  Meth(M), MRC(Mrc), RegClassID( Mrc->getRegClassID() ),
+                     IG(this), IGNodeStack(), ReservedColorList(RCL)
+{
+  if( DEBUG_RA)
+    cout << "Created Reg Class: " << RegClassID << endl;
+
+  // This constructor inits IG. The actual matrix is created by a call to 
+  // createInterferenceGraph() above.
+
+  IsColorUsedArr = new bool[ Mrc->getNumOfAllRegs() ];
+}
+
+
+
+void RegClass::colorAllRegs()
+{
+  if(DEBUG_RA) cout << "Coloring IGs ..." << endl;
+
+  //preColorIGNodes();                    // pre-color IGNodes
+  pushAllIGNodes();                     // push all IG Nodes
+
+  unsigned int StackSize = IGNodeStack.size();    
+  IGNode *CurIGNode;
+
+  // for all LRs on stack
+  for( unsigned int IGN=0; IGN < StackSize; IGN++) {  
+  
+    CurIGNode = IGNodeStack.top();      // pop the IGNode on top of stack
+    IGNodeStack.pop();
+    colorIGNode (CurIGNode);            // color it
+  }
+
+
+  // InsertSpillCode;  ********* TODO ********
+
+}
+
+
+
+void RegClass::pushAllIGNodes()
+{
+  bool NeedMoreSpills;          
+  IGNode *IGNodeSpill, *IGNode;
+
+  IG.setCurDegreeOfIGNodes();           // calculate degree of IGNodes
+
+  // push non-constrained IGNodes
+  bool PushedAll  = pushUnconstrainedIGNodes(); 
+
+  if( DEBUG_RA) {
+    cout << " Puhsed all-unconstrained IGNodes. ";
+    if( PushedAll ) cout << " No constrained nodes left.";
+    cout << endl;
+  }
+
+  if( PushedAll )                       // if NO constrained nodes left
+    return;
+
+
+  // now, we have constrained nodes. So, push one of them (the one with min 
+  // spill cost) and try to push the others as unConstrained nodes. 
+  // Repeat this.
+
+  do{
+
+    //get IGNode with min spill cost
+    IGNodeSpill = getIGNodeWithMinSpillCost(); 
+
+    //  push IGNode on to stack
+    IGNodeStack.push( IGNodeSpill ); 
+
+    // set OnStack flag and decrement degree of neighs 
+    IGNode->pushOnStack(); 
+   
+    // now push NON-constrined ones, if any
+    NeedMoreSpills = ! pushUnconstrainedIGNodes(); 
+
+  } while( NeedMoreSpills );            // repeat until we have pushed all 
+
+}
+
+
+
+
+
+
+bool  RegClass::pushUnconstrainedIGNodes()  
+{
+  // # of LRs for this reg class 
+  unsigned int IGNodeListSize = IG.getIGNodeList().size(); 
+  bool pushedall = true;
+
+  // a pass over IGNodeList
+  for( unsigned i =0; i  < IGNodeListSize; i++) {
+
+    // get IGNode i from IGNodeList
+    IGNode *IGNode = IG.getIGNodeList()[i]; 
+
+    if( ! IGNode )                      // can be null due to merging
+       continue;
+
+                                        // if the degree of IGNode is lower
+    if( (unsigned) IGNode->getCurDegree()  < MRC->getNumOfAvailRegs() ) {   
+      IGNodeStack.push( IGNode );       // push IGNode on to the stack
+      IGNode->pushOnStack();            // set OnStack and dec deg of neighs
+
+      if (DEBUG_RA > 1) {
+       cout << " pushed un-constrained IGNode " << IGNode->getIndex() ;
+       cout << " on to stack" << endl;
+      }
+    }
+    else pushedall = false;             // we didn't push all live ranges
+    
+  } // for
+  
+  // returns true if we pushed all live ranges - else false
+  return pushedall; 
+}
+
+
+
+
+IGNode * RegClass::getIGNodeWithMinSpillCost()
+{
+  IGNode *IGNode=NULL;
+  unsigned int IGNodeListSize = IG.getIGNodeList().size(); 
+
+  // pass over IGNodeList
+  for( unsigned int i =0; i  < IGNodeListSize; i++) {
+    IGNode = IG.getIGNodeList()[i];
+    
+    if( ! IGNode )                      // can be null due to merging
+      continue;
+    
+    // return the first IGNode ########## Change this #######
+    if( ! IGNode->isOnStack() ) return IGNode;   
+  }
+  
+  assert(0);
+  return NULL;
+}
+
+
+
+
+void RegClass::colorIGNode(IGNode *const Node)
+{
+
+  if( ! Node->hasColor() )   {          // not colored as an arg etc.
+   
+
+    // init all elements to  false;
+    for( unsigned  i=0; i < MRC->getNumOfAllRegs(); i++) { 
+      IsColorUsedArr[ i ] = false;
+    }
+    
+    // init all reserved_regs to true - we can't use them
+    for( unsigned i=0; i < ReservedColorList->size() ; i++) {  
+      IsColorUsedArr[ (*ReservedColorList)[i] ] = true;
+    }
+
+    MRC->colorIGNode(Node, IsColorUsedArr);
+  }
+  else {
+    cout << " Node " << Node->getIndex();
+    cout << " already colored with color " << Node->getColor() << endl;
+  }
+
+
+  if( !Node->hasColor() ) {
+    cout << " Node " << Node->getIndex();
+    cout << " - could not find a color (needs spilling)" << endl;
+  }
+
+}
+
+
+#if 0
+
+  if( DEBUG_RA) {                       // printing code 
+    /*    cout << " Node " << Node->getIndex();
+    if( Node->hasColor() ) { 
+      cout << " colored with color " << Node->getColor() <<  " [" ;
+      cout << SparcFloatRegOrder::getRegName(Node->getColor());
+      if( Node->getTypeID() == Type::DoubleTyID )
+       cout << "+" << SparcFloatRegOrder::getRegName(Node->getColor()+1);
+      cout << "]" << endl;
+    }
+    */
+    // MRC->printReg( Node->getParentLR());
+    cout << " Node " << Node->getIndex();
+    if( Node->hasColor() ) 
+      cout << " colored with color " << Node->getColor() << endl;
+    
+#endif