[llvm-commits] CVS: llvm/lib/Target/Sparc/SparcRegClassInfo.cpp SparcRegInfo.cpp EmitAssembly.cpp

Vikram Adve vadve at cs.uiuc.edu
Thu Jul 10 14:43:01 PDT 2003


Changes in directory llvm/lib/Target/Sparc:

SparcRegClassInfo.cpp updated: 1.23 -> 1.24
SparcRegInfo.cpp updated: 1.101 -> 1.102
EmitAssembly.cpp updated: 1.80 -> 1.81

---
Log message:

Several fixes to handling of int CC register:

(1) An int CC live range must be spilled if there are any interferences,
    even if no other "neighbour" in the interf. graph has been allocated
    that reg. yet.  This is actually true of any class with only one reg!  

(2) SparcIntCCRegClass::colorIGNode sets the color even if the LR must
    be spilled so that the machine-independent spill code doesn't have to
    make the machine-dependent decision of which CC name to use based on
    operand type: %xcc or %icc.  (These are two halves of the same register.)

(3) LR->isMarkedForSpill() is no longer the same as LR->hasColor().
    These should never have been the same, and this is necessary now for #2.

(4) All RDCCR and WRCCR instructions are directly generated with the
    phony number for %ccr so that EmitAssembly/EmitBinary doesn't have to
    deal with this.



---
Diffs of the changes:

Index: llvm/lib/Target/Sparc/SparcRegClassInfo.cpp
diff -u llvm/lib/Target/Sparc/SparcRegClassInfo.cpp:1.23 llvm/lib/Target/Sparc/SparcRegClassInfo.cpp:1.24
--- llvm/lib/Target/Sparc/SparcRegClassInfo.cpp:1.23	Sun Jul  6 17:50:31 2003
+++ llvm/lib/Target/Sparc/SparcRegClassInfo.cpp	Thu Jul 10 14:42:11 2003
@@ -117,7 +117,8 @@
 //
 // Algorithm:
 //
-//     If the single int CC register is used (either as icc or xcc)
+//     If (node has any interferences)
+//         /* all interference operations can use only one register! */
 //         mark the LR for spilling
 //     else {
 //         if (the LR is a 64-bit comparison) use %xcc
@@ -130,30 +131,33 @@
 void SparcIntCCRegClass::colorIGNode(IGNode *Node,
                                      std::vector<bool> &IsColorUsedArr) const
 {
-  if (IsColorUsedArr[xcc] && IsColorUsedArr[icc])
+  if (Node->getNumOfNeighbors() > 0)
     Node->getParentLR()->markForSpill();
-  else {
-    // Choose whether to use %xcc or %icc based on type of value compared
-    const LiveRange* ccLR = Node->getParentLR();
-    const Type* setCCType = (* ccLR->begin())->getType(); // any Value in LR
-    assert(setCCType->isIntegral() || isa<PointerType>(setCCType));
-    int ccReg = ((isa<PointerType>(setCCType) || setCCType == Type::LongTy)
-                 ? xcc : icc);
+
+  // Mark the appropriate register in any case (even if it needs to be spilled)
+  // because there is only one possible register, but more importantly, the
+  // spill algorithm cannot find it.  In particular, we have to choose
+  // whether to use %xcc or %icc based on type of value compared
+  // 
+  const LiveRange* ccLR = Node->getParentLR();
+  const Type* setCCType = (* ccLR->begin())->getType(); // any Value in LR
+  assert(setCCType->isIntegral() || isa<PointerType>(setCCType));
+  int ccReg = ((isa<PointerType>(setCCType) || setCCType == Type::LongTy)
+               ? xcc : icc);
 
 #ifndef NDEBUG
-    // Let's just make sure values of two different types have not been
-    // coalesced into this LR.
-    for (ValueSet::const_iterator I=ccLR->begin(), E=ccLR->end(); I!=E; ++I) {
-      const Type* ccType = (*I)->getType();
-      assert((ccReg == xcc && (isa<PointerType>(ccType)
-                               || ccType == Type::LongTy)) ||
-             (ccReg == icc && ccType->isIntegral() && ccType != Type::LongTy)
-             && "Comparisons needing different intCC regs coalesced in LR!");
-    }
+  // Let's just make sure values of two different types have not been
+  // coalesced into this LR.
+  for (ValueSet::const_iterator I=ccLR->begin(), E=ccLR->end(); I!=E; ++I) {
+    const Type* ccType = (*I)->getType();
+    assert((ccReg == xcc && (isa<PointerType>(ccType)
+                             || ccType == Type::LongTy)) ||
+           (ccReg == icc && ccType->isIntegral() && ccType != Type::LongTy)
+           && "Comparisons needing different intCC regs coalesced in LR!");
+  }
 #endif
 
-    Node->setColor(ccReg);                // only one int cc reg is available
-  }
+  Node->setColor(ccReg);                // only one int cc reg is available
 }
 
 


