Added destructors and comments.
authorRuchira Sasanka <sasanka@students.uiuc.edu>
Mon, 7 Jan 2002 19:19:18 +0000 (19:19 +0000)
committerRuchira Sasanka <sasanka@students.uiuc.edu>
Mon, 7 Jan 2002 19:19:18 +0000 (19:19 +0000)
Added correct spill candidate selection logic.

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

lib/CodeGen/RegAlloc/IGNode.cpp
lib/CodeGen/RegAlloc/InterferenceGraph.cpp
lib/CodeGen/RegAlloc/LiveRangeInfo.cpp
lib/CodeGen/RegAlloc/PhyRegAlloc.cpp
lib/CodeGen/RegAlloc/RegClass.cpp
lib/Target/SparcV9/RegAlloc/IGNode.cpp
lib/Target/SparcV9/RegAlloc/InterferenceGraph.cpp
lib/Target/SparcV9/RegAlloc/LiveRangeInfo.cpp
lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp
lib/Target/SparcV9/RegAlloc/RegClass.cpp

index d8473d2370bb765bb36c315578a6146435fd4b3c..4e66d9a762c96724ddedc7303f99a9b70d4abeba 100644 (file)
@@ -1,6 +1,9 @@
 #include "llvm/CodeGen/IGNode.h"
 
 
+//-----------------------------------------------------------------------------
+// Constructor
+//-----------------------------------------------------------------------------
 IGNode::IGNode(LiveRange *const PLR, unsigned int Ind): Index(Ind),
                                                        AdjList(),
                                                         ParentLR(PLR)
@@ -11,9 +14,11 @@ IGNode::IGNode(LiveRange *const PLR, unsigned int Ind): Index(Ind),
 }
 
 
