Added comments and correct logic for finding register sizes.
authorRuchira Sasanka <sasanka@students.uiuc.edu>
Mon, 7 Jan 2002 19:20:28 +0000 (19:20 +0000)
committerRuchira Sasanka <sasanka@students.uiuc.edu>
Mon, 7 Jan 2002 19:20:28 +0000 (19:20 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1494 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/SparcV9/SparcV9Internals.h
lib/Target/SparcV9/SparcV9RegClassInfo.cpp
lib/Target/SparcV9/SparcV9RegInfo.cpp
lib/Target/SparcV9/SparcV9TargetMachine.cpp

index c24b9bd3841975ea08f08402b289f230236568ed..45aa029e877418a9c041dc088ed8af1cb6da7c26 100644 (file)
@@ -180,7 +180,6 @@ class PhyRegAlloc;
 
 class UltraSparcRegInfo : public MachineRegInfo
 {
-
  private:
 
   // The actual register classes in the Sparc
@@ -336,20 +335,21 @@ class UltraSparcRegInfo : public MachineRegInfo
 
 
 
-
+  bool isVarArgCall(const MachineInstr *CallMI) const;
 
 
 
  public:
 
 
-  UltraSparcRegInfo(const TargetMachine& tgt ) :    MachineRegInfo(tgt),
-                                                    UltraSparcInfo(& (const UltraSparc&) tgt), 
-                                                   NumOfIntArgRegs(6), 
-                                                   NumOfFloatArgRegs(32),
-                                                   InvalidRegNum(1000),
-                                                   SizeOfOperandOnStack(8)
-  {    
+  UltraSparcRegInfo(const TargetMachine& tgt ) :    
+    MachineRegInfo(tgt),
+    UltraSparcInfo(& (const UltraSparc&) tgt), 
+    NumOfIntArgRegs(6), 
+    NumOfFloatArgRegs(32),
+    InvalidRegNum(1000),
+    SizeOfOperandOnStack(8) {
+   
     MachineRegClassArr.push_back( new SparcIntRegClass(IntRegClassID) );
     MachineRegClassArr.push_back( new SparcFloatRegClass(FloatRegClassID) );
     MachineRegClassArr.push_back( new SparcIntCCRegClass(IntCCRegClassID) );
@@ -421,7 +421,8 @@ class UltraSparcRegInfo : public MachineRegInfo
                       AddedInstrns *const FirstAI) const;
 
   void colorCallArgs(const MachineInstr *const CallMI, LiveRangeInfo& LRI,
-                    AddedInstrns *const CallAI,  PhyRegAlloc &PRA) const;
+                    AddedInstrns *const CallAI,  PhyRegAlloc &PRA,
+                    const BasicBlock *BB) const;
 
   void colorRetValue(const MachineInstr *const RetI,   LiveRangeInfo& LRI,
                     AddedInstrns *const RetAI) const;
@@ -478,6 +479,14 @@ class UltraSparcRegInfo : public MachineRegInfo
     return (reg != InvalidRegNum && reg < 32);
   }
   
+
+
+  inline int getSpilledRegSize(const int RegType) const {
+    return 8;
+    //
+    // for Sparc, we allocate 8 bytes on stack for all register types
+  }
+
   const Value * getCallInstRetVal(const MachineInstr *CallMI) const;
 
   MachineInstr * cpReg2RegMI(const unsigned SrcReg, const unsigned DestReg,
index f79dd5817bbf8343fb6b2208b0f5ac9ec23015ac..6b39d61f5e1df284346d03b110d74dc4557c9f9d 100644 (file)
@@ -4,23 +4,20 @@
 #include "llvm/Target/Sparc.h"
 
 //-----------------------------------------------------------------------------
-// Int Register Class
+// Int Register Class - method for coloring a node in the interference graph.
+//
+// Algorithm:
+//     Record the colors/suggested colors of all neighbors.
+//
+//     If there is a suggested color, try to allocate it
+//     If there is no call interf, try to allocate volatile, then non volatile
+//     If there is call interf, try to allocate non-volatile. If that fails
+//     try to allocate a volatile and insert save across calls
+//     If both above fail, spill.
+//  
 //-----------------------------------------------------------------------------
-
 void SparcIntRegClass::colorIGNode(IGNode * Node, bool IsColorUsedArr[]) const 
 {
-
-  /* Algorithm:
-     Record the colors/suggested colors of all neighbors.
-
-     If there is a suggested color, try to allocate it
-     If there is no call interf, try to allocate volatile, then non volatile
-     If there is call interf, try to allocate non-volatile. If that fails
-     try to allocate a volatile and insert save across calls
-     If both above fail, spill.
-
-  */
-
   LiveRange * LR = Node->getParentLR();
   unsigned NumNeighbors =  Node->getNumOfNeighbors();   // total # of neighbors
 
@@ -37,7 +34,6 @@ void SparcIntRegClass::colorIGNode(IGNode * Node, bool IsColorUsedArr[]) const
        if( NeighLR-> isSuggestedColorUsable() ) 
          IsColorUsedArr[ NeighLR->getSuggestedColor() ] = true; 
     }    
-
   }
 
   if( DEBUG_RA ) {
@@ -49,8 +45,6 @@ void SparcIntRegClass::colorIGNode(IGNode * Node, bool IsColorUsedArr[]) const
 
     unsigned SugCol = LR->getSuggestedColor();
 
-    // cout << "\n  -Has sug color: " << SugCol;
-
     if( ! IsColorUsedArr[ SugCol ] ) {
 
       if( LR->isSuggestedColorUsable()  ) {
@@ -102,6 +96,7 @@ void SparcIntRegClass::colorIGNode(IGNode * Node, bool IsColorUsedArr[]) const
 
   // if color is not found because of call interference
   // try even finding a volatile color and insert save across calls
+  //
   else if( LR->isCallInterference() ) 
   { 
     // start from 0 - try to find even a volatile this time
@@ -116,16 +111,16 @@ void SparcIntRegClass::colorIGNode(IGNode * Node, bool IsColorUsedArr[]) const
        LR->setColor(c);  
        //  get the live range corresponding to live var
        // since LR span across calls, must save across calls 
+       //
        LR->markForSaveAcrossCalls();       
-
        if(DEBUG_RA) cout << "\n  Colored after SECOND search with col " << c ;
     }
-
   }
 
 
   // If we couldn't find a color regardless of call interference - i.e., we
   // don't have either a volatile or non-volatile color left
+  //
   if( !ColorFound )  
     LR->markForSpill();               // no color found - must spill
 
@@ -141,61 +136,23 @@ void SparcIntRegClass::colorIGNode(IGNode * Node, bool IsColorUsedArr[]) const
 
 
 //-----------------------------------------------------------------------------
-// Float Register Class
-//-----------------------------------------------------------------------------
-
-// find the first available color in the range [Start,End] depending on the
-// type of the Node (i.e., float/double)
-
-int SparcFloatRegClass::findFloatColor(const LiveRange *const LR, 
-                                      unsigned Start,
-                                      unsigned End, 
-                                      bool IsColorUsedArr[] ) const
-{
-
-  bool ColorFound = false;
-  unsigned c;
-
-  if( LR->getTypeID() == Type::DoubleTyID ) { 
-      
-    // find first unused color for a double 
-    for( c=Start; c < End ;c+= 2){
-      if( ! IsColorUsedArr[ c ] &&  ! IsColorUsedArr[ c+1 ]) 
-       { ColorFound=true;  break; }
-    }
-    
-  } else {
-    
-    // find first unused color for a single
-    for( c=Start; c < End; c++) { 
-      if( ! IsColorUsedArr[ c ] ) { ColorFound=true;  break; }
-    }
-  }
-  
-  if( ColorFound ) return c;
-  else return -1;
-}
-
-
-
-
-
+// Float Register Class - method for coloring a node in the interference graph.
+//
+// Algorithm:
+//
+//     If the LR is a double try to allocate f32 - f63
+//     If the above fails or LR is single precision
+//        If the LR does not interfere with a call
+//        start allocating from f0
+//     Else start allocating from f6
+//     If a color is still not found because LR interferes with a call
+//        Search in f0 - f6. If found mark for spill across calls.
+//     If a color is still not fond, mark for spilling
+//
+//----------------------------------------------------------------------------
 void SparcFloatRegClass::colorIGNode(IGNode * Node,bool IsColorUsedArr[]) const
 {
 
-  /* Algorithm:
-
-     If the LR is a double try to allocate f32 - f63
-     If the above fails or LR is single precision
-        If the LR does not interfere with a call
-          start allocating from f0
-       Else start allocating from f6
-     If a color is still not found because LR interferes with a call
-        Search in f0 - f6. If found mark for spill across calls.
-     If a color is still not fond, mark for spilling
-  */
-
-
   LiveRange * LR = Node->getParentLR();
   unsigned NumNeighbors =  Node->getNumOfNeighbors();   // total # of neighbors
 
@@ -245,17 +202,24 @@ void SparcFloatRegClass::colorIGNode(IGNode * Node,bool IsColorUsedArr[]) const
   bool isCallInterf = LR->isCallInterference();
 
   // if value is a double - search the double only reigon (f32 - f63)
+  // i.e. we try to allocate f32 - f63 first for doubles since singles
+  // cannot go there. By doing that, we provide more space for singles
+  // in f0 - f31
+  //
   if( LR->getTypeID() == Type::DoubleTyID )       
     ColorFound = findFloatColor( LR, 32, 64, IsColorUsedArr );
     
 
-  if( ColorFound >= 0 ) {
+  if( ColorFound >= 0 ) {               // if we could find a color
     LR->setColor(ColorFound);                
     if( DEBUG_RA) UltraSparcRegInfo::printReg( LR );
     return;
   }
+  else { 
 
-  else { // the above fails or LR is single precision
+    // if we didn't find a color becuase the LR was single precision or
+    // all f32-f63 range is filled, we try to allocate a register from
+    // the f0 - f31 region 
 
     unsigned SearchStart;                 // start pos of color in pref-order
 
@@ -270,16 +234,15 @@ void SparcFloatRegClass::colorIGNode(IGNode * Node,bool IsColorUsedArr[]) const
     }
     
     ColorFound = findFloatColor( LR, SearchStart, 32, IsColorUsedArr );
-
   }
 
-  if( ColorFound >= 0 ) {
+
+
+  if( ColorFound >= 0 ) {               // if we could find a color
     LR->setColor(ColorFound);                  
     if( DEBUG_RA) UltraSparcRegInfo::printReg( LR );
     return;
   }
-
-
   else if( isCallInterf ) { 
 
     // We are here because there is a call interference and no non-volatile
@@ -306,11 +269,43 @@ void SparcFloatRegClass::colorIGNode(IGNode * Node,bool IsColorUsedArr[]) const
   LR->markForSpill();               // no color found - must spill
   if( DEBUG_RA) UltraSparcRegInfo::printReg( LR );
   
-
 }
 
 
 
+//-----------------------------------------------------------------------------
+// Helper method for coloring a node of Float Reg class.
+// Finds the first available color in the range [Start,End] depending on the
+// type of the Node (i.e., float/double)
+//-----------------------------------------------------------------------------
+int SparcFloatRegClass::findFloatColor(const LiveRange *const LR, 
+                                      unsigned Start,
+                                      unsigned End, 
+                                      bool IsColorUsedArr[] ) const {
+
+  bool ColorFound = false;
+  unsigned c;
+
+  if( LR->getTypeID() == Type::DoubleTyID ) { 
+      
+    // find first unused color for a double 
+    for( c=Start; c < End ;c+= 2){
+      if( ! IsColorUsedArr[ c ] &&  ! IsColorUsedArr[ c+1 ]) 
+       { ColorFound=true;  break; }
+    }
+    
+  } else {
+    
+    // find first unused color for a single
+    for( c=Start; c < End; c++) { 
+      if( ! IsColorUsedArr[ c ] ) { ColorFound=true;  break; }
+    }
+  }
+  
+  if( ColorFound ) return c;
+  else return -1;
+}
+
 
 
 
index 1876e458a0a1e396539e7af253cb58f45e249bd8..6a0460de7415a3a3447f5537a2a57b76e3617d7a 100644 (file)
@@ -5,23 +5,22 @@
 #include "llvm/iOther.h"
 #include "llvm/CodeGen/InstrScheduling.h"
 #include "llvm/CodeGen/InstrSelection.h"
-
 #include "llvm/Analysis/LiveVar/MethodLiveVarInfo.h"
 #include "llvm/CodeGen/PhyRegAlloc.h"
-
-
-
+#include "llvm/DerivedTypes.h"
 
 //---------------------------------------------------------------------------
-// UltraSparcRegInfo
+// Purpose: 
+// This file contains implementation of Sparc specific helper methods
+// used for register allocation.
 //---------------------------------------------------------------------------
 
+
 //---------------------------------------------------------------------------
-// Finds the return value of a call instruction
+// Finds the return value of a sparc specific call instruction
 //---------------------------------------------------------------------------
-
 const Value * 
-UltraSparcRegInfo::getCallInstRetVal(const MachineInstr *CallMI) const{
+UltraSparcRegInfo::getCallInstRetVal(const MachineInstr *CallMI) const {
 
   unsigned OpCode = CallMI->getOpCode();
   unsigned NumOfImpRefs =  CallMI->getNumImplicitRefs();
@@ -30,6 +29,7 @@ UltraSparcRegInfo::getCallInstRetVal(const MachineInstr *CallMI) const{
 
     // The one before the last implicit operand is the return value of 
     // a CALL instr
+    //
     if( NumOfImpRefs > 1 )
       if(  CallMI->implicitRefIsDefined(NumOfImpRefs-2) ) 
        return  CallMI->getImplicitRef(NumOfImpRefs-2); 
@@ -37,7 +37,8 @@ UltraSparcRegInfo::getCallInstRetVal(const MachineInstr *CallMI) const{
   }
   else if( OpCode == JMPLCALL) {
 
-    // The last implicit operand is the return value of a JMPL in   
+    // The last implicit operand is the return value of a JMPL
+    // 
     if( NumOfImpRefs > 0 )
       if(  CallMI->implicitRefIsDefined(NumOfImpRefs-1) ) 
        return  CallMI->getImplicitRef(NumOfImpRefs-1); 
@@ -46,13 +47,13 @@ UltraSparcRegInfo::getCallInstRetVal(const MachineInstr *CallMI) const{
     assert(0 && "OpCode must be CALL/JMPL for a call instr");
 
   return NULL;
-
 }
 
+
+
 //---------------------------------------------------------------------------
-// Finds the return address of a call instruction
+// Finds the return address of a call sparc specific call instruction
 //---------------------------------------------------------------------------
-
 const Value *
 UltraSparcRegInfo::getCallInstRetAddr(const MachineInstr *CallMI)const {
 
@@ -63,7 +64,9 @@ UltraSparcRegInfo::getCallInstRetAddr(const MachineInstr *CallMI)const {
     unsigned NumOfImpRefs =  CallMI->getNumImplicitRefs();
 
     assert( NumOfImpRefs && "CALL instr must have at least on ImpRef");
+
     // The last implicit operand is the return address of a CALL instr
+    //
     return  CallMI->getImplicitRef(NumOfImpRefs-1); 
 
   }
@@ -79,14 +82,13 @@ UltraSparcRegInfo::getCallInstRetAddr(const MachineInstr *CallMI)const {
   assert(0  && "There must be a return addr for a call instr");
 
   return NULL;
-
 }
 
 
+
 //---------------------------------------------------------------------------
 // Finds the # of actual arguments of the call instruction
 //---------------------------------------------------------------------------
-
 const unsigned 
 UltraSparcRegInfo::getCallInstNumArgs(const MachineInstr *CallMI) const {
 
@@ -128,15 +130,33 @@ UltraSparcRegInfo::getCallInstNumArgs(const MachineInstr *CallMI) const {
 
   assert( (NumArgs != -1)  && "Internal error in getCallInstNumArgs" );
   return (unsigned) NumArgs;
-  
 }
 
 
+
 //---------------------------------------------------------------------------
-// Suggests a register for the ret address in the RET machine instruction
+// Finds whether a call is an indirect call
 //---------------------------------------------------------------------------
+bool UltraSparcRegInfo::isVarArgCall(const MachineInstr *CallMI) const {
+
+  assert ( (UltraSparcInfo->getInstrInfo()).isCall(CallMI->getOpCode()) );
+
+  const MachineOperand & calleeOp = CallMI->getOperand(0);
+  Value *calleeVal =  calleeOp.getVRegValue();
 
+  PointerType *PT =  cast<PointerType> (calleeVal->getType());
+  MethodType  *MT = cast<MethodType>(PT->getElementType());
+
+  return MT->isVarArg();
+}
+
+
+
+
+//---------------------------------------------------------------------------
+// Suggests a register for the ret address in the RET machine instruction.
+// We always suggest %i7 by convention.
+//---------------------------------------------------------------------------
 void UltraSparcRegInfo::suggestReg4RetAddr(const MachineInstr * RetMI, 
                                           LiveRangeInfo& LRI) const {
 
@@ -145,30 +165,27 @@ void UltraSparcRegInfo::suggestReg4RetAddr(const MachineInstr * RetMI,
   
   MachineOperand & MO  = ( MachineOperand &) RetMI->getOperand(0);
 
+  // return address is always mapped to i7
+  //
   MO.setRegForValue( getUnifiedRegNum( IntRegClassID, SparcIntRegOrder::i7) );
   
-  // TODO (Optimize)
+  // Possible Optimization
   // Instead of setting the color, we can suggest one. In that case,
   // we have to test later whether it received the suggested color.
   // In that case, a LR has to be created at the start of method.
   // It has to be done as follows (remove the setRegVal above):
 
-  /*
-  const Value *RetAddrVal = MO.getVRegValue();
-
-  assert( RetAddrVal && "LR for ret address must be created at start");
-
-  LiveRange * RetAddrLR = LRI.getLiveRangeForValue( RetAddrVal);  
-  RetAddrLR->setSuggestedColor(getUnifiedRegNum( IntRegClassID, 
-  SparcIntRegOrdr::i7) );
-  */
-
-
+  // const Value *RetAddrVal = MO.getVRegValue();
+  // assert( RetAddrVal && "LR for ret address must be created at start");
+  // LiveRange * RetAddrLR = LRI.getLiveRangeForValue( RetAddrVal);  
+  // RetAddrLR->setSuggestedColor(getUnifiedRegNum( IntRegClassID, 
+  // SparcIntRegOrdr::i7) );
 }
 
 
 //---------------------------------------------------------------------------
-// Suggests a register for the ret address in the JMPL/CALL machine instr
+// Suggests a register for the ret address in the JMPL/CALL machine instr.
+// Sparc ABI dictates that %o7 be used for this purpose.
 //---------------------------------------------------------------------------
 void UltraSparcRegInfo::suggestReg4CallAddr(const MachineInstr * CallMI,
                                            LiveRangeInfo& LRI,
@@ -187,18 +204,6 @@ void UltraSparcRegInfo::suggestReg4CallAddr(const MachineInstr * CallMI,
   RetAddrLR->setColor(getUnifiedRegNum(IntRegClassID,SparcIntRegOrder::o7));
   LRI.addLRToMap( RetAddrVal, RetAddrLR);
   
-
-  /*  
-  assert( (CallMI->getNumOperands() == 3) && "JMPL must have 3 operands");
-
-  // directly set color since the LR of ret address (if there were one) 
-  // will not extend after the call instr
-
-  MachineOperand & MO  = ( MachineOperand &) CallMI->getOperand(2);
-  MO.setRegForValue( getUnifiedRegNum( IntRegClassID,SparcIntRegOrder::o7) );
-
-  */
-
 }
 
 
@@ -206,10 +211,11 @@ void UltraSparcRegInfo::suggestReg4CallAddr(const MachineInstr * CallMI,
 
 //---------------------------------------------------------------------------
 //  This method will suggest colors to incoming args to a method. 
+//  According to the Sparc ABI, the first 6 incoming args are in 
+//  %i0 - %i5 (if they are integer) OR in %f0 - %f31 (if they are float).
 //  If the arg is passed on stack due to the lack of regs, NOTHING will be
-//  done - it will be colored (or spilled) as a normal value.
+//  done - it will be colored (or spilled) as a normal live range.
 //---------------------------------------------------------------------------
-
 void UltraSparcRegInfo::suggestRegs4MethodArgs(const Method *const Meth, 
                                               LiveRangeInfo& LRI) const 
 {
@@ -230,13 +236,12 @@ void UltraSparcRegInfo::suggestRegs4MethodArgs(const Method *const Meth,
 
 
     // if the arg is in int class - allocate a reg for an int arg
+    //
     if( RegType == IntRegType ) {
 
       if( argNo < NumOfIntArgRegs) {
        LR->setSuggestedColor( SparcIntRegOrder::i0 + argNo );
-
       }
-  
       else {
        // Do NOTHING as this will be colored as a normal value.
        if (DEBUG_RA) cerr << " Int Regr not suggested for method arg\n";
@@ -250,15 +255,16 @@ void UltraSparcRegInfo::suggestRegs4MethodArgs(const Method *const Meth,
     else if( RegType == FPDoubleRegType && (argNo*2) < NumOfFloatArgRegs) 
       LR->setSuggestedColor( SparcFloatRegOrder::f0 + (argNo * 2) ); 
     
-
   }
-  
 }
 
+
+
 //---------------------------------------------------------------------------
-// 
+// This method is called after graph coloring to move incoming args to
+// the correct hardware registers if they did not receive the correct
+// (suggested) color through graph coloring.
 //---------------------------------------------------------------------------
-
 void UltraSparcRegInfo::colorMethodArgs(const Method *const Meth, 
                                        LiveRangeInfo& LRI,
                                        AddedInstrns *const FirstAI) const {
@@ -282,11 +288,11 @@ void UltraSparcRegInfo::colorMethodArgs(const Method *const Meth,
     unsigned RegType = getRegType( LR );
     unsigned RegClassID = (LR->getRegClass())->getID();
 
-
-    // find whether this argument is coming in a register (if not, on stack)
-
+    // Find whether this argument is coming in a register (if not, on stack)
+    // Also find the correct register that the argument must go (UniArgReg)
+    //
     bool isArgInReg = false;
-    unsigned UniArgReg = InvalidRegNum;         // reg that LR MUST be colored with
+    unsigned UniArgReg = InvalidRegNum;        // reg that LR MUST be colored with
 
     if( (RegType== IntRegType && argNo <  NumOfIntArgRegs)) {
       isArgInReg = true;
@@ -303,21 +309,23 @@ void UltraSparcRegInfo::colorMethodArgs(const Method *const Meth,
     }
 
     
-    if( LR->hasColor() ) {
+    if( LR->hasColor() ) {              // if this arg received a register
 
       unsigned UniLRReg = getUnifiedRegNum(  RegClassID, LR->getColor() );
 
       // if LR received the correct color, nothing to do
+      //
       if( UniLRReg == UniArgReg )
        continue;
 
-      // We are here because the LR did not have a suggested 
-      // color or did not receive the suggested color but LR got a register.
-      // Now we have to copy %ix reg (or stack pos of arg) 
-      // to the register it was colored with.
+      // We are here because the LR did not receive the suggested 
+      // but LR received another register.
+      // Now we have to copy the %i reg (or stack pos of arg) 
+      // to the register the LR was colored with.
       
-      // if the arg is coming in UniArgReg register MUST go into
+      // if the arg is coming in UniArgReg register, it MUST go into
       // the UniLRReg register
+      //
       if( isArgInReg ) 
        AdMI = cpReg2RegMI( UniArgReg, UniLRReg, RegType );
 
@@ -325,12 +333,14 @@ void UltraSparcRegInfo::colorMethodArgs(const Method *const Meth,
 
        // Now the arg is coming on stack. Since the LR recieved a register,
        // we just have to load the arg on stack into that register
+       //
         const MachineFrameInfo& frameInfo = target.getFrameInfo();
         assert(frameInfo.argsOnStackHaveFixedSize()); 
         
-        bool growUp;
+        bool growUp;                    // find the offset of arg in stack frame
        int firstArg =
-          frameInfo.getFirstIncomingArgOffset(MachineCodeForMethod::get(Meth), growUp);
+          frameInfo.getFirstIncomingArgOffset(MachineCodeForMethod::get(Meth), 
+                                             growUp);
        int offsetFromFP =
           growUp? firstArg + argNo * frameInfo.getSizeOfEachArgOnStack()
                 : firstArg - argNo * frameInfo.getSizeOfEachArgOnStack();
@@ -347,11 +357,9 @@ void UltraSparcRegInfo::colorMethodArgs(const Method *const Meth,
 
       // Now, the LR did not receive a color. But it has a stack offset for
       // spilling.
-
       // So, if the arg is coming in UniArgReg register,  we can just move
       // that on to the stack pos of LR
 
-
       if( isArgInReg ) {
 
        MachineInstr *AdIBef = 
@@ -502,7 +510,8 @@ void UltraSparcRegInfo::suggestRegs4CallArgs(const MachineInstr *const CallMI,
 void UltraSparcRegInfo::colorCallArgs(const MachineInstr *const CallMI,
                                      LiveRangeInfo& LRI,
                                      AddedInstrns *const CallAI,
-                                     PhyRegAlloc &PRA) const {
+                                     PhyRegAlloc &PRA,
+                                     const BasicBlock *BB) const {
 
   assert ( (UltraSparcInfo->getInstrInfo()).isCall(CallMI->getOpCode()) );
 
@@ -588,12 +597,18 @@ void UltraSparcRegInfo::colorCallArgs(const MachineInstr *const CallMI,
   } // if there a return value
   
 
+  //-------------------------------------------
   // Now color all args of the call instruction
+  //-------------------------------------------
 
   vector <MachineInstr *> AddedInstrnsBefore;
 
   unsigned NumOfCallArgs =  getCallInstNumArgs( CallMI );
 
+  bool VarArgCall = isVarArgCall( CallMI );
+
+  if(VarArgCall) cerr << "\nVar arg call found!!\n";
+
   for(unsigned argNo=0, i=0; i < NumOfCallArgs; ++i, ++argNo ) {
 
     const Value *CallArg = CallMI->getImplicitRef(i);
@@ -615,14 +630,32 @@ void UltraSparcRegInfo::colorCallArgs(const MachineInstr *const CallMI,
     }
     else if(RegType == FPSingleRegType && argNo < NumOfFloatArgRegs)  { 
       isArgInReg = true;
-      UniArgReg = getUnifiedRegNum(RegClassID, 
-                                  SparcFloatRegOrder::f0 + (argNo*2 + 1) );
+
+      if( !VarArgCall )
+       UniArgReg = getUnifiedRegNum(RegClassID, 
+                                    SparcFloatRegOrder::f0 + (argNo*2 + 1) );
+      else {                   
+       // a variable argument call - must pass float arg in %o's
+       if( argNo <  NumOfIntArgRegs)
+         UniArgReg=getUnifiedRegNum(IntRegClassID,SparcIntRegOrder::o0+argNo);
+       else    
+         isArgInReg = false;
+      }          
+
     }
     else if(RegType == FPDoubleRegType && argNo < NumOfFloatArgRegs)  { 
       isArgInReg = true;
-      UniArgReg = getUnifiedRegNum(RegClassID, SparcFloatRegOrder::f0+argNo*2);
-    }
 
+      if( !VarArgCall )
+       UniArgReg =getUnifiedRegNum(RegClassID,SparcFloatRegOrder::f0+argNo*2);
+      else {                   
+       // a variable argument call - must pass float arg in %o's
+       if( argNo <  NumOfIntArgRegs)
+         UniArgReg=getUnifiedRegNum(IntRegClassID,SparcIntRegOrder::o0+argNo);
+       else    
+         isArgInReg = false;
+      }          
+    }
 
     // not possible to have a null LR since all args (even consts)  
     // must be defined before
@@ -636,9 +669,6 @@ void UltraSparcRegInfo::colorCallArgs(const MachineInstr *const CallMI,
     }
 
 
-    // if the LR received the suggested color, NOTHING to do
-
-
     if( LR->hasColor() ) {
 
 
@@ -656,8 +686,30 @@ void UltraSparcRegInfo::colorCallArgs(const MachineInstr *const CallMI,
       // to pass it as an argument
 
       if( isArgInReg ) {
-       AdMI = cpReg2RegMI(UniLRReg, UniArgReg, RegType );
-       AddedInstrnsBefore.push_back( AdMI ); 
+
+       if( VarArgCall && RegClassID == FloatRegClassID ) {
+
+  
+         // for a variable argument call, the float reg must go in a %o reg.
+         // We have to move a float reg to an int reg via memory.
+         // The store instruction will be directly added to  
+         // CallAI->InstrnsBefore since it does not need reordering
+         // 
+         int TmpOff = PRA.mcInfo.pushTempValue(target,  
+                                              getSpilledRegSize(RegType));
+
+         AdMI = cpReg2MemMI(UniLRReg, getFramePointer(), TmpOff, RegType );
+         CallAI->InstrnsBefore.push_back( AdMI ); 
+
+         AdMI = cpMem2RegMI(getFramePointer(), TmpOff, UniArgReg, IntRegType);
+         AddedInstrnsBefore.push_back( AdMI ); 
+       }
+
+       else {  
+         AdMI = cpReg2RegMI(UniLRReg, UniArgReg, RegType );
+         AddedInstrnsBefore.push_back( AdMI ); 
+       }
+
       }
       
       else {
@@ -688,9 +740,12 @@ void UltraSparcRegInfo::colorCallArgs(const MachineInstr *const CallMI,
        // Since, the outgoing arg goes in a register we just have to insert
        // a load instruction to load the LR to outgoing register
 
-
-       AdMI = cpMem2RegMI(getFramePointer(), LR->getSpillOffFromFP(),
-                          UniArgReg, RegType );
+       if( VarArgCall && RegClassID == FloatRegClassID ) 
+         AdMI = cpMem2RegMI(getFramePointer(), LR->getSpillOffFromFP(),
+                            UniArgReg, IntRegType );
+       else
+         AdMI = cpMem2RegMI(getFramePointer(), LR->getSpillOffFromFP(),
+                            UniArgReg, RegType );
         
        cerr << "\nCaution: Loading a spilled val to a reg as a call arg";
        AddedInstrnsBefore.push_back( AdMI );  // Now add the instruction
@@ -709,9 +764,9 @@ void UltraSparcRegInfo::colorCallArgs(const MachineInstr *const CallMI,
        
        int TReg = PRA.getUniRegNotUsedByThisInst( LR->getRegClass(), CallMI );
 
-    /**** NOTE: THIS SHOULD USE THE RIGHT SIZE FOR THE REG BEING PUSHED ****/
-       int TmpOff = PRA.mcInfo.pushTempValue(target, 8);
-                          // target.findOptimalStorageSize(LR->getType()));
+       int TmpOff = PRA.mcInfo.pushTempValue(target,  
+                                   getSpilledRegSize(getRegType(LR)) );
+
         
        int argOffset = PRA.mcInfo.allocateOptionalArg(target, LR->getType()); 
         
@@ -772,6 +827,11 @@ void UltraSparcRegInfo::colorCallArgs(const MachineInstr *const CallMI,
   }
 
 
+  // now insert caller saving code for this call instruction
+  //
+  insertCallerSavingCode(CallMI, BB, PRA);
+
+
   // Reset optional args area again to be safe
   PRA.mcInfo.resetOptionalArgs(target);
   
@@ -1112,7 +1172,7 @@ void UltraSparcRegInfo::insertCallerSavingCode(const MachineInstr *MInst,
 
   // Clear the temp area of the stack
   //PRA.mcInfo.popAllTempValues(target);
-  // TODO*** Don't do this since we can have a situation lik
+  // TODO*** Don't do this since we can have a situation like
   /*
 
         stx     %o1     %i6     1999   <--- inserted by this code
@@ -1185,9 +1245,10 @@ void UltraSparcRegInfo::insertCallerSavingCode(const MachineInstr *MInst,
            // and add them to InstrnsBefore and InstrnsAfter of the
            // call instruction
 
-    /**** NOTE: THIS SHOULD USE THE RIGHT SIZE FOR THE REG BEING PUSHED ****/
-           int StackOff =  PRA.mcInfo.pushTempValue(target, 8);
-                // target.findOptimalStorageSize(LR->getType()));
+
+           int StackOff =  PRA.mcInfo.pushTempValue(target,  
+                                              getSpilledRegSize(RegType));
+
             
            MachineInstr *AdIBefCC, *AdIAftCC, *AdICpCC;
            MachineInstr *AdIBef, *AdIAft;
@@ -1561,9 +1622,8 @@ void UltraSparcRegInfo::moveInst2OrdVec(vector<MachineInstr *> &OrdVec,
          const int RegType = getRegType(UReg);
          MachineInstr *AdIBef, *AdIAft;
              
-         // TODO: Change 8 below
-    /**** NOTE: THIS SHOULD USE THE RIGHT SIZE FOR THE REG BEING PUSHED ****/
-         const int StackOff =  PRA.mcInfo.pushTempValue(target, 8);
+         const int StackOff =  PRA.mcInfo.pushTempValue(target,
+                                        getSpilledRegSize(RegType));
          
          // Save the UReg (%ox) on stack before it's destroyed
          AdIBef=cpReg2MemMI(UReg, getFramePointer(), StackOff, RegType);
index 20bad83dfc650b52b857613c921b6028696f655b..9524e80515999771fc5c12febd6607dc10e4d90c 100644 (file)
@@ -291,14 +291,17 @@ UltraSparc::compileMethod(Method *method)
           << "\n\n";
       return true;
     }
-  
+
+  /*  
   if (ScheduleInstructionsWithSSA(method, *this))
     {
       cerr << "Instruction scheduling before allocation failed for method "
           << method->getName() << "\n\n";
       return true;
     }
+  */
   
+
   AllocateRegisters(method, *this);          // allocate registers
   
   ApplyPeepholeOptimizations(method, *this); // machine-dependent peephole opts