Index: llvm/lib/Target/Sparc/SparcRegInfo.cpp
diff -u llvm/lib/Target/Sparc/SparcRegInfo.cpp:1.101 llvm/lib/Target/Sparc/SparcRegInfo.cpp:1.102
--- llvm/lib/Target/Sparc/SparcRegInfo.cpp:1.101	Sun Jul  6 15:13:59 2003
+++ llvm/lib/Target/Sparc/SparcRegInfo.cpp	Thu Jul 10 14:42:11 2003
@@ -424,7 +424,7 @@
       UniArgReg = getUnifiedRegNum( regClassIDOfArgReg, regNum);
     }
     
-    if( LR->hasColor() ) {              // if this arg received a register
+    if( ! LR->isMarkedForSpill() ) {    // if this arg received a register
 
       unsigned UniLRReg = getUnifiedRegNum(  RegClassID, LR->getColor() );
 
@@ -618,25 +618,7 @@
     // If not, do NOTHING as this will be colored as a normal value.
     if(regNum != getInvalidRegNum())
       LR->setSuggestedColor(regNum);
-    
-#ifdef CANNOT_PRECOPY_CALLARGS
-    // Repeat for the second copy of the argument, which would be
-    // an FP argument being passed to a function with no prototype
-    const Value *argCopy = argDesc->getArgInfo(i).getArgCopy();
-    if (argCopy != NULL)
-      {
-        assert(regType != IntRegType && argCopy->getType()->isInteger()
-               && "Must be passing copy of FP argument in int register");
-        int copyRegNum = regNumForIntArg(/*inCallee*/false, /*isVarArgs*/false,
-                                         argNo, regClassIDOfArgReg);
-        assert(copyRegNum != getInvalidRegNum()); 
-        LiveRange *const copyLR = LRI.getLiveRangeForValue(argCopy); 
-        copyLR->setSuggestedColor(copyRegNum);
-      }
-#endif
-    
   } // for all call arguments
-
 }
 
 
@@ -664,7 +646,7 @@
       UniArgReg = (unsigned) UniArgRegOrNone;
     }
   
-  if (LR->hasColor()) {
+  if (! LR->isMarkedForSpill()) {
     unsigned UniLRReg = getUnifiedRegNum(RegClassID, LR->getColor());
     
     // if LR received the correct color, nothing to do
@@ -772,42 +754,6 @@
     
     CallMI->insertUsedReg(getUnifiedRegNum(RegClassID, CorrectCol));	
     
-#ifdef CANNOT_PRECOPY_CALLARGS
-    // unified number for CorrectCol
-    unsigned UniRetReg = getUnifiedRegNum(RegClassID, CorrectCol);
-    recvCorrectColor;
-
-    // if the LR received the correct color, NOTHING to do
-    bool recvCorrectColor = (RetValLR->hasColor()
-                             ? RetValLR->getColor() == CorrectCol : false);
-    
-    // if we didn't receive the correct color for some reason, 
-    // put copy instruction
-    if( !recvCorrectColor ) {
-      
-      unsigned regType = getRegType(RetValLR);
-
-      if( RetValLR->hasColor() ) {
-	
-	unsigned UniRetLRReg=getUnifiedRegNum(RegClassID,RetValLR->getColor());
-	
-	// the return value is coming in UniRetReg but has to go into
-	// the UniRetLRReg
-
-	cpReg2RegMI(CallAI->InstrnsAfter, UniRetReg, UniRetLRReg, regType);
-
-      } // if LR has color
-      else {
-
-	// if the LR did NOT receive a color, we have to move the return
-	// value coming in UniRetReg to the stack pos of spilled LR
-	
-        cpReg2MemMI(CallAI->InstrnsAfter, UniRetReg,
-                    getFramePointer(),RetValLR->getSpillOffFromFP(), regType);
-      }
-    } // the LR didn't receive the suggested color  
-#endif
-    
   } // if there a return value
   
 
@@ -849,24 +795,6 @@
       CallMI->insertUsedReg(UniArgReg);         // mark the reg as used
     }
 
