Added support for both call/jmpl instructions
authorRuchira Sasanka <sasanka@students.uiuc.edu>
Sun, 21 Oct 2001 16:43:41 +0000 (16:43 +0000)
committerRuchira Sasanka <sasanka@students.uiuc.edu>
Sun, 21 Oct 2001 16:43:41 +0000 (16:43 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@930 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Target/TargetRegInfo.h
lib/CodeGen/RegAlloc/PhyRegAlloc.cpp
lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp
lib/Target/SparcV9/SparcV9Internals.h
lib/Target/SparcV9/SparcV9RegInfo.cpp

index bf5337856be1221977fa458f9f4ffd4cbe99a050..9a7ef4665f24f33032912cd3c64147121ddebf80 100644 (file)
@@ -86,7 +86,6 @@ class MachineRegInfo : public NonCopyableV {
 protected:
 
   MachineRegClassArrayType MachineRegClassArr;    
-
   
 public:
 
@@ -171,6 +170,7 @@ public:
 
   virtual int getRegType(const LiveRange *const LR) const=0;
 
+  virtual const Value * getCallInstRetVal(const MachineInstr *CallMI) const=0;
 
   inline virtual unsigned getFramePointer() const=0;
 
index b36e8e44437d430476c39dc58717398ecfe8e85d..43ea5a5cd0ffa1361237c53aeb2198e7a42f368a 100644 (file)
@@ -149,7 +149,7 @@ void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst,
                                       const LiveVarSet *const LVSetAft ) 
 {
   // Now find the LR of the return value of the call
-  // The last *implicit operand* is the return value of a 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
@@ -158,19 +158,13 @@ void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst,
 
   LiveRange *RetValLR = NULL;
 
-  unsigned NumOfImpRefs =  MInst->getNumImplicitRefs();
-  if(  NumOfImpRefs > 0 ) {
-
-    if(  MInst->implicitRefIsDefined(NumOfImpRefs-1) ) {
-
-      const Value *RetVal = MInst->getImplicitRef(NumOfImpRefs-1); 
-      RetValLR = LRI.getLiveRangeForValue( RetVal );
-      assert( RetValLR && "No LR for RetValue of call");
-    }
+  const Value *RetVal = MRI.getCallInstRetVal( MInst );
 
+  if( RetVal ) {
+    RetValLR = LRI.getLiveRangeForValue( RetVal );
+    assert( RetValLR && "No LR for RetValue of call");
   }
 
-
   if( DEBUG_RA)
     cout << "\n For call inst: " << *MInst;
 
@@ -356,20 +350,17 @@ void PhyRegAlloc::insertCallerSavingCode(const MachineInstr *MInst,
   // to determine, which LRs must be saved across calls. The return value
   // of the call is live in this set - but we must not save/restore it.
 
-  unsigned NumOfImpRefs =  MInst->getNumImplicitRefs();
-  if(  NumOfImpRefs > 0 ) {
-    
-    if(  MInst->implicitRefIsDefined(NumOfImpRefs-1) ) {
 
-      const Value *RetVal = MInst->getImplicitRef(NumOfImpRefs-1); 
-      LiveRange *RetValLR = LRI.getLiveRangeForValue( RetVal );
-      assert( RetValLR && "No LR for RetValue of call");
+  const Value *RetVal = MRI.getCallInstRetVal( MInst );
 
-      PushedRegSet.insert(  
-       MRI.getUnifiedRegNum((RetValLR->getRegClass())->getID(), 
-                            RetValLR->getColor() ) );
-    }
+  if( RetVal ) {
+
+    LiveRange *RetValLR = LRI.getLiveRangeForValue( RetVal );
+    assert( RetValLR && "No LR for RetValue of call");
 
+    PushedRegSet.insert(
+                MRI.getUnifiedRegNum((RetValLR->getRegClass())->getID(), 
+                                     RetValLR->getColor() ) );
   }
 
 
index b36e8e44437d430476c39dc58717398ecfe8e85d..43ea5a5cd0ffa1361237c53aeb2198e7a42f368a 100644 (file)
@@ -149,7 +149,7 @@ void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst,
                                       const LiveVarSet *const LVSetAft ) 
 {
   // Now find the LR of the return value of the call
-  // The last *implicit operand* is the return value of a 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
@@ -158,19 +158,13 @@ void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst,
 
   LiveRange *RetValLR = NULL;
 
-  unsigned NumOfImpRefs =  MInst->getNumImplicitRefs();
-  if(  NumOfImpRefs > 0 ) {
-
-    if(  MInst->implicitRefIsDefined(NumOfImpRefs-1) ) {
-
-      const Value *RetVal = MInst->getImplicitRef(NumOfImpRefs-1); 
-      RetValLR = LRI.getLiveRangeForValue( RetVal );
-      assert( RetValLR && "No LR for RetValue of call");
-    }
+  const Value *RetVal = MRI.getCallInstRetVal( MInst );
 
+  if( RetVal ) {
+    RetValLR = LRI.getLiveRangeForValue( RetVal );
+    assert( RetValLR && "No LR for RetValue of call");
   }
 
-
   if( DEBUG_RA)
     cout << "\n For call inst: " << *MInst;
 
@@ -356,20 +350,17 @@ void PhyRegAlloc::insertCallerSavingCode(const MachineInstr *MInst,
   // to determine, which LRs must be saved across calls. The return value
   // of the call is live in this set - but we must not save/restore it.
 
-  unsigned NumOfImpRefs =  MInst->getNumImplicitRefs();
-  if(  NumOfImpRefs > 0 ) {
-    
-    if(  MInst->implicitRefIsDefined(NumOfImpRefs-1) ) {
 
-      const Value *RetVal = MInst->getImplicitRef(NumOfImpRefs-1); 
-      LiveRange *RetValLR = LRI.getLiveRangeForValue( RetVal );
-      assert( RetValLR && "No LR for RetValue of call");
+  const Value *RetVal = MRI.getCallInstRetVal( MInst );
 
-      PushedRegSet.insert(  
-       MRI.getUnifiedRegNum((RetValLR->getRegClass())->getID(), 
-                            RetValLR->getColor() ) );
-    }
+  if( RetVal ) {
+
+    LiveRange *RetValLR = LRI.getLiveRangeForValue( RetVal );
+    assert( RetValLR && "No LR for RetValue of call");
 
+    PushedRegSet.insert(
+                MRI.getUnifiedRegNum((RetValLR->getRegClass())->getID(), 
+                                     RetValLR->getColor() ) );
   }
 
 
index 6828a68e66706f69d0a9c28947f9e41d7fe4186f..e19d3044953107271a7ced509eb51b05b56f58b5 100644 (file)
@@ -171,7 +171,8 @@ class UltraSparcRegInfo : public MachineRegInfo
   void suggestReg4RetAddr(const MachineInstr * RetMI, 
                          LiveRangeInfo& LRI) const;
 
-  void suggestReg4CallAddr(const MachineInstr * CallMI) const;
+  void suggestReg4CallAddr(const MachineInstr * CallMI, LiveRangeInfo& LRI,
+                          vector<RegClass *> RCList) const;
 
 
   Value *getValue4ReturnAddr( const MachineInstr * MInst ) const ;
@@ -235,6 +236,9 @@ class UltraSparcRegInfo : public MachineRegInfo
   MachineInstr * cpValue2RegMI(Value * Val,  const unsigned DestReg,
                               const int RegType) const;
 
+  const Value *getCallInstRetAddr(const MachineInstr *CallMI) const;
+  const unsigned getCallInstNumArgs(const MachineInstr *CallMI) const;
+
 
  public:
 
@@ -361,6 +365,8 @@ class UltraSparcRegInfo : public MachineRegInfo
   }
 
 
+  const Value * getCallInstRetVal(const MachineInstr *CallMI) const;
+
   MachineInstr * cpReg2RegMI(const unsigned SrcReg, const unsigned DestReg,
                             const int RegType) const;
 
index 3622510de8fbcaeefe971fa772e64663d621c530..d65d57edce515da6ca9a1818a746373c776a2529 100644 (file)
 // UltraSparcRegInfo
 //---------------------------------------------------------------------------
 
+//---------------------------------------------------------------------------
+// Finds the return value of a call instruction
+//---------------------------------------------------------------------------
+
+const Value * 
+UltraSparcRegInfo::getCallInstRetVal(const MachineInstr *CallMI) const{
+
+  unsigned OpCode = CallMI->getOpCode();
+  unsigned NumOfImpRefs =  CallMI->getNumImplicitRefs();
+
+  if( OpCode == CALL ) {
+
+    // 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); 
+
+  }
+  else if( OpCode == JMPL) {
+
+    // The last implicit operand is the return value of a JMPL in   
+    if( NumOfImpRefs > 0 )
+      if(  CallMI->implicitRefIsDefined(NumOfImpRefs-1) ) 
+       return  CallMI->getImplicitRef(NumOfImpRefs-1); 
+  }
+  else
+    assert(0 && "OpCode must be CALL/JMPL for a call instr");
+
+  return NULL;
+
+}
+
+//---------------------------------------------------------------------------
+// Finds the return address of a call instruction
+//---------------------------------------------------------------------------
+
+const Value *
+UltraSparcRegInfo::getCallInstRetAddr(const MachineInstr *CallMI)const {
+
+  unsigned OpCode = CallMI->getOpCode();
+
+  if( OpCode == CALL) {
+
+    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); 
+
+  }
+  else if( OpCode == JMPL ) {
+
+    MachineOperand & MO  = ( MachineOperand &) CallMI->getOperand(2);
+    return MO.getVRegValue();
+
+  }
+  else
+    assert(0 && "OpCode must be CALL/JMPL for a call instr");
+
+  assert(0  && "There must be a return addr for a call instr");
+
+  return NULL;
+
+}
+
+
+//---------------------------------------------------------------------------
+// Finds the # of actaul arguments of the call instruction
+//---------------------------------------------------------------------------
+
+const unsigned 
+UltraSparcRegInfo::getCallInstNumArgs(const MachineInstr *CallMI) const {
+
+  unsigned OpCode = CallMI->getOpCode();
+  unsigned NumOfImpRefs =  CallMI->getNumImplicitRefs();
+  int NumArgs = -1;
+
+  if( OpCode == CALL ) {
+
+    switch( NumOfImpRefs ) {
+
+    case 0: assert(0 && "A CALL inst must have at least one ImpRef (RetAddr)");
+
+    case 1: NumArgs = 0;
+            break;
+    
+    default:  // two or more implicit refs
+      if(  CallMI->implicitRefIsDefined(NumOfImpRefs-2) ) 
+       NumArgs = NumOfImpRefs - 2;    // i.e., NumOfImpRef-2 is the ret val
+      else 
+       NumArgs = NumOfImpRefs - 1;
+    }
+
+  }
+  else if( OpCode == JMPL ) {
+
+    // The last implicit operand is the return value of a JMPL instr
+    if( NumOfImpRefs > 0 ) {
+      if(  CallMI->implicitRefIsDefined(NumOfImpRefs-1) ) 
+       NumArgs = NumOfImpRefs - 1;    // i.e., NumOfImpRef-1 is the ret val
+      else 
+       NumArgs = NumOfImpRefs;
+    }
+    else 
+      NumArgs = NumOfImpRefs;
+  }
+  else
+    assert(0 && "OpCode must be CALL/JMPL for a call instr");
+
+  assert( (NumArgs != -1)  && "Internal error in getCallInstNumArgs" );
+  return (unsigned) NumArgs;
+
+}
+
+
 //---------------------------------------------------------------------------
 // Suggests a register for the ret address in the RET machine instruction
 //---------------------------------------------------------------------------
@@ -27,6 +144,10 @@ void UltraSparcRegInfo::suggestReg4RetAddr(const MachineInstr * RetMI,
 
   MO.setRegForValue( getUnifiedRegNum( IntRegClassID, SparcIntRegOrder::i7) );
 
+  // ***TODO: If the JMPL can be also used as a return instruction, 
+  // change the assertion. The return address register of JMPL will still
+  // be Operand(0)
+
 
   // TODO (Optimize): 
   // Instead of setting the color, we can suggest one. In that case,
@@ -51,9 +172,25 @@ void UltraSparcRegInfo::suggestReg4RetAddr(const MachineInstr * RetMI,
 //---------------------------------------------------------------------------
 // Suggests a register for the ret address in the JMPL/CALL machine instr
 //---------------------------------------------------------------------------
-void UltraSparcRegInfo::suggestReg4CallAddr(const MachineInstr * CallMI) const
-{
+void UltraSparcRegInfo::suggestReg4CallAddr(const MachineInstr * CallMI,
+                                           LiveRangeInfo& LRI,
+                                           vector<RegClass *> RCList) const {
+
+
+  const Value *RetAddrVal = getCallInstRetAddr( CallMI );
+
+  // RetAddrVal cannot be NULL (asserted in  getCallInstRetAddr)
+  // create a new LR for the return address and color it
+  
+  LiveRange * RetAddrLR = new LiveRange();  
+  RetAddrLR->add( RetAddrVal );
+  unsigned RegClassID = getRegClassIDOfValue( RetAddrVal );
+  RetAddrLR->setRegClass( RCList[RegClassID] );
+  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) 
@@ -61,6 +198,9 @@ void UltraSparcRegInfo::suggestReg4CallAddr(const MachineInstr * CallMI) const
 
   MachineOperand & MO  = ( MachineOperand &) CallMI->getOperand(2);
   MO.setRegForValue( getUnifiedRegNum( IntRegClassID,SparcIntRegOrder::o7) );
+
+  */
+
 }
 
 
@@ -220,7 +360,7 @@ void UltraSparcRegInfo::suggestRegs4CallArgs(const MachineInstr *const CallMI,
 
   assert ( (UltraSparcInfo->getInstrInfo()).isCall(CallMI->getOpCode()) );
 
-  suggestReg4CallAddr(CallMI);
+  suggestReg4CallAddr(CallMI, LRI, RCList);
 
 
   // First color the return value of the call instruction. The return value
@@ -233,49 +373,42 @@ void UltraSparcRegInfo::suggestRegs4CallArgs(const MachineInstr *const CallMI,
   // if type is not void,  create a new live range and set its 
   // register class and add to LRI
 
-  unsigned NumOfImpRefs =  CallMI->getNumImplicitRefs();
-  unsigned NumOfCallArgs = NumOfImpRefs;  // assume all implicits are args
 
-  if(  NumOfImpRefs > 0 ) {
+  const Value *RetVal = getCallInstRetVal( CallMI );
 
-    // The last implicit operand is the return value of a call
-    if(  CallMI->implicitRefIsDefined(NumOfImpRefs-1) ) {
 
-      const Value *RetVal = CallMI->getImplicitRef(NumOfImpRefs-1); 
+  if( RetVal ) {
 
-      assert( (! LRI.getLiveRangeForValue( RetVal ) ) && 
-             "LR for ret Value of call already definded!");
+    assert( (! LRI.getLiveRangeForValue( RetVal ) ) && 
+           "LR for ret Value of call already definded!");
 
 
       // create a new LR for the return value
 
-      LiveRange * RetValLR = new LiveRange();  
-      RetValLR->add( RetVal );
-      unsigned RegClassID = getRegClassIDOfValue( RetVal );
-      RetValLR->setRegClass( RCList[RegClassID] );
-      LRI.addLRToMap( RetVal, RetValLR);
-
-      // now suggest a register depending on the register class of ret arg
-
-      if( RegClassID == IntRegClassID ) 
-       RetValLR->setSuggestedColor(SparcIntRegOrder::o0);
-      else if (RegClassID == FloatRegClassID ) 
-       RetValLR->setSuggestedColor(SparcFloatRegOrder::f0 );
-      else assert( 0 && "Unknown reg class for return value of call\n");
-
-      // the last imp ref is the def, so one less arg
-      NumOfCallArgs--; 
+    LiveRange * RetValLR = new LiveRange();  
+    RetValLR->add( RetVal );
+    unsigned RegClassID = getRegClassIDOfValue( RetVal );
+    RetValLR->setRegClass( RCList[RegClassID] );
+    LRI.addLRToMap( RetVal, RetValLR);
+    
+    // now suggest a register depending on the register class of ret arg
 
-    }
+    if( RegClassID == IntRegClassID ) 
+      RetValLR->setSuggestedColor(SparcIntRegOrder::o0);
+    else if (RegClassID == FloatRegClassID ) 
+      RetValLR->setSuggestedColor(SparcFloatRegOrder::f0 );
+    else assert( 0 && "Unknown reg class for return value of call\n");
 
   }
 
+  
   // Now suggest colors for arguments (operands) of the call instruction.
   // Colors are suggested only if the arg number is smaller than the
   // the number of registers allocated for argument passing.
+  // Now, go thru call args - implicit operands of the call MI
 
+  unsigned NumOfCallArgs =  getCallInstNumArgs( CallMI );
   
-  // go thru call args - implicit operands of the call MI
   for(unsigned argNo=0, i=0; i < NumOfCallArgs; ++i, ++argNo ) {
 
     const Value *CallArg = CallMI->getImplicitRef(i);
@@ -331,7 +464,6 @@ void UltraSparcRegInfo::colorCallArgs(const MachineInstr *const CallMI,
                                      LiveRangeInfo& LRI,
                                      AddedInstrns *const CallAI) const {
 
-
   assert ( (UltraSparcInfo->getInstrInfo()).isCall(CallMI->getOpCode()) );
 
   // First color the return value of the call.
@@ -340,79 +472,68 @@ void UltraSparcRegInfo::colorCallArgs(const MachineInstr *const CallMI,
   
   MachineInstr *AdMI;
 
-  unsigned NumOfImpRefs =  CallMI->getNumImplicitRefs();
-  unsigned NumOfCallArgs = NumOfImpRefs;  // assume all implicits are args
-
-  if(  NumOfImpRefs > 0 ) {
-
-    // The last implicit operand is the return value of a call
-    if(  CallMI->implicitRefIsDefined(NumOfImpRefs-1) ) {
-
-      // one less call arg since last implicit ref is the return value
-      NumOfCallArgs--;
-
-      // find the return value and its LR
-      const Value *RetVal = CallMI->getImplicitRef(NumOfImpRefs-1); 
-      LiveRange * RetValLR = LRI.getLiveRangeForValue( RetVal );
-
-      if( !RetValLR ) {
-       cerr << "\nNo LR for:";
-       printValue( RetVal );
-       cerr << endl;
-       assert( RetValLR && "ERR:No LR for non-void return value");
-       //return;
-      }
-
-      bool recvSugColor = false;
-
-      if( RetValLR->hasSuggestedColor() && RetValLR->hasColor() )
-       if( RetValLR->getSuggestedColor() == RetValLR->getColor())
-         recvSugColor = true;
-
-      // if we didn't receive the suggested color for some reason, 
-      // put copy instruction
-
-      if( !recvSugColor ) {
+  const Value *RetVal = getCallInstRetVal( CallMI );
 
-       if( RetValLR->hasColor() ) {
+  if( RetVal ) {
 
-         unsigned RegType = getRegType( RetValLR );
-         unsigned RegClassID = (RetValLR->getRegClass())->getID();
+    LiveRange * RetValLR = LRI.getLiveRangeForValue( RetVal );
 
-         unsigned 
-           UniRetLRReg=getUnifiedRegNum(RegClassID,RetValLR->getColor());
-         unsigned UniRetReg = InvalidRegNum;
-
-         // find where we receive the return value depending on
-         // register class
-           
-         if(RegClassID == IntRegClassID)
-           UniRetReg = getUnifiedRegNum( RegClassID, SparcIntRegOrder::o0);
-         else if(RegClassID == FloatRegClassID)
-           UniRetReg = getUnifiedRegNum( RegClassID, SparcFloatRegOrder::f0);
-
-
-         AdMI = cpReg2RegMI(UniRetReg, UniRetLRReg, RegType );         
-         CallAI->InstrnsAfter.push_back( AdMI );
+    if( !RetValLR ) {
+      cerr << "\nNo LR for:";
+      printValue( RetVal );
+      cerr << endl;
+      assert( RetValLR && "ERR:No LR for non-void return value");
+      //return;
+    }
+    
+    bool recvSugColor = false;
+    
+    if( RetValLR->hasSuggestedColor() && RetValLR->hasColor() )
+      if( RetValLR->getSuggestedColor() == RetValLR->getColor())
+       recvSugColor = true;
+    
+    // if we didn't receive the suggested color for some reason, 
+    // put copy instruction
+    
+    if( !recvSugColor ) {
       
+      if( RetValLR->hasColor() ) {
+       
+       unsigned RegType = getRegType( RetValLR );
+       unsigned RegClassID = (RetValLR->getRegClass())->getID();
+       
+       unsigned 
+         UniRetLRReg=getUnifiedRegNum(RegClassID,RetValLR->getColor());
+       unsigned UniRetReg = InvalidRegNum;
+       
+       // find where we receive the return value depending on
+       // register class
+       
+       if(RegClassID == IntRegClassID)
+         UniRetReg = getUnifiedRegNum( RegClassID, SparcIntRegOrder::o0);
+       else if(RegClassID == FloatRegClassID)
+         UniRetReg = getUnifiedRegNum( RegClassID, SparcFloatRegOrder::f0);
+       
+       
+       AdMI = cpReg2RegMI(UniRetReg, UniRetLRReg, RegType );   
+       CallAI->InstrnsAfter.push_back( AdMI );
        
-       } // if LR has color
-       else {
        
-         assert(0 && "LR of return value is splilled");
-       }
+      } // if LR has color
+      else {
+       
+       assert(0 && "LR of return value is splilled");
+      }
       
-
-      } // the LR didn't receive the suggested color  
+      
+    } // the LR didn't receive the suggested color  
     
-    } // if there a return value
-
-  } // if there is an implicit arg for a return value
+  } // if there a return value
   
 
-
   // Now color all args of the call instruction
 
+  unsigned NumOfCallArgs =  getCallInstNumArgs( CallMI );
 
   for(unsigned argNo=0, i=0; i < NumOfCallArgs; ++i, ++argNo ) {