Rewrote uses of deprecated `MachineFunction::get(BasicBlock *BB)'.
[oota-llvm.git] / lib / Target / SparcV9 / RegAlloc / RegClass.cpp
index 2246643594612f06ed6a1c8b6e333402118314d7..788921ba019f0417be1dd9e99d57d4a1c3ab6871 100644 (file)
@@ -1,19 +1,26 @@
-#include "llvm/CodeGen/RegClass.h"
+//===-- RegClass.cpp -----------------------------------------------------===//
+// 
+//  class RegClass for coloring-based register allocation for LLVM.
+// 
+//===----------------------------------------------------------------------===//
 
+#include "llvm/CodeGen/RegClass.h"
+#include "llvm/CodeGen/RegAllocCommon.h"
+using std::cerr;
 
 //----------------------------------------------------------------------------
 // This constructor inits IG. The actual matrix is created by a call to 
 // createInterferenceGraph() above.
 //----------------------------------------------------------------------------
-RegClass::RegClass(const Method *const M, 
-                  const MachineRegClassInfo *const Mrc, 
-                  const ReservedColorListType *const RCL)
+RegClass::RegClass(const Function *M, 
+                  const MachineRegClassInfo *Mrc,
+                  const ReservedColorListType *RCL)
                   :  Meth(M), MRC(Mrc), RegClassID( Mrc->getRegClassID() ),
                      IG(this), IGNodeStack(), ReservedColorList(RCL) {
-  if( DEBUG_RA)
-    cout << "Created Reg Class: " << RegClassID << endl;
+  if( DEBUG_RA >= RA_DEBUG_Interference)
+    cerr << "Created Reg Class: " << RegClassID << "\n";
 
-  IsColorUsedArr = new bool[ Mrc->getNumOfAllRegs() ];
+  IsColorUsedArr.resize(Mrc->getNumOfAllRegs());
 }
 
 
@@ -23,7 +30,8 @@ RegClass::RegClass(const Method *const M,
 //----------------------------------------------------------------------------
 void RegClass::colorAllRegs()
 {
-  if(DEBUG_RA) cout << "Coloring IG of reg class " << RegClassID << " ...\n";
+  if(DEBUG_RA >= RA_DEBUG_Coloring)
+    cerr << "Coloring IG of reg class " << RegClassID << " ...\n";
 
                                         // pre-color IGNodes
   pushAllIGNodes();                     // push all IG Nodes
@@ -56,10 +64,10 @@ void RegClass::pushAllIGNodes()
                                         // 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( DEBUG_RA >= RA_DEBUG_Coloring) {
+    cerr << " Puhsed all-unconstrained IGNodes. ";
+    if( PushedAll ) cerr << " No constrained nodes left.";
+    cerr << "\n";
   }
 
   if( PushedAll )                       // if NO constrained nodes left
@@ -70,15 +78,14 @@ void RegClass::pushAllIGNodes()
   // spill cost) and try to push the others as unConstrained nodes. 
   // Repeat this.
 
-  do{
-
+  do {
     //get node with min spill cost
     //
     IGNode *IGNodeSpill =  getIGNodeWithMinSpillCost(); 
    
     //  push that node on to stack
     //
-    IGNodeStack.push( IGNodeSpill ); 
+    IGNodeStack.push(IGNodeSpill);
 
     // set its OnStack flag and decrement degree of neighs 
     //
@@ -86,11 +93,12 @@ void RegClass::pushAllIGNodes()
    
     // now push NON-constrined ones, if any
     //
-    NeedMoreSpills = ! pushUnconstrainedIGNodes(); 
+    NeedMoreSpills = !pushUnconstrainedIGNodes(); 
 
-    cerr << "\nConstrained IG Node found !@!" <<  IGNodeSpill->getIndex();
+    if (DEBUG_RA >= RA_DEBUG_Coloring)
+      cerr << "\nConstrained IG Node found !@!" << IGNodeSpill->getIndex();
 
-  } while( NeedMoreSpills );            // repeat until we have pushed all 
+  } while(NeedMoreSpills);            // repeat until we have pushed all 
 
 }
 
@@ -128,9 +136,9 @@ bool  RegClass::pushUnconstrainedIGNodes()
       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;
+      if (DEBUG_RA >= RA_DEBUG_Coloring) {
+       cerr << " pushed un-constrained IGNode " << IGNode->getIndex() ;
+       cerr << " on to stack\n";
       }
     }
     else pushedall = false;             // we didn't push all live ranges
@@ -150,9 +158,9 @@ IGNode * RegClass::getIGNodeWithMinSpillCost()
 {
 
   unsigned int IGNodeListSize = IG.getIGNodeList().size(); 
-  long MinSpillCost = -1;
+  double MinSpillCost = 0;
   IGNode *MinCostIGNode = NULL;
-
+  bool isFirstNode = true;
 
   // pass over IGNodeList to find the IGNode with minimum spill cost
   // among all IGNodes that are not yet pushed on to the stack
@@ -165,11 +173,13 @@ IGNode * RegClass::getIGNodeWithMinSpillCost()
 
     if( ! IGNode->isOnStack() ) {
 
-      unsigned SpillCost = IGNode->getParentLR()->getSpillCost();
+      double SpillCost = (double) IGNode->getParentLR()->getSpillCost() /
+       (double) (IGNode->getCurDegree() + 1);
     
-      if( MinSpillCost == -1) {         // for the first IG node
+      if( isFirstNode ) {         // for the first IG node
        MinSpillCost = SpillCost;
        MinCostIGNode = IGNode;
+       isFirstNode = false;
       }
 
       else if( MinSpillCost > SpillCost) {
@@ -197,32 +207,47 @@ void RegClass::colorIGNode(IGNode *const Node)
 
     // init all elements of to  IsColorUsedAr  false;
     //
-    for( unsigned  i=0; i < MRC->getNumOfAllRegs(); i++) { 
-      IsColorUsedArr[ i ] = 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;
+      IsColorUsedArr[(*ReservedColorList)[i]] = true;
     }
 
+    // initialize all colors used by neighbors of this node to true
+    LiveRange *LR = Node->getParentLR();
+    unsigned NumNeighbors =  Node->getNumOfNeighbors();
+    for (unsigned n=0; n < NumNeighbors; n++) {
+      IGNode *NeighIGNode = Node->getAdjIGNode(n);
+      LiveRange *NeighLR = NeighIGNode->getParentLR();
+      
+      if (NeighLR->hasColor()) {                        // if has a color
+        IsColorUsedArr[NeighLR->getColor()] = true;  // mark color as used
+      } else if (NeighLR->hasSuggestedColor() &&
+                 NeighLR->isSuggestedColorUsable()) {
+        // this color is suggested for the neighbour, so don't use it
+        IsColorUsedArr[NeighLR->getSuggestedColor()] = true; 
+      }
+    }
+    
     // call the target specific code for coloring
     //
     MRC->colorIGNode(Node, IsColorUsedArr);
   }
   else {
-    if( DEBUG_RA ) {
-      cout << " Node " << Node->getIndex();
-      cout << " already colored with color " << Node->getColor() << endl;
+    if( DEBUG_RA >= RA_DEBUG_Coloring) {
+      cerr << " Node " << Node->getIndex();
+      cerr << " already colored with color " << Node->getColor() << "\n";
     }
   }
 
 
   if( !Node->hasColor() ) {
-    if( DEBUG_RA ) {
-      cout << " Node " << Node->getIndex();
-      cout << " - could not find a color (needs spilling)" << endl;
+    if( DEBUG_RA >= RA_DEBUG_Coloring) {
+      cerr << " Node " << Node->getIndex();
+      cerr << " - could not find a color (needs spilling)\n";
     }
   }