Several fixes to handling of int CC register:
authorVikram S. Adve <vadve@cs.uiuc.edu>
Thu, 10 Jul 2003 19:42:11 +0000 (19:42 +0000)
committerVikram S. Adve <vadve@cs.uiuc.edu>
Thu, 10 Jul 2003 19:42:11 +0000 (19:42 +0000)
(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.

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

lib/Target/SparcV9/SparcV9AsmPrinter.cpp
lib/Target/SparcV9/SparcV9RegClassInfo.cpp
lib/Target/SparcV9/SparcV9RegInfo.cpp

index 829a3b8bb3120f32c53eb59107e7a473b35b0c45..f66b36f9be4a613812bb6ebc626a499ccd6adfff 100644 (file)
@@ -393,27 +393,12 @@ SparcFunctionAsmPrinter::printOneOperand(const MachineOperand &mop,
   
   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>";
index 8c20ab04c822091bbc3199870246e89e5ea150a1..038ccb369eec5614335430f0bb3719a8e23c4e7c 100644 (file)
@@ -117,7 +117,8 @@ void SparcIntRegClass::colorIGNode(IGNode * Node,
 //
 // 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 SparcIntRegClass::colorIGNode(IGNode * Node,
 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 962b9f68d1c6156562ca2e931919d5d0086b894a..e1eb148f02587285eb98ffc5733b1ffcad0054cb 100644 (file)
@@ -424,7 +424,7 @@ void UltraSparcRegInfo::colorMethodArgs(const Function *Meth,
       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 @@ void UltraSparcRegInfo::suggestRegs4CallArgs(MachineInstr *CallMI,
     // 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 @@ UltraSparcRegInfo::InitializeOutgoingArg(MachineInstr* CallMI,
       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 @@ void UltraSparcRegInfo::colorCallArgs(MachineInstr *CallMI,
     
     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 @@ void UltraSparcRegInfo::colorCallArgs(MachineInstr *CallMI,
       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 @@ void UltraSparcRegInfo::colorCallArgs(MachineInstr *CallMI,
     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 @@ void UltraSparcRegInfo::colorRetValue(MachineInstr *RetMI,
 
     // 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 @@ UltraSparcRegInfo::cpReg2RegMI(std::vector<MachineInstr*>& mvec,
   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 @@ UltraSparcRegInfo::cpReg2MemMI(std::vector<MachineInstr*>& mvec,
   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 @@ UltraSparcRegInfo::cpMem2RegMI(std::vector<MachineInstr*>& mvec,
     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 @@ UltraSparcRegInfo::insertCallerSavingCode
     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 @@ UltraSparcRegInfo::insertCallerSavingCode
     // 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();