-#ifdef CANNOT_PRECOPY_CALLARGS
-    
-    // Get the LR of call operand (parameter).  There must be one because
-    // all args (even constants) must be defined before.
-    LiveRange *const LR = LRI.getLiveRangeForValue(CallArg); 
-    assert(LR && "NO LR for call arg");  
-
-    unsigned RegClassID = getRegClassIDOfType(CallArg->getType());
-
-    if (regNum != getInvalidRegNum()) {
-      assert(regClassIDOfArgReg == RegClassID &&
-             "Moving values between reg classes must happen during selection");
-    }
-    
-    InitializeOutgoingArg(CallMI, CallAI, PRA, LR, regType, RegClassID,
-                          UniArgReg, argNo, AddedInstrnsBefore);
-#endif
-    
     // Repeat for the second copy of the argument, which would be
     // an FP argument being passed to a function with no prototype.
     // It may either be passed as a copy in an integer register
@@ -875,38 +803,7 @@
     if (argCopyReg != TargetRegInfo::getInvalidRegNum())
       {
         CallMI->insertUsedReg(argCopyReg); // mark the reg as used
-
-#ifdef CANNOT_PRECOPY_CALLARGS
-        assert(regType != IntRegType && argCopy->getType()->isInteger()
-               && "Must be passing copy of FP argument in int register");
-        
-        unsigned copyRegClassID = getRegClassIDOfType(argCopy->getType());
-        unsigned copyRegType = getRegType(argCopy->getType());
-        
-        int copyRegNum = regNumForIntArg(/*inCallee*/false, /*isVarArgs*/false,
-                                         argNo, regClassIDOfArgReg);
-        assert(copyRegNum != getInvalidRegNum()); 
-        assert(regClassIDOfArgReg == copyRegClassID &&
-           "Moving values between reg classes must happen during selection");
-        
-        InitializeOutgoingArg(CallMI, CallAI, PRA,
-                              LRI.getLiveRangeForValue(argCopy), copyRegType,
-                              copyRegClassID, copyRegNum, argNo,
-                              AddedInstrnsBefore);
-#endif
-      }
-    
-#ifdef CANNOT_PRECOPY_CALLARGS
-    if (regNum != getInvalidRegNum() &&
-        argDesc->getArgInfo(i).usesStackSlot())
-      {
-        // Pass the argument via the stack in addition to regNum
-        assert(regType != IntRegType && "Passing an integer arg. twice?");
-        assert(!argCopy && "Passing FP arg in FP reg, INT reg, and stack?");
-        InitializeOutgoingArg(CallMI, CallAI, PRA, LR, regType, RegClassID,
-                              getInvalidRegNum(), argNo, AddedInstrnsBefore);
       }
-#endif
   }  // for each parameter in call instruction
 
   // If we added any instruction before the call instruction, verify
@@ -1014,34 +911,6 @@
 
     // Mark the register as used by this instruction
     RetMI->insertUsedReg(UniRetReg);
-
-#ifdef CANNOT_PRECOPY_CALLARGS
-    LiveRange *LR = LRI.getLiveRangeForValue(RetVal); 
-    assert(LR && "No LR for return value of non-void method?");
-
-    if (LR->hasColor()) {
-      // if the LR received the correct color, NOTHING to do
-      if (LR->getColor() == CorrectCol)
-        return;
-    
-      // We are here because the LR was allocated a register
-      // It may be the suggested register or not
-
-      // copy the LR of retun value to i0 or f0
-
-      unsigned UniLRReg =getUnifiedRegNum( RegClassID, LR->getColor());
-
-      // the LR received  UniLRReg but must be colored with UniRetReg
-      // to pass as the return value
-      cpReg2RegMI(RetAI->InstrnsBefore, UniLRReg, UniRetReg, regType);
-    }
-    else {                              // if the LR is spilled
-      cpMem2RegMI(RetAI->InstrnsBefore, getFramePointer(),
-                  LR->getSpillOffFromFP(), UniRetReg, regType);
-      //std::cerr << "\nCopied the return value from stack\n";
-    }
-#endif
-  
   } // if there is a return value
 
 }
@@ -1088,14 +957,19 @@
   case IntCCRegType:
     if (getRegType(DestReg) == IntRegType) {
       // copy intCC reg to int reg
-      MI = (BuildMI(V9::RDCCR, 2).addMReg(SparcIntCCRegClass::ccr).
-            addMReg(DestReg,MOTy::Def));
+      MI = (BuildMI(V9::RDCCR, 2)
+            .addMReg(getUnifiedRegNum(UltraSparcRegInfo::IntCCRegClassID,
+                                      SparcIntCCRegClass::ccr))
+            .addMReg(DestReg,MOTy::Def));
     } else {
       // copy int reg to intCC reg
       assert(getRegType(SrcReg) == IntRegType
              && "Can only copy CC reg to/from integer reg");
-      MI = (BuildMI(V9::WRCCRr, 3).addMReg(SrcReg).addMReg(SparcIntRegClass::g0)
-            .addMReg(SparcIntCCRegClass::ccr, MOTy::Def));
+      MI = (BuildMI(V9::WRCCRr, 3)
+            .addMReg(SrcReg)
+            .addMReg(SparcIntRegClass::g0)
+            .addMReg(getUnifiedRegNum(UltraSparcRegInfo::IntCCRegClassID,
+                                      SparcIntCCRegClass::ccr), MOTy::Def));
     }
     break;
     
@@ -1160,7 +1034,9 @@
   case IntCCRegType:
     assert(scratchReg >= 0 && "Need scratch reg to store %ccr to memory");
     assert(getRegType(scratchReg) ==IntRegType && "Invalid scratch reg");
-    MI = (BuildMI(V9::RDCCR, 2).addMReg(SparcIntCCRegClass::ccr)
+    MI = (BuildMI(V9::RDCCR, 2)
+          .addMReg(getUnifiedRegNum(UltraSparcRegInfo::IntCCRegClassID,
+                                    SparcIntCCRegClass::ccr))
           .addMReg(scratchReg, MOTy::Def));
     mvec.push_back(MI);
     
@@ -1219,8 +1095,11 @@
     assert(scratchReg >= 0 && "Need scratch reg to load %ccr from memory");
     assert(getRegType(scratchReg) ==IntRegType && "Invalid scratch reg");
     cpMem2RegMI(mvec, SrcPtrReg, Offset, scratchReg, IntRegType);
-    MI = BuildMI(V9::WRCCRr, 3).addMReg(scratchReg)
-      .addMReg(SparcIntRegClass::g0).addMReg(SparcIntCCRegClass::ccr,MOTy::Def);
+    MI = (BuildMI(V9::WRCCRr, 3)
+          .addMReg(scratchReg)
+          .addMReg(SparcIntRegClass::g0)
+          .addMReg(getUnifiedRegNum(UltraSparcRegInfo::IntCCRegClassID,
+                                    SparcIntCCRegClass::ccr), MOTy::Def));
     break;
     
   case FloatCCRegType: {
@@ -1323,7 +1202,7 @@
     LiveRange *RetValLR = PRA.LRI.getLiveRangeForValue( tmpRetVal );
     assert(RetValLR && "No LR for RetValue of call");
 
-    if (RetValLR->hasColor())
+    if (! RetValLR->isMarkedForSpill())
       PushedRegSet.insert(getUnifiedRegNum(RetValLR->getRegClassID(),
                                            RetValLR->getColor()));
   }
@@ -1341,8 +1220,9 @@
     // doesn't have a dominating def - see Assumptions above
     if( LR )   {  
       
-      if( LR->hasColor() ) {
+      if(! LR->isMarkedForSpill()) {
 
+        assert(LR->hasColor() && "LR is neither spilled nor colored?");
 	unsigned RCID = LR->getRegClassID();
 	unsigned Color = LR->getColor();
 


Index: llvm/lib/Target/Sparc/EmitAssembly.cpp
diff -u llvm/lib/Target/Sparc/EmitAssembly.cpp:1.80 llvm/lib/Target/Sparc/EmitAssembly.cpp:1.81
--- llvm/lib/Target/Sparc/EmitAssembly.cpp:1.80	Sun Jul  6 15:13:59 2003
+++ llvm/lib/Target/Sparc/EmitAssembly.cpp	Thu Jul 10 14:42:11 2003
@@ -393,27 +393,12 @@
   
   switch (mop.getType())
     {
-    case MachineOperand::MO_CCRegister:
-      {
-        // We need to print %icc or %xcc as %ccr for certain opcodes.
-        int regNum = (int)mop.getAllocatedRegNum();
-        if (regNum != Target.getRegInfo().getInvalidRegNum() &&
-            Target.getRegInfo().getRegClassIDOfReg(regNum)
-            == UltraSparcRegInfo::IntCCRegClassID)
-          {
-            if (opCode == V9::RDCCR || opCode == V9::WRCCRi || opCode == V9::WRCCRr)
-              {
-                toAsm << "%" << Target.getRegInfo().getMachineRegClass(UltraSparcRegInfo::IntCCRegClassID)->getRegName(SparcIntCCRegClass::ccr);
-                break;
-              }
-          }
-        // all other cases can be handled like any other register
-      }
-
     case MachineOperand::MO_VirtualRegister:
+    case MachineOperand::MO_CCRegister:
     case MachineOperand::MO_MachineRegister:
       {
         int regNum = (int)mop.getAllocatedRegNum();
+        
         if (regNum == Target.getRegInfo().getInvalidRegNum()) {
           // better to print code with NULL registers than to die
           toAsm << "<NULL VALUE>";





More information about the llvm-commits mailing list