-
-void IGNode::pushOnStack()            // sets on to stack and 
-{                                     // reduce the degree of neighbors  
+//-----------------------------------------------------------------------------
+// Sets this IGNode on stack and reduce the degree of neighbors  
+//-----------------------------------------------------------------------------
+void IGNode::pushOnStack()             
+{                                     
   OnStack = true; 
   int neighs = AdjList.size();
 
@@ -25,7 +30,10 @@ void IGNode::pushOnStack()            // sets on to stack and
   for(int i=0; i < neighs; i++)  (AdjList[i])->decCurDegree();
 }
  
-
+//-----------------------------------------------------------------------------
+// Deletes an adjacency node. IGNodes are deleted when coalescing merges
+// two IGNodes together.
+//-----------------------------------------------------------------------------
 void IGNode::delAdjIGNode(const IGNode *const Node) {
   vector <IGNode *>::iterator It = AdjList.begin();
     
index d8ec2470aaa43b4bc46a3256a83d08e009ef41df..e18c9a7a348b8d405a6d7ebaef9e4e71ed5b090e 100644 (file)
@@ -1,6 +1,10 @@
 #include "llvm/CodeGen/InterferenceGraph.h"
 
-
+//-----------------------------------------------------------------------------
+// Constructor: Records the RegClass and initalizes IGNodeList.
+// The matrix is NOT yet created by the constructor. Call createGraph() 
+// to create it after adding all IGNodes to the IGNodeList.
+//-----------------------------------------------------------------------------
 InterferenceGraph::InterferenceGraph(RegClass *const RC) : RegCl(RC), 
                                                           IGNodeList() 
 {   
@@ -11,14 +15,34 @@ InterferenceGraph::InterferenceGraph(RegClass *const RC) : RegCl(RC),
   }
 }
 
-InterferenceGraph:: ~InterferenceGraph() {                // destructor
-    if( IG )
-      delete []IG;
+
+//-----------------------------------------------------------------------------
+// destructor. Deletes the bit matrix and all IGNodes
+//-----------------------------------------------------------------------------
+InterferenceGraph:: ~InterferenceGraph() {             
+
+  // delete the matrix
+  //
+  if( IG )
+    delete []IG;
+
+  // delete all IGNodes in the IGNodeList
+  //
+  vector<IGNode *>::const_iterator IGIt = IGNodeList.begin();
+  for(unsigned i=0; i < IGNodeList.size() ; ++i) {
+
+    const IGNode *const Node = IGNodeList[i];
+    if( Node ) delete Node;
   }
 
+}
 
 
 
+//-----------------------------------------------------------------------------
+// Creates (dynamically allocates) the bit matrix necessary to hold the
+// interference graph.
+//-----------------------------------------------------------------------------
 void InterferenceGraph::createGraph()   
 { 
     Size = IGNodeList.size();
@@ -32,21 +56,24 @@ void InterferenceGraph::createGraph()
        IG[i][j] = 0;
 }
 
-
-
+//-----------------------------------------------------------------------------
+// creates a new IGNode for the given live range and add to IG
+//-----------------------------------------------------------------------------
 void InterferenceGraph::addLRToIG(LiveRange *const LR)
 {
   IGNode *Node = new IGNode(LR,  IGNodeList.size() );
   IGNodeList.push_back( Node );
-  //Node->setRegClass( RegCl );
+
 }
 
 
+//-----------------------------------------------------------------------------
+// set interference for two live ranges
 // 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);   
@@ -79,7 +106,9 @@ void InterferenceGraph::setInterference(const LiveRange *const LR1,
 }
 
 
-
+//----------------------------------------------------------------------------
+// return whether two live ranges interfere
+//----------------------------------------------------------------------------
 unsigned InterferenceGraph::getInterference(const LiveRange *const LR1,
                                           const LiveRange *const LR2 ) const {
 
@@ -100,11 +129,12 @@ unsigned InterferenceGraph::getInterference(const LiveRange *const LR1,
 }
 
 
-
+//----------------------------------------------------------------------------
 // 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 ) {
@@ -147,11 +177,6 @@ void InterferenceGraph::mergeIGNodesOfLRs(const LiveRange *const LR1,
       setInterference(LR1, LROfNeigh );  
     }
     
-    //cout<< "  #Neighs - Neigh: ["<< NeighNode->getIndex()<< "] ";
-    //cout << NeighNode->getNumOfNeighbors();
-    //cout << " Dest: [" << DestNode->getIndex() << "] ";
-    //cout << DestNode->getNumOfNeighbors()  << endl;
-
   }
 
   IGNodeList[ SrcInd ] = NULL;
@@ -162,10 +187,10 @@ void InterferenceGraph::mergeIGNodesOfLRs(const LiveRange *const LR1,
 }
 
 
-
+//----------------------------------------------------------------------------
 // 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();
@@ -183,7 +208,9 @@ void InterferenceGraph::setCurDegreeOfIGNodes()
 
 //--------------------- debugging (Printing) methods -----------------------
 
-
+//----------------------------------------------------------------------------
+// Print the IGnodes 
+//----------------------------------------------------------------------------
 void InterferenceGraph::printIG() const
 {
 
@@ -203,7 +230,9 @@ void InterferenceGraph::printIG() const
     }
 }
 
-
+//----------------------------------------------------------------------------
+// Print the IGnodes in the IGNode List
+//----------------------------------------------------------------------------
 void InterferenceGraph::printIGNodeList() const
 {
   vector<IGNode *>::const_iterator IGIt = IGNodeList.begin(); // hash map iter
index 00385d99de20cc03443fc63d343ae6f516905938..7fb688f55effee3cbf1e9295062351ebc00a662f 100644 (file)
@@ -1,5 +1,8 @@
 #include "llvm/CodeGen/LiveRangeInfo.h"
 
+//---------------------------------------------------------------------------
+// Constructor
+//---------------------------------------------------------------------------
 LiveRangeInfo::LiveRangeInfo(const Method *const M, 
                             const TargetMachine& tm,
                             vector<RegClass *> &RCL) 
@@ -10,22 +13,58 @@ LiveRangeInfo::LiveRangeInfo(const Method *const M,
 { }
 
 
+//---------------------------------------------------------------------------
+// Destructor: Deletes all LiveRanges in the LiveRangeMap
+//---------------------------------------------------------------------------
+LiveRangeInfo::~LiveRangeInfo() {
+
+  LiveRangeMapType::iterator MI =  LiveRangeMap.begin(); 
+
+  for( ; MI != LiveRangeMap.end() ; ++MI) {  
+    if( (*MI).first ) {
+      
+      LiveRange *LR = (*MI).second;
+       
+      if( LR ) {
+
+       // we need to be careful in deleting LiveRanges in LiveRangeMap
+       // since two/more Values in the live range map can point to the same
+       // live range. We have to make the other entries NULL when we delete
+       // a live range.
+
+       LiveRange::iterator LI = LR->begin();
+       
+       for( ; LI != LR->end() ; ++LI) { 
+         LiveRangeMap[*LI] = NULL;
+       }
+
+       delete LR;
+
+      }
+    }
+  }
+
+}
+
+
+//---------------------------------------------------------------------------
 // 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 and both
 // LRs don't have suggested colors
-
+//---------------------------------------------------------------------------
 void LiveRangeInfo::unionAndUpdateLRs(LiveRange *const L1, LiveRange *L2)
 {
   assert( L1 != L2);
-  L1->setUnion( L2 );             // add elements of L2 to L1
+  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    
+    L1->add( *L2It );                   // add the var in L2 to L1
+    LiveRangeMap[ *L2It ] = L1;         // now the elements in L2 should map 
+                                        //to L1    
   }
 
 
@@ -40,13 +79,19 @@ void LiveRangeInfo::unionAndUpdateLRs(LiveRange *const L1, LiveRange *L2)
   if( L2->isCallInterference() )
     L1->setCallInterference();
   
+  L1->addSpillCost( L2->getSpillCost() ); // add the spill costs
 
-  delete ( L2 );                 // delete L2 as it is no longer needed
+  delete ( L2 );                        // delete L2 as it is no longer needed
 }
 
 
 
-                                 
+//---------------------------------------------------------------------------
+// Method for constructing all live ranges in a method. It creates live 
+// ranges for all values defined in the instruction stream. Also, it
+// creates live ranges for all incoming arguments of the method.
+//---------------------------------------------------------------------------
 void LiveRangeInfo::constructLiveRanges()
 {  
 
@@ -216,10 +261,14 @@ void LiveRangeInfo::constructLiveRanges()
 }
 
 
-
-// Suggest colors for call and return args. 
-// Also create new LRs for implicit defs
-
+//---------------------------------------------------------------------------
+// If some live ranges must be colored with specific hardware registers
+// (e.g., for outgoing call args), suggesting of colors for such live
+// ranges is done using target specific method. Those methods are called
+// from this function. The target specific methods must:
+//    1) suggest colors for call and return args. 
+//    2) create new LRs for implicit defs in machine instructions
+//---------------------------------------------------------------------------
 void LiveRangeInfo::suggestRegs4CallRets()
 {
 
@@ -243,11 +292,11 @@ void LiveRangeInfo::suggestRegs4CallRets()
 }
 
 
+//--------------------------------------------------------------------------
+// The following method coalesces live ranges when possible. This method
+// must be called after the interference graph has been constructed.
 
 
-void LiveRangeInfo::coalesceLRs()  
-{
-
 /* Algorithm:
    for each BB in method
      for each machine instruction (inst)
@@ -260,6 +309,11 @@ void LiveRangeInfo::coalesceLRs()
                    merge2IGNodes(def, op) // i.e., merge 2 LRs 
 
 */
+//---------------------------------------------------------------------------
+void LiveRangeInfo::coalesceLRs()  
+{
+
+
 
   if( DEBUG_RA) 
     cout << endl << "Coalscing LRs ..." << endl;
index 240e8c1c2a98b68982cf92297e63d12200e3d771..dc1c8690ee6977bab9e5a70e455b4613683739c0 100644 (file)
@@ -14,6 +14,7 @@
 #include "llvm/CodeGen/MachineInstr.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/MachineFrameInfo.h"
+#include <math.h>
 
 
 // ***TODO: There are several places we add instructions. Validate the order
@@ -41,22 +42,31 @@ PhyRegAlloc::PhyRegAlloc(Method *M,
                           LVI(Lvi), LRI(M, tm, RegClassList), 
                          MRI( tm.getRegInfo() ),
                           NumOfRegClasses(MRI.getNumOfRegClasses()),
-                         AddedInstrMap()
-                    
-{
-  // **TODO: use an actual reserved color list 
-  ReservedColorListType *RCL = new ReservedColorListType();
+                         AddedInstrMap(), LoopDepthCalc(M), ResColList() {
 
   // 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) );
+    RegClassList.push_back( new RegClass(M, MRI.getMachineRegClass(rc), 
+                                        &ResColList) );
 }
 
+
+//----------------------------------------------------------------------------
+// Destructor: Deletes register classes
+//----------------------------------------------------------------------------
+PhyRegAlloc::~PhyRegAlloc() { 
+
+  for( unsigned int rc=0; rc < NumOfRegClasses; rc++) { 
+    RegClass *RC = RegClassList[rc];
+    delete RC;
+  }
+} 
+
 //----------------------------------------------------------------------------
 // This method initally creates interference graphs (one in each reg class)
 // and IGNodeList (one in each IG). The actual nodes will be pushed later. 
 //----------------------------------------------------------------------------
-
 void PhyRegAlloc::createIGNodeListsAndIGs()
 {
   if(DEBUG_RA ) cout << "Creating LR lists ..." << endl;
@@ -71,7 +81,7 @@ void PhyRegAlloc::createIGNodeListsAndIGs()
       
       if( (*HMI).first ) { 
 
-       LiveRange *L = (*HMI).second;      // get the LiveRange
+       LiveRange *L = (*HMI).second;   // get the LiveRange
 
        if( !L) { 
          if( DEBUG_RA) {
@@ -103,13 +113,13 @@ void PhyRegAlloc::createIGNodeListsAndIGs()
 
 
 
+
 //----------------------------------------------------------------------------
 // This method will add all interferences at for a given instruction.
 // 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) {
@@ -117,6 +127,7 @@ void PhyRegAlloc::addInterference(const Value *const Def,
   LiveVarSet::const_iterator LIt = LVSet->begin();
 
   // get the live range of instruction
+  //
   const LiveRange *const LROfDef = LRI.getLiveRangeForValue( Def );   
 
   IGNode *const IGNodeOfDef = LROfDef->getUserIGNode();
@@ -125,6 +136,7 @@ void PhyRegAlloc::addInterference(const Value *const Def,
   RegClass *const RCOfDef = LROfDef->getRegClass(); 
 
   // for each live var in live variable set
+  //
   for( ; LIt != LVSet->end(); ++LIt) {
 
     if( DEBUG_RA > 1) {
@@ -133,16 +145,19 @@ void PhyRegAlloc::addInterference(const Value *const Def,
     }
 
     //  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);  
 
@@ -161,6 +176,8 @@ void PhyRegAlloc::addInterference(const Value *const Def,
 }
 
 
+
+
 //----------------------------------------------------------------------------
 // For a call instruction, this method sets the CallInterference flag in 
 // the LR of each variable live int the Live Variable Set live after the
@@ -169,18 +186,15 @@ void PhyRegAlloc::addInterference(const Value *const Def,
 //----------------------------------------------------------------------------
 
 void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst, 
-                                      const LiveVarSet *const LVSetAft ) 
-{
-  // Now find the LR of the return value of the call
-
+                                      const LiveVarSet *const LVSetAft ) {
 
+  // Now find the LR of the return value of the call
   // We do this because, we look at the LV set *after* the instruction
   // to determine, which LRs must be saved across calls. The return value
   // of the call is live in this set - but it does not interfere with call
   // (i.e., we can allocate a volatile register to the return value)
-
+  //
   LiveRange *RetValLR = NULL;
-
   const Value *RetVal = MRI.getCallInstRetVal( MInst );
 
   if( RetVal ) {
@@ -194,9 +208,11 @@ void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst,
   LiveVarSet::const_iterator LIt = LVSetAft->begin();
 
   // for each live var in live variable set after machine inst
+  //
   for( ; LIt != LVSetAft->end(); ++LIt) {
 
-   //  get the live range corresponding to live var
+    //  get the live range corresponding to live var
+    //
     LiveRange *const LR = LRI.getLiveRangeForValue(*LIt ); 
 
     if( LR && DEBUG_RA) {
@@ -207,6 +223,7 @@ void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst,
 
     // LR can be null if it is a const since a const 
     // doesn't have a dominating def - see Assumptions above
+    //
     if( LR && (LR != RetValLR) )   {  
       LR->setCallInterference();
       if( DEBUG_RA) {
@@ -220,55 +237,72 @@ void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst,
 }
 
 
+
+
 //----------------------------------------------------------------------------
 // This method will walk thru code and create interferences in the IG of
-// each RegClass.
+// each RegClass. Also, this method calculates the spill cost of each
+// Live Range (it is done in this method to save another pass over the code).
 //----------------------------------------------------------------------------
-
 void PhyRegAlloc::buildInterferenceGraphs()
 {
 
   if(DEBUG_RA) cout << "Creating interference graphs ..." << endl;
 
+  unsigned BBLoopDepthCost;
   Method::const_iterator BBI = Meth->begin();  // random iterator for BBs   
 
   for( ; BBI != Meth->end(); ++BBI) {          // traverse BBs in random order
 
+    // find the 10^(loop_depth) of this BB 
+    //
+    BBLoopDepthCost = (unsigned) pow( 10.0, LoopDepthCalc.getLoopDepth(*BBI));
+
     // 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; 
 
       // get the LV set after the instruction
+      //
       const LiveVarSet *const LVSetAI = 
        LVI->getLiveVarSetAfterMInst(MInst, *BBI);
     
       const bool isCallInst = TM.getInstrInfo().isCall(MInst->getOpCode());
 
       if( isCallInst ) {
-       //cout << "\nFor call inst: " << *MInst;
-
        // set the isCallInterference flag of each live range wich extends
        // accross this call instruction. This information is used by graph
        // coloring algo to avoid allocating volatile colors to live ranges
        // that span across calls (since they have to be saved/restored)
+       //
        setCallInterferences( MInst,  LVSetAI);
       }
 
 
-      // iterate over  MI operands to find defs
+      // iterate over all MI operands to find defs
+      //
       for( MachineInstr::val_const_op_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
+       } 
+
+       // Calculate the spill cost of each live range
+       //
+       LiveRange *LR = LRI.getLiveRangeForValue( *OpI );
+       if( LR )
+         LR->addSpillCost(BBLoopDepthCost);
+      } 
 
 
       // if there are multiple defs in this instruction e.g. in SETX
@@ -279,7 +313,7 @@ void PhyRegAlloc::buildInterferenceGraphs()
 
       // Also add interference for any implicit definitions in a machine
       // instr (currently, only calls have this).
-
+      //
       unsigned NumOfImpRefs =  MInst->getNumImplicitRefs();
       if(  NumOfImpRefs > 0 ) {
        for(unsigned z=0; z < NumOfImpRefs; z++) 
@@ -287,11 +321,6 @@ void PhyRegAlloc::buildInterferenceGraphs()
            addInterference( MInst->getImplicitRef(z), LVSetAI, isCallInst );
       }
 
-      /*
-      // record phi instrns in PhiInstList
-      if( TM.getInstrInfo().isDummyPhiInstr(MInst->getOpCode()) )
-       PhiInstList.push_back( MInst );
-      */
 
     } // for all machine instructions in BB
     
@@ -300,24 +329,28 @@ void PhyRegAlloc::buildInterferenceGraphs()
 
   // 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
+  //  
+  addInterferencesForArgs();          
 
   if( DEBUG_RA)
     cout << "Interference graphs calculted!" << endl;
 
 }
 
+
+
 //--------------------------------------------------------------------------
 // Pseudo instructions will be exapnded to multiple instructions by the
-// assembler. Consequently, all the opernds must get distinct registers
+// assembler. Consequently, all the opernds must get distinct registers.
+// Therefore, we mark all operands of a pseudo instruction as they interfere
+// with one another.
 //--------------------------------------------------------------------------
-
 void PhyRegAlloc::addInterf4PseudoInstr(const MachineInstr *MInst) {
 
   bool setInterf = false;
 
   // iterate over  MI operands to find defs
+  //
   for( MachineInstr::val_const_op_iterator It1(MInst);!It1.done(); ++It1) {
     
     const LiveRange *const LROfOp1 = LRI.getLiveRangeForValue( *It1 ); 
@@ -325,8 +358,6 @@ void PhyRegAlloc::addInterf4PseudoInstr(const MachineInstr *MInst) {
     if( !LROfOp1 && It1.isDef() )
       assert( 0 && "No LR for Def in PSEUDO insruction");
 
-    //if( !LROfOp1 ) continue;
-
     MachineInstr::val_const_op_iterator It2 = It1;
     ++It2;
        
@@ -341,11 +372,9 @@ void PhyRegAlloc::addInterf4PseudoInstr(const MachineInstr *MInst) {
  
        if( RCOfOp1 == RCOfOp2 ){ 
          RCOfOp1->setInterference( LROfOp1, LROfOp2 );  
-         //cerr << "\nSet interfs for PSEUDO inst: " << *MInst;
          setInterf = true;
        }
 
-
       } // if Op2 has a LR
 
     } // for all other defs in machine instr
@@ -363,8 +392,6 @@ void PhyRegAlloc::addInterf4PseudoInstr(const MachineInstr *MInst) {
 
 
 
-
-
 //----------------------------------------------------------------------------
 // This method will add interferences for incoming arguments to a method.
 //----------------------------------------------------------------------------
@@ -391,12 +418,16 @@ void PhyRegAlloc::addInterferencesForArgs()
 }
 
 
+
+
 //----------------------------------------------------------------------------
 // This method is called after register allocation is complete to set the
 // allocated reisters in the machine code. This code will add register numbers
-// to MachineOperands that contain a Value.
+// to MachineOperands that contain a Value. Also it calls target specific
+// methods to produce caller saving instructions. At the end, it adds all
+// additional instructions produced by the register allocator to the 
+// instruction stream. 
 //----------------------------------------------------------------------------
-
 void PhyRegAlloc::updateMachineCode()
 {
 
@@ -405,35 +436,67 @@ void PhyRegAlloc::updateMachineCode()
   for( ; BBI != Meth->end(); ++BBI) {          // traverse BBs in random order
 
     // 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 *MInst = *MInstIterator; 
-
+      
+      unsigned Opcode =  MInst->getOpCode();
+    
       // do not process Phis
-      if( (TM.getInstrInfo()).isPhi( MInst->getOpCode()) )
+      if( (TM.getInstrInfo()).isPhi( Opcode ) )
        continue;
 
+      // Now insert speical instructions (if necessary) for call/return
+      // instructions. 
+      //
+      if( (TM.getInstrInfo()).isCall( Opcode) ||  
+         (TM.getInstrInfo()).isReturn( Opcode)  ) {
+
+       AddedInstrns *AI = AddedInstrMap[ MInst];
+       if ( !AI ) { 
+         AI = new AddedInstrns();
+         AddedInstrMap[ MInst ] = AI;
+       }
+       
+       // Tmp stack poistions are needed by some calls that have spilled args
+       // So reset it before we call each such method
+       // TODO: mcInfo.popAllTempValues(TM);  
+       
+       if( (TM.getInstrInfo()).isCall( Opcode ) )
+         MRI.colorCallArgs( MInst, LRI, AI, *this, *BBI );
+       
+       else if (  (TM.getInstrInfo()).isReturn(Opcode) ) 
+         MRI.colorRetValue( MInst, LRI, AI );
+       
+      }
+      
+
+      /* -- Using above code instead of this
 
       // if this machine instr is call, insert caller saving code
 
       if( (TM.getInstrInfo()).isCall( MInst->getOpCode()) )
        MRI.insertCallerSavingCode(MInst,  *BBI, *this );
+       
+      */
 
-
+      
       // reset the stack offset for temporary variables since we may
       // need that to spill
-      //mcInfo.popAllTempValues(TM);
+      // mcInfo.popAllTempValues(TM);
       // TODO ** : do later
       
       //for(MachineInstr::val_const_op_iterator OpI(MInst);!OpI.done();++OpI) {
 
 
       // Now replace set the registers for operands in the machine instruction
-
+      //
       for(unsigned OpNum=0; OpNum < MInst->getNumOperands(); ++OpNum) {
 
        MachineOperand& Op = MInst->getOperand(OpNum);
@@ -490,9 +553,14 @@ void PhyRegAlloc::updateMachineCode()
       } // for each operand
 
 
+      // Now add instructions that the register allocator inserts before/after 
+      // this machine instructions (done only for calls/rets/incoming args)
+      // We do this here, to ensure that spill for an instruction is inserted
+      // closest as possible to an instruction (see above insertCode4Spill...)
+      // 
       // If there are instructions to be added, *before* this machine
       // instruction, add them now.
-      
+      //      
       if( AddedInstrMap[ MInst ] ) {
 
        deque<MachineInstr *> &IBef = (AddedInstrMap[MInst])->InstrnsBefore;
@@ -518,7 +586,7 @@ void PhyRegAlloc::updateMachineCode()
 
       // If there are instructions to be added *after* this machine
       // instruction, add them now
-      
+      //
       if( AddedInstrMap[ MInst ] && 
          ! (AddedInstrMap[ MInst ]->InstrnsAfter).empty() ) {
 
@@ -600,9 +668,9 @@ void PhyRegAlloc::insertCode4SpilledLR(const LiveRange *LR,
   RegClass *RC = LR->getRegClass();
   const LiveVarSet *LVSetBef =  LVI->getLiveVarSetBeforeMInst(MInst, BB);
 
-  /**** NOTE: THIS SHOULD USE THE RIGHT SIZE FOR THE REG BEING PUSHED ****/
+
   int TmpOff = 
-    mcInfo.pushTempValue(TM, 8 /* TM.findOptimalStorageSize(LR->getType()) */);
+    mcInfo.pushTempValue(TM, MRI.getSpilledRegSize(RegType) );
   
   MachineInstr *MIBef=NULL,  *AdIMid=NULL, *MIAft=NULL;
   
@@ -696,8 +764,7 @@ int PhyRegAlloc::getUsableUniRegAtMI(RegClass *RC,
     // we couldn't find an unused register. Generate code to free up a reg by
     // saving it on stack and restoring after the instruction
 
-    /**** NOTE: THIS SHOULD USE THE RIGHT SIZE FOR THE REG BEING PUSHED ****/
-    int TmpOff = mcInfo.pushTempValue(TM, /*size*/ 8);
+    int TmpOff = mcInfo.pushTempValue(TM,  MRI.getSpilledRegSize(RegType) );
     
     RegU = getUniRegNotUsedByThisInst(RC, MInst);
     MIBef = MRI.cpReg2MemMI(RegU, MRI.getFramePointer(), TmpOff, RegType );
@@ -1003,6 +1070,8 @@ void PhyRegAlloc::printMachineCode()
 }
 
 
+#if 0
+
 //----------------------------------------------------------------------------
 //
 //----------------------------------------------------------------------------
@@ -1043,7 +1112,7 @@ void PhyRegAlloc::colorCallRetArgs()
 
 }
 
-
+#endif 
 
 //----------------------------------------------------------------------------
 
@@ -1134,8 +1203,11 @@ void PhyRegAlloc::allocateStackSpace4SpilledLRs()
        LiveRange *L = (*HMI).second;      // get the LiveRange
        if(L)
          if( ! L->hasColor() ) 
-  /**** NOTE: THIS SHOULD USE THE RIGHT SIZE FOR THE REG BEING PUSHED ****/
-           L->setSpillOffFromFP(mcInfo.allocateSpilledValue(TM, Type::LongTy /*L->getType()*/ ));
+
+           //  NOTE: ** allocating the size of long Type **
+           L->setSpillOffFromFP(mcInfo.allocateSpilledValue(TM, 
+                                Type::LongTy));
+                                                           
       }
     } // for all LR's in hash map
 }
@@ -1152,8 +1224,8 @@ void PhyRegAlloc::allocateRegisters()
   // make sure that we put all register classes into the RegClassList 
   // before we call constructLiveRanges (now done in the constructor of 
   // PhyRegAlloc class).
-
-  constructLiveRanges();                // create LR info
+  //
+  LRI.constructLiveRanges();            // create LR info
 
   if( DEBUG_RA )
     LRI.printLiveRanges();
@@ -1173,11 +1245,9 @@ void PhyRegAlloc::allocateRegisters()
       RegClassList[ rc ]->printIG();       
   }
   
+
   LRI.coalesceLRs();                    // coalesce all live ranges
   
-  // coalscing could not get rid of all phi's, add phi elimination
-  // instructions
-  // insertPhiEleminateInstrns();
 
   if( DEBUG_RA) {
     // print all LRs in all reg classes
@@ -1193,6 +1263,7 @@ void PhyRegAlloc::allocateRegisters()
   // mark un-usable suggested color before graph coloring algorithm.
   // When this is done, the graph coloring algo will not reserve
   // suggested color unnecessarily - they can be used by another LR
+  //
   markUnusableSugColors(); 
 
   // color all register classes using the graph coloring algo
@@ -1201,32 +1272,29 @@ void PhyRegAlloc::allocateRegisters()
 
   // Atter grpah coloring, if some LRs did not receive a color (i.e, spilled)
   // a poistion for such spilled LRs
+  //
   allocateStackSpace4SpilledLRs();
 
   mcInfo.popAllTempValues(TM);  // TODO **Check
 
-  // color incoming args and call args
+  // color incoming args - if the correct color was not received
+  // insert code to copy to the correct register
+  //
   colorIncomingArgs();
-  colorCallRetArgs();
 
+
+  // Now update the machine code with register names and add any 
+  // additional code inserted by the register allocator to the instruction
+  // stream
+  //
   updateMachineCode(); 
+
+
   if (DEBUG_RA) {
     MachineCodeForMethod::get(Meth).dump();
     printMachineCode();                   // only for DEBUGGING
   }
 
-
-  
-  /*
-  printMachineCode();                   // only for DEBUGGING
-
-  cout << "\nAllocted for method " <<  Meth->getName();
-  char ch;
-  cin >> ch;
-  */
-  
-
 }
 
 
index d0f1c444300169bd0c16ddd046ac6f9d577ee437..2246643594612f06ed6a1c8b6e333402118314d7 100644 (file)
@@ -1,35 +1,37 @@
 #include "llvm/CodeGen/RegClass.h"
 
 
-
+//----------------------------------------------------------------------------
+// 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)
                   :  Meth(M), MRC(Mrc), RegClassID( Mrc->getRegClassID() ),
-                     IG(this), IGNodeStack(), ReservedColorList(RCL)
-{
+                     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() ];
 }
 
 
 
+//----------------------------------------------------------------------------
+// Main entry point for coloring a register class.
+//----------------------------------------------------------------------------
 void RegClass::colorAllRegs()
 {
   if(DEBUG_RA) cout << "Coloring IG of reg class " << RegClassID << " ...\n";
 
-  //preColorIGNodes();                    // pre-color IGNodes
+                                        // pre-color IGNodes
   pushAllIGNodes();                     // push all IG Nodes
 
   unsigned int StackSize = IGNodeStack.size();    
   IGNode *CurIGNode;
 
-  // for all LRs on stack
+                                        // for all LRs on stack
   for( unsigned int IGN=0; IGN < StackSize; IGN++) {  
   
     CurIGNode = IGNodeStack.top();      // pop the IGNode on top of stack
@@ -37,13 +39,13 @@ void RegClass::colorAllRegs()
     colorIGNode (CurIGNode);            // color it
   }
 
-
-  // InsertSpillCode;  ********* TODO ********
-
 }
 
 
 
+//----------------------------------------------------------------------------
+// The method for pushing all IGNodes on to the stack.
+//----------------------------------------------------------------------------
 void RegClass::pushAllIGNodes()
 {
   bool NeedMoreSpills;          
@@ -51,7 +53,7 @@ void RegClass::pushAllIGNodes()
 
   IG.setCurDegreeOfIGNodes();           // calculate degree of IGNodes
 
-  // push non-constrained IGNodes
+                                        // push non-constrained IGNodes
   bool PushedAll  = pushUnconstrainedIGNodes(); 
 
   if( DEBUG_RA) {
@@ -71,15 +73,19 @@ void RegClass::pushAllIGNodes()
   do{
 
     //get node with min spill cost
+    //
     IGNode *IGNodeSpill =  getIGNodeWithMinSpillCost(); 
    
     //  push that node on to stack
+    //
     IGNodeStack.push( IGNodeSpill ); 
 
     // set its OnStack flag and decrement degree of neighs 
+    //
     IGNodeSpill->pushOnStack(); 
    
     // now push NON-constrined ones, if any
+    //
     NeedMoreSpills = ! pushUnconstrainedIGNodes(); 
 
     cerr << "\nConstrained IG Node found !@!" <<  IGNodeSpill->getIndex();
@@ -137,46 +143,72 @@ bool  RegClass::pushUnconstrainedIGNodes()
 
 
 
-
+//----------------------------------------------------------------------------
+// Get the IGNode withe the minimum spill cost
+//----------------------------------------------------------------------------
 IGNode * RegClass::getIGNodeWithMinSpillCost()
 {
-  IGNode *IGNode=NULL;
+
   unsigned int IGNodeListSize = IG.getIGNodeList().size(); 
+  long MinSpillCost = -1;
+  IGNode *MinCostIGNode = NULL;
+
 
-  // pass over IGNodeList
+  // pass over IGNodeList to find the IGNode with minimum spill cost
+  // among all IGNodes that are not yet pushed on to the stack
+  //
   for( unsigned int i =0; i  < IGNodeListSize; i++) {
-    IGNode = IG.getIGNodeList()[i];
+    IGNode *IGNode = IG.getIGNodeList()[i];
     
     if( ! IGNode )                      // can be null due to merging
       continue;
+
+    if( ! IGNode->isOnStack() ) {
+
+      unsigned SpillCost = IGNode->getParentLR()->getSpillCost();
     
-    // return the first IGNode ########## Change this #######
-    if( ! IGNode->isOnStack() ) return IGNode;   
+      if( MinSpillCost == -1) {         // for the first IG node
+       MinSpillCost = SpillCost;
+       MinCostIGNode = IGNode;
+      }
+
+      else if( MinSpillCost > SpillCost) {
+       MinSpillCost = SpillCost;
+       MinCostIGNode = IGNode;
+      }
+
+    }
   }
   
-  assert(0);
-  return NULL;
+  assert( MinCostIGNode && "No IGNode to spill");
+  return MinCostIGNode;
 }
 
 
 
-
+//----------------------------------------------------------------------------
+// Color the IGNode using the machine specific code.
+//----------------------------------------------------------------------------
 void RegClass::colorIGNode(IGNode *const Node)
 {
 
   if( ! Node->hasColor() )   {          // not colored as an arg etc.
    
 
-    // init all elements to  false;
+    // init all elements of to  IsColorUsedAr  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;
     }
 
+    // call the target specific code for coloring
+    //
     MRC->colorIGNode(Node, IsColorUsedArr);
   }
   else {
index d8473d2370bb765bb36c315578a6146435fd4b3c..4e66d9a762c96724ddedc7303f99a9b70d4abeba 100644 (file)
@@ -1,6 +1,9 @@
 #include "llvm/CodeGen/IGNode.h"
 
 
+//-----------------------------------------------------------------------------
+// Constructor
+//-----------------------------------------------------------------------------
 IGNode::IGNode(LiveRange *const PLR, unsigned int Ind): Index(Ind),
                                                        AdjList(),
                                                         ParentLR(PLR)
@@ -11,9 +14,11 @@ IGNode::IGNode(LiveRange *const PLR, unsigned int Ind): Index(Ind),
 }
 
 
-
-void IGNode::pushOnStack()            // sets on to stack and 
-{                                     // reduce the degree of neighbors  
+//-----------------------------------------------------------------------------
+// Sets this IGNode on stack and reduce the degree of neighbors  
+//-----------------------------------------------------------------------------
+void IGNode::pushOnStack()             
+{                                     
   OnStack = true; 
   int neighs = AdjList.size();
 
@@ -25,7 +30,10 @@ void IGNode::pushOnStack()            // sets on to stack and
   for(int i=0; i < neighs; i++)  (AdjList[i])->decCurDegree();
 }
  
-
+//-----------------------------------------------------------------------------
+// Deletes an adjacency node. IGNodes are deleted when coalescing merges
+// two IGNodes together.
+//-----------------------------------------------------------------------------
 void IGNode::delAdjIGNode(const IGNode *const Node) {
   vector <IGNode *>::iterator It = AdjList.begin();
     
index d8ec2470aaa43b4bc46a3256a83d08e009ef41df..e18c9a7a348b8d405a6d7ebaef9e4e71ed5b090e 100644 (file)
@@ -1,6 +1,10 @@
 #include "llvm/CodeGen/InterferenceGraph.h"
 
-
+//-----------------------------------------------------------------------------
+// Constructor: Records the RegClass and initalizes IGNodeList.
+// The matrix is NOT yet created by the constructor. Call createGraph() 
+// to create it after adding all IGNodes to the IGNodeList.
+//-----------------------------------------------------------------------------
 InterferenceGraph::InterferenceGraph(RegClass *const RC) : RegCl(RC), 
                                                           IGNodeList() 
 {   
@@ -11,14 +15,34 @@ InterferenceGraph::InterferenceGraph(RegClass *const RC) : RegCl(RC),
   }
 }
 
-InterferenceGraph:: ~InterferenceGraph() {                // destructor
-    if( IG )
-      delete []IG;
+
+//-----------------------------------------------------------------------------
+// destructor. Deletes the bit matrix and all IGNodes
+//-----------------------------------------------------------------------------
+InterferenceGraph:: ~InterferenceGraph() {             
+
+  // delete the matrix
+  //
+  if( IG )
+    delete []IG;
+
+  // delete all IGNodes in the IGNodeList
+  //
+  vector<IGNode *>::const_iterator IGIt = IGNodeList.begin();
+  for(unsigned i=0; i < IGNodeList.size() ; ++i) {
+
+    const IGNode *const Node = IGNodeList[i];
+    if( Node ) delete Node;
   }
 
+}
 
 
 
+//-----------------------------------------------------------------------------
+// Creates (dynamically allocates) the bit matrix necessary to hold the
+// interference graph.
+//-----------------------------------------------------------------------------
 void InterferenceGraph::createGraph()   
 { 
     Size = IGNodeList.size();
@@ -32,21 +56,24 @@ void InterferenceGraph::createGraph()
        IG[i][j] = 0;
 }
 
-
-
+//-----------------------------------------------------------------------------
+// creates a new IGNode for the given live range and add to IG
+//-----------------------------------------------------------------------------
 void InterferenceGraph::addLRToIG(LiveRange *const LR)
 {
   IGNode *Node = new IGNode(LR,  IGNodeList.size() );
   IGNodeList.push_back( Node );
-  //Node->setRegClass( RegCl );
+
 }
 
 
+//-----------------------------------------------------------------------------
+// set interference for two live ranges
 // 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);   
@@ -79,7 +106,9 @@ void InterferenceGraph::setInterference(const LiveRange *const LR1,
 }
 
 
-
+//----------------------------------------------------------------------------
+// return whether two live ranges interfere
+//----------------------------------------------------------------------------
 unsigned InterferenceGraph::getInterference(const LiveRange *const LR1,
                                           const LiveRange *const LR2 ) const {
 
@@ -100,11 +129,12 @@ unsigned InterferenceGraph::getInterference(const LiveRange *const LR1,
 }
 
 
-
+//----------------------------------------------------------------------------
 // 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 ) {
@@ -147,11 +177,6 @@ void InterferenceGraph::mergeIGNodesOfLRs(const LiveRange *const LR1,
       setInterference(LR1, LROfNeigh );  
     }
     
-    //cout<< "  #Neighs - Neigh: ["<< NeighNode->getIndex()<< "] ";
-    //cout << NeighNode->getNumOfNeighbors();
-    //cout << " Dest: [" << DestNode->getIndex() << "] ";
-    //cout << DestNode->getNumOfNeighbors()  << endl;
-
   }
 
   IGNodeList[ SrcInd ] = NULL;
@@ -162,10 +187,10 @@ void InterferenceGraph::mergeIGNodesOfLRs(const LiveRange *const LR1,
 }
 
 
-
+//----------------------------------------------------------------------------
 // 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();
@@ -183,7 +208,9 @@ void InterferenceGraph::setCurDegreeOfIGNodes()
 
 //--------------------- debugging (Printing) methods -----------------------
 
-
+//----------------------------------------------------------------------------
+// Print the IGnodes 
+//----------------------------------------------------------------------------
 void InterferenceGraph::printIG() const
 {
 
@@ -203,7 +230,9 @@ void InterferenceGraph::printIG() const
     }
 }
 
-
+//----------------------------------------------------------------------------
+// Print the IGnodes in the IGNode List
+//----------------------------------------------------------------------------
 void InterferenceGraph::printIGNodeList() const
 {
   vector<IGNode *>::const_iterator IGIt = IGNodeList.begin(); // hash map iter
index 00385d99de20cc03443fc63d343ae6f516905938..7fb688f55effee3cbf1e9295062351ebc00a662f 100644 (file)
@@ -1,5 +1,8 @@
 #include "llvm/CodeGen/LiveRangeInfo.h"
 
+//---------------------------------------------------------------------------
+// Constructor
+//---------------------------------------------------------------------------
 LiveRangeInfo::LiveRangeInfo(const Method *const M, 
                             const TargetMachine& tm,
                             vector<RegClass *> &RCL) 
@@ -10,22 +13,58 @@ LiveRangeInfo::LiveRangeInfo(const Method *const M,
 { }
 
 
+//---------------------------------------------------------------------------
+// Destructor: Deletes all LiveRanges in the LiveRangeMap
+//---------------------------------------------------------------------------
+LiveRangeInfo::~LiveRangeInfo() {
+
+  LiveRangeMapType::iterator MI =  LiveRangeMap.begin(); 
+
+  for( ; MI != LiveRangeMap.end() ; ++MI) {  
+    if( (*MI).first ) {
+      
+      LiveRange *LR = (*MI).second;
+       
+      if( LR ) {
+
+       // we need to be careful in deleting LiveRanges in LiveRangeMap
+       // since two/more Values in the live range map can point to the same
+       // live range. We have to make the other entries NULL when we delete
+       // a live range.
+
+       LiveRange::iterator LI = LR->begin();
+       
+       for( ; LI != LR->end() ; ++LI) { 
+         LiveRangeMap[*LI] = NULL;
+       }
+
+       delete LR;
+
+      }
+    }
+  }
+
+}
+
+
+//---------------------------------------------------------------------------
 // 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 and both
 // LRs don't have suggested colors
-
+//---------------------------------------------------------------------------
 void LiveRangeInfo::unionAndUpdateLRs(LiveRange *const L1, LiveRange *L2)
 {
   assert( L1 != L2);
-  L1->setUnion( L2 );             // add elements of L2 to L1
+  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    
+    L1->add( *L2It );                   // add the var in L2 to L1
+    LiveRangeMap[ *L2It ] = L1;         // now the elements in L2 should map 
+                                        //to L1    
   }
 
 
@@ -40,13 +79,19 @@ void LiveRangeInfo::unionAndUpdateLRs(LiveRange *const L1, LiveRange *L2)
   if( L2->isCallInterference() )
     L1->setCallInterference();
   
+  L1->addSpillCost( L2->getSpillCost() ); // add the spill costs
 
-  delete ( L2 );                 // delete L2 as it is no longer needed
+  delete ( L2 );                        // delete L2 as it is no longer needed
 }
 
 
 
-                                 
+//---------------------------------------------------------------------------
+// Method for constructing all live ranges in a method. It creates live 
+// ranges for all values defined in the instruction stream. Also, it
+// creates live ranges for all incoming arguments of the method.
+//---------------------------------------------------------------------------
 void LiveRangeInfo::constructLiveRanges()
 {  
 
@@ -216,10 +261,14 @@ void LiveRangeInfo::constructLiveRanges()
 }
 
 
-
-// Suggest colors for call and return args. 
-// Also create new LRs for implicit defs
-
+//---------------------------------------------------------------------------
+// If some live ranges must be colored with specific hardware registers
+// (e.g., for outgoing call args), suggesting of colors for such live
+// ranges is done using target specific method. Those methods are called
+// from this function. The target specific methods must:
+//    1) suggest colors for call and return args. 
+//    2) create new LRs for implicit defs in machine instructions
+//---------------------------------------------------------------------------
 void LiveRangeInfo::suggestRegs4CallRets()
 {
 
@@ -243,11 +292,11 @@ void LiveRangeInfo::suggestRegs4CallRets()
 }
 
 
+//--------------------------------------------------------------------------
+// The following method coalesces live ranges when possible. This method
+// must be called after the interference graph has been constructed.
 
 
-void LiveRangeInfo::coalesceLRs()  
-{
-
 /* Algorithm:
    for each BB in method
      for each machine instruction (inst)
@@ -260,6 +309,11 @@ void LiveRangeInfo::coalesceLRs()
                    merge2IGNodes(def, op) // i.e., merge 2 LRs 
 
 */
+//---------------------------------------------------------------------------
+void LiveRangeInfo::coalesceLRs()  
+{
+
+
 
   if( DEBUG_RA) 
     cout << endl << "Coalscing LRs ..." << endl;
index 240e8c1c2a98b68982cf92297e63d12200e3d771..dc1c8690ee6977bab9e5a70e455b4613683739c0 100644 (file)
@@ -14,6 +14,7 @@
 #include "llvm/CodeGen/MachineInstr.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/MachineFrameInfo.h"
+#include <math.h>
 
 
 // ***TODO: There are several places we add instructions. Validate the order
@@ -41,22 +42,31 @@ PhyRegAlloc::PhyRegAlloc(Method *M,
                           LVI(Lvi), LRI(M, tm, RegClassList), 
                          MRI( tm.getRegInfo() ),
                           NumOfRegClasses(MRI.getNumOfRegClasses()),
-                         AddedInstrMap()
-                    
-{
-  // **TODO: use an actual reserved color list 
-  ReservedColorListType *RCL = new ReservedColorListType();
+                         AddedInstrMap(), LoopDepthCalc(M), ResColList() {
 
   // 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) );
+    RegClassList.push_back( new RegClass(M, MRI.getMachineRegClass(rc), 
+                                        &ResColList) );
 }
 
+
+//----------------------------------------------------------------------------
+// Destructor: Deletes register classes
+//----------------------------------------------------------------------------
+PhyRegAlloc::~PhyRegAlloc() { 
+
+  for( unsigned int rc=0; rc < NumOfRegClasses; rc++) { 
+    RegClass *RC = RegClassList[rc];
+    delete RC;
+  }
+} 
+
 //----------------------------------------------------------------------------
 // This method initally creates interference graphs (one in each reg class)
 // and IGNodeList (one in each IG). The actual nodes will be pushed later. 
 //----------------------------------------------------------------------------
-
 void PhyRegAlloc::createIGNodeListsAndIGs()
 {
   if(DEBUG_RA ) cout << "Creating LR lists ..." << endl;
@@ -71,7 +81,7 @@ void PhyRegAlloc::createIGNodeListsAndIGs()
       
       if( (*HMI).first ) { 
 
-       LiveRange *L = (*HMI).second;      // get the LiveRange
+       LiveRange *L = (*HMI).second;   // get the LiveRange
 
        if( !L) { 
          if( DEBUG_RA) {
@@ -103,13 +113,13 @@ void PhyRegAlloc::createIGNodeListsAndIGs()
 
 
 
+
 //----------------------------------------------------------------------------
 // This method will add all interferences at for a given instruction.
 // 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) {
@@ -117,6 +127,7 @@ void PhyRegAlloc::addInterference(const Value *const Def,
   LiveVarSet::const_iterator LIt = LVSet->begin();
 
   // get the live range of instruction
+  //
   const LiveRange *const LROfDef = LRI.getLiveRangeForValue( Def );   
 
   IGNode *const IGNodeOfDef = LROfDef->getUserIGNode();
@@ -125,6 +136,7 @@ void PhyRegAlloc::addInterference(const Value *const Def,
   RegClass *const RCOfDef = LROfDef->getRegClass(); 
 
   // for each live var in live variable set
+  //
   for( ; LIt != LVSet->end(); ++LIt) {
 
     if( DEBUG_RA > 1) {
@@ -133,16 +145,19 @@ void PhyRegAlloc::addInterference(const Value *const Def,
     }
 
     //  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);  
 
@@ -161,6 +176,8 @@ void PhyRegAlloc::addInterference(const Value *const Def,
 }
 
 
+
+
 //----------------------------------------------------------------------------
 // For a call instruction, this method sets the CallInterference flag in 
 // the LR of each variable live int the Live Variable Set live after the
@@ -169,18 +186,15 @@ void PhyRegAlloc::addInterference(const Value *const Def,
 //----------------------------------------------------------------------------
 
 void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst, 
-                                      const LiveVarSet *const LVSetAft ) 
-{
-  // Now find the LR of the return value of the call
-
+                                      const LiveVarSet *const LVSetAft ) {
 
+  // Now find the LR of the return value of the call
   // We do this because, we look at the LV set *after* the instruction
   // to determine, which LRs must be saved across calls. The return value
   // of the call is live in this set - but it does not interfere with call
   // (i.e., we can allocate a volatile register to the return value)
-
+  //
   LiveRange *RetValLR = NULL;
-
   const Value *RetVal = MRI.getCallInstRetVal( MInst );
 
   if( RetVal ) {
@@ -194,9 +208,11 @@ void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst,
   LiveVarSet::const_iterator LIt = LVSetAft->begin();
 
   // for each live var in live variable set after machine inst
+  //
   for( ; LIt != LVSetAft->end(); ++LIt) {
 
-   //  get the live range corresponding to live var
+    //  get the live range corresponding to live var
+    //
     LiveRange *const LR = LRI.getLiveRangeForValue(*LIt ); 
 
     if( LR && DEBUG_RA) {
@@ -207,6 +223,7 @@ void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst,
 
     // LR can be null if it is a const since a const 
     // doesn't have a dominating def - see Assumptions above
+    //
     if( LR && (LR != RetValLR) )   {  
       LR->setCallInterference();
       if( DEBUG_RA) {
@@ -220,55 +237,72 @@ void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst,
 }
 
 
+
+
 //----------------------------------------------------------------------------
 // This method will walk thru code and create interferences in the IG of
-// each RegClass.
+// each RegClass. Also, this method calculates the spill cost of each
+// Live Range (it is done in this method to save another pass over the code).
 //----------------------------------------------------------------------------
-
 void PhyRegAlloc::buildInterferenceGraphs()
 {
 
   if(DEBUG_RA) cout << "Creating interference graphs ..." << endl;
 
+  unsigned BBLoopDepthCost;
   Method::const_iterator BBI = Meth->begin();  // random iterator for BBs   
 
   for( ; BBI != Meth->end(); ++BBI) {          // traverse BBs in random order
 
+    // find the 10^(loop_depth) of this BB 
+    //
+    BBLoopDepthCost = (unsigned) pow( 10.0, LoopDepthCalc.getLoopDepth(*BBI));
+
     // 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; 
 
       // get the LV set after the instruction
+      //
       const LiveVarSet *const LVSetAI = 
        LVI->getLiveVarSetAfterMInst(MInst, *BBI);
     
       const bool isCallInst = TM.getInstrInfo().isCall(MInst->getOpCode());
 
       if( isCallInst ) {
-       //cout << "\nFor call inst: " << *MInst;
-
        // set the isCallInterference flag of each live range wich extends
        // accross this call instruction. This information is used by graph
        // coloring algo to avoid allocating volatile colors to live ranges
        // that span across calls (since they have to be saved/restored)
+       //
        setCallInterferences( MInst,  LVSetAI);
       }
 
 
-      // iterate over  MI operands to find defs
+      // iterate over all MI operands to find defs
+      //
       for( MachineInstr::val_const_op_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
+       } 
+
+       // Calculate the spill cost of each live range
+       //
+       LiveRange *LR = LRI.getLiveRangeForValue( *OpI );
+       if( LR )
+         LR->addSpillCost(BBLoopDepthCost);
+      } 
 
 
       // if there are multiple defs in this instruction e.g. in SETX
@@ -279,7 +313,7 @@ void PhyRegAlloc::buildInterferenceGraphs()
 
       // Also add interference for any implicit definitions in a machine
       // instr (currently, only calls have this).
-
+      //
       unsigned NumOfImpRefs =  MInst->getNumImplicitRefs();
       if(  NumOfImpRefs > 0 ) {
        for(unsigned z=0; z < NumOfImpRefs; z++) 
@@ -287,11 +321,6 @@ void PhyRegAlloc::buildInterferenceGraphs()
            addInterference( MInst->getImplicitRef(z), LVSetAI, isCallInst );
       }
 
-      /*
-      // record phi instrns in PhiInstList
-      if( TM.getInstrInfo().isDummyPhiInstr(MInst->getOpCode()) )
-       PhiInstList.push_back( MInst );
-      */
 
     } // for all machine instructions in BB
     
@@ -300,24 +329,28 @@ void PhyRegAlloc::buildInterferenceGraphs()
 
   // 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
+  //  
+  addInterferencesForArgs();          
 
   if( DEBUG_RA)
     cout << "Interference graphs calculted!" << endl;
 
 }
 
+
+
 //--------------------------------------------------------------------------
 // Pseudo instructions will be exapnded to multiple instructions by the
-// assembler. Consequently, all the opernds must get distinct registers
+// assembler. Consequently, all the opernds must get distinct registers.
+// Therefore, we mark all operands of a pseudo instruction as they interfere
+// with one another.
 //--------------------------------------------------------------------------
-
 void PhyRegAlloc::addInterf4PseudoInstr(const MachineInstr *MInst) {
 
   bool setInterf = false;
 
   // iterate over  MI operands to find defs
+  //
   for( MachineInstr::val_const_op_iterator It1(MInst);!It1.done(); ++It1) {
     
     const LiveRange *const LROfOp1 = LRI.getLiveRangeForValue( *It1 ); 
@@ -325,8 +358,6 @@ void PhyRegAlloc::addInterf4PseudoInstr(const MachineInstr *MInst) {
     if( !LROfOp1 && It1.isDef() )
       assert( 0 && "No LR for Def in PSEUDO insruction");
 
-    //if( !LROfOp1 ) continue;
-
     MachineInstr::val_const_op_iterator It2 = It1;
     ++It2;
        
@@ -341,11 +372,9 @@ void PhyRegAlloc::addInterf4PseudoInstr(const MachineInstr *MInst) {
  
        if( RCOfOp1 == RCOfOp2 ){ 
          RCOfOp1->setInterference( LROfOp1, LROfOp2 );  
-         //cerr << "\nSet interfs for PSEUDO inst: " << *MInst;
          setInterf = true;
        }
 
-
       } // if Op2 has a LR
 
     } // for all other defs in machine instr
@@ -363,8 +392,6 @@ void PhyRegAlloc::addInterf4PseudoInstr(const MachineInstr *MInst) {
 
 
 
-
-
 //----------------------------------------------------------------------------
 // This method will add interferences for incoming arguments to a method.
 //----------------------------------------------------------------------------
@@ -391,12 +418,16 @@ void PhyRegAlloc::addInterferencesForArgs()
 }
 
 
+
+
 //----------------------------------------------------------------------------
 // This method is called after register allocation is complete to set the
 // allocated reisters in the machine code. This code will add register numbers
-// to MachineOperands that contain a Value.
+// to MachineOperands that contain a Value. Also it calls target specific
+// methods to produce caller saving instructions. At the end, it adds all
+// additional instructions produced by the register allocator to the 
+// instruction stream. 
 //----------------------------------------------------------------------------
-
 void PhyRegAlloc::updateMachineCode()
 {
 
@@ -405,35 +436,67 @@ void PhyRegAlloc::updateMachineCode()
   for( ; BBI != Meth->end(); ++BBI) {          // traverse BBs in random order
 
     // 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 *MInst = *MInstIterator; 
-
+      
+      unsigned Opcode =  MInst->getOpCode();
+    
       // do not process Phis
-      if( (TM.getInstrInfo()).isPhi( MInst->getOpCode()) )
+      if( (TM.getInstrInfo()).isPhi( Opcode ) )
        continue;
 
+      // Now insert speical instructions (if necessary) for call/return
+      // instructions. 
+      //
+      if( (TM.getInstrInfo()).isCall( Opcode) ||  
+         (TM.getInstrInfo()).isReturn( Opcode)  ) {
+
+       AddedInstrns *AI = AddedInstrMap[ MInst];
+       if ( !AI ) { 
+         AI = new AddedInstrns();
+         AddedInstrMap[ MInst ] = AI;
+       }
+       
+       // Tmp stack poistions are needed by some calls that have spilled args
+       // So reset it before we call each such method
+       // TODO: mcInfo.popAllTempValues(TM);  
+       
+       if( (TM.getInstrInfo()).isCall( Opcode ) )
+         MRI.colorCallArgs( MInst, LRI, AI, *this, *BBI );
+       
+       else if (  (TM.getInstrInfo()).isReturn(Opcode) ) 
+         MRI.colorRetValue( MInst, LRI, AI );
+       
+      }
+      
+
+      /* -- Using above code instead of this
 
       // if this machine instr is call, insert caller saving code
 
       if( (TM.getInstrInfo()).isCall( MInst->getOpCode()) )
        MRI.insertCallerSavingCode(MInst,  *BBI, *this );
+       
+      */
 
-
+      
       // reset the stack offset for temporary variables since we may
       // need that to spill
-      //mcInfo.popAllTempValues(TM);
+      // mcInfo.popAllTempValues(TM);
       // TODO ** : do later
       
       //for(MachineInstr::val_const_op_iterator OpI(MInst);!OpI.done();++OpI) {
 
 
       // Now replace set the registers for operands in the machine instruction
-
+      //
       for(unsigned OpNum=0; OpNum < MInst->getNumOperands(); ++OpNum) {
 
        MachineOperand& Op = MInst->getOperand(OpNum);
@@ -490,9 +553,14 @@ void PhyRegAlloc::updateMachineCode()
       } // for each operand
 
 
+      // Now add instructions that the register allocator inserts before/after 
+      // this machine instructions (done only for calls/rets/incoming args)
+      // We do this here, to ensure that spill for an instruction is inserted
+      // closest as possible to an instruction (see above insertCode4Spill...)
+      // 
       // If there are instructions to be added, *before* this machine
       // instruction, add them now.
-      
+      //      
       if( AddedInstrMap[ MInst ] ) {
 
        deque<MachineInstr *> &IBef = (AddedInstrMap[MInst])->InstrnsBefore;
@@ -518,7 +586,7 @@ void PhyRegAlloc::updateMachineCode()
 
       // If there are instructions to be added *after* this machine
       // instruction, add them now
-      
+      //
       if( AddedInstrMap[ MInst ] && 
          ! (AddedInstrMap[ MInst ]->InstrnsAfter).empty() ) {
 
@@ -600,9 +668,9 @@ void PhyRegAlloc::insertCode4SpilledLR(const LiveRange *LR,
   RegClass *RC = LR->getRegClass();
   const LiveVarSet *LVSetBef =  LVI->getLiveVarSetBeforeMInst(MInst, BB);
 
-  /**** NOTE: THIS SHOULD USE THE RIGHT SIZE FOR THE REG BEING PUSHED ****/
+
   int TmpOff = 
-    mcInfo.pushTempValue(TM, 8 /* TM.findOptimalStorageSize(LR->getType()) */);
+    mcInfo.pushTempValue(TM, MRI.getSpilledRegSize(RegType) );
   
   MachineInstr *MIBef=NULL,  *AdIMid=NULL, *MIAft=NULL;
   
@@ -696,8 +764,7 @@ int PhyRegAlloc::getUsableUniRegAtMI(RegClass *RC,
     // we couldn't find an unused register. Generate code to free up a reg by
     // saving it on stack and restoring after the instruction
 
-    /**** NOTE: THIS SHOULD USE THE RIGHT SIZE FOR THE REG BEING PUSHED ****/
-    int TmpOff = mcInfo.pushTempValue(TM, /*size*/ 8);
+    int TmpOff = mcInfo.pushTempValue(TM,  MRI.getSpilledRegSize(RegType) );
     
     RegU = getUniRegNotUsedByThisInst(RC, MInst);
     MIBef = MRI.cpReg2MemMI(RegU, MRI.getFramePointer(), TmpOff, RegType );
@@ -1003,6 +1070,8 @@ void PhyRegAlloc::printMachineCode()
 }
 
 
+#if 0
+
 //----------------------------------------------------------------------------
 //
 //----------------------------------------------------------------------------
@@ -1043,7 +1112,7 @@ void PhyRegAlloc::colorCallRetArgs()
 
 }
 
-
+#endif 
 
 //----------------------------------------------------------------------------
 
@@ -1134,8 +1203,11 @@ void PhyRegAlloc::allocateStackSpace4SpilledLRs()
        LiveRange *L = (*HMI).second;      // get the LiveRange
        if(L)
          if( ! L->hasColor() ) 
-  /**** NOTE: THIS SHOULD USE THE RIGHT SIZE FOR THE REG BEING PUSHED ****/
-           L->setSpillOffFromFP(mcInfo.allocateSpilledValue(TM, Type::LongTy /*L->getType()*/ ));
+
+           //  NOTE: ** allocating the size of long Type **
+           L->setSpillOffFromFP(mcInfo.allocateSpilledValue(TM, 
+                                Type::LongTy));
+                                                           
       }
     } // for all LR's in hash map
 }
@@ -1152,8 +1224,8 @@ void PhyRegAlloc::allocateRegisters()
   // make sure that we put all register classes into the RegClassList 
   // before we call constructLiveRanges (now done in the constructor of 
   // PhyRegAlloc class).
-
-  constructLiveRanges();                // create LR info
+  //
+  LRI.constructLiveRanges();            // create LR info
 
   if( DEBUG_RA )
     LRI.printLiveRanges();
@@ -1173,11 +1245,9 @@ void PhyRegAlloc::allocateRegisters()
       RegClassList[ rc ]->printIG();       
   }
   
+
   LRI.coalesceLRs();                    // coalesce all live ranges
   
-  // coalscing could not get rid of all phi's, add phi elimination
-  // instructions
-  // insertPhiEleminateInstrns();
 
   if( DEBUG_RA) {
     // print all LRs in all reg classes
@@ -1193,6 +1263,7 @@ void PhyRegAlloc::allocateRegisters()
   // mark un-usable suggested color before graph coloring algorithm.
   // When this is done, the graph coloring algo will not reserve
   // suggested color unnecessarily - they can be used by another LR
+  //
   markUnusableSugColors(); 
 
   // color all register classes using the graph coloring algo
@@ -1201,32 +1272,29 @@ void PhyRegAlloc::allocateRegisters()
 
   // Atter grpah coloring, if some LRs did not receive a color (i.e, spilled)
   // a poistion for such spilled LRs
+  //
   allocateStackSpace4SpilledLRs();
 
   mcInfo.popAllTempValues(TM);  // TODO **Check
 
-  // color incoming args and call args
+  // color incoming args - if the correct color was not received
+  // insert code to copy to the correct register
+  //
   colorIncomingArgs();
-  colorCallRetArgs();
 
+
+  // Now update the machine code with register names and add any 
+  // additional code inserted by the register allocator to the instruction
+  // stream
+  //
   updateMachineCode(); 
+
+
   if (DEBUG_RA) {
     MachineCodeForMethod::get(Meth).dump();
     printMachineCode();                   // only for DEBUGGING
   }
 
-
-  
-  /*
-  printMachineCode();                   // only for DEBUGGING
-
-  cout << "\nAllocted for method " <<  Meth->getName();
-  char ch;
-  cin >> ch;
-  */
-  
-
 }
 
 
index d0f1c444300169bd0c16ddd046ac6f9d577ee437..2246643594612f06ed6a1c8b6e333402118314d7 100644 (file)
@@ -1,35 +1,37 @@
 #include "llvm/CodeGen/RegClass.h"
 
 
-
+//----------------------------------------------------------------------------
+// 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)
                   :  Meth(M), MRC(Mrc), RegClassID( Mrc->getRegClassID() ),
-                     IG(this), IGNodeStack(), ReservedColorList(RCL)
-{
+                     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() ];
 }
 
 
 
+//----------------------------------------------------------------------------
+// Main entry point for coloring a register class.
+//----------------------------------------------------------------------------
 void RegClass::colorAllRegs()
 {
   if(DEBUG_RA) cout << "Coloring IG of reg class " << RegClassID << " ...\n";
 
-  //preColorIGNodes();                    // pre-color IGNodes
+                                        // pre-color IGNodes
   pushAllIGNodes();                     // push all IG Nodes
 
   unsigned int StackSize = IGNodeStack.size();    
   IGNode *CurIGNode;
 
-  // for all LRs on stack
+                                        // for all LRs on stack
   for( unsigned int IGN=0; IGN < StackSize; IGN++) {  
   
     CurIGNode = IGNodeStack.top();      // pop the IGNode on top of stack
@@ -37,13 +39,13 @@ void RegClass::colorAllRegs()
     colorIGNode (CurIGNode);            // color it
   }
 
-
-  // InsertSpillCode;  ********* TODO ********
-
 }
 
 
 
+//----------------------------------------------------------------------------
+// The method for pushing all IGNodes on to the stack.
+//----------------------------------------------------------------------------
 void RegClass::pushAllIGNodes()
 {
   bool NeedMoreSpills;          
@@ -51,7 +53,7 @@ void RegClass::pushAllIGNodes()
 
   IG.setCurDegreeOfIGNodes();           // calculate degree of IGNodes
 
-  // push non-constrained IGNodes
+                                        // push non-constrained IGNodes
   bool PushedAll  = pushUnconstrainedIGNodes(); 
 
   if( DEBUG_RA) {
@@ -71,15 +73,19 @@ void RegClass::pushAllIGNodes()
   do{
 
     //get node with min spill cost
+    //
     IGNode *IGNodeSpill =  getIGNodeWithMinSpillCost(); 
    
     //  push that node on to stack
+    //
     IGNodeStack.push( IGNodeSpill ); 
 
     // set its OnStack flag and decrement degree of neighs 
+    //
     IGNodeSpill->pushOnStack(); 
    
     // now push NON-constrined ones, if any
+    //
     NeedMoreSpills = ! pushUnconstrainedIGNodes(); 
 
     cerr << "\nConstrained IG Node found !@!" <<  IGNodeSpill->getIndex();
@@ -137,46 +143,72 @@ bool  RegClass::pushUnconstrainedIGNodes()
 
 
 
-
+//----------------------------------------------------------------------------
+// Get the IGNode withe the minimum spill cost
+//----------------------------------------------------------------------------
 IGNode * RegClass::getIGNodeWithMinSpillCost()
 {
-  IGNode *IGNode=NULL;
+
   unsigned int IGNodeListSize = IG.getIGNodeList().size(); 
+  long MinSpillCost = -1;
+  IGNode *MinCostIGNode = NULL;
+
 
-  // pass over IGNodeList
+  // pass over IGNodeList to find the IGNode with minimum spill cost
+  // among all IGNodes that are not yet pushed on to the stack
+  //
   for( unsigned int i =0; i  < IGNodeListSize; i++) {
-    IGNode = IG.getIGNodeList()[i];
+    IGNode *IGNode = IG.getIGNodeList()[i];
     
     if( ! IGNode )                      // can be null due to merging
       continue;
+
+    if( ! IGNode->isOnStack() ) {
+
+      unsigned SpillCost = IGNode->getParentLR()->getSpillCost();
     
-    // return the first IGNode ########## Change this #######
-    if( ! IGNode->isOnStack() ) return IGNode;   
+      if( MinSpillCost == -1) {         // for the first IG node
+       MinSpillCost = SpillCost;
+       MinCostIGNode = IGNode;
+      }
+
+      else if( MinSpillCost > SpillCost) {
+       MinSpillCost = SpillCost;
+       MinCostIGNode = IGNode;
+      }
+
+    }
   }
   
-  assert(0);
-  return NULL;
+  assert( MinCostIGNode && "No IGNode to spill");
+  return MinCostIGNode;
 }
 
 
 
-
+//----------------------------------------------------------------------------
+// Color the IGNode using the machine specific code.
+//----------------------------------------------------------------------------
 void RegClass::colorIGNode(IGNode *const Node)
 {
 
   if( ! Node->hasColor() )   {          // not colored as an arg etc.
    
 
-    // init all elements to  false;
+    // init all elements of to  IsColorUsedAr  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;
     }
 
+    // call the target specific code for coloring
+    //
     MRC->colorIGNode(Node, IsColorUsedArr);
   }
   else {