[llvm-commits] CVS: llvm/lib/Target/Sparc/SparcInstrInfo.cpp SparcInstrSelection.cpp SparcInternals.h SparcRegInfo.cpp

Vikram Adve vadve at cs.uiuc.edu
Sat May 31 02:31:01 PDT 2003


Changes in directory llvm/lib/Target/Sparc:

SparcInstrInfo.cpp updated: 1.44 -> 1.45
SparcInstrSelection.cpp updated: 1.98 -> 1.99
SparcInternals.h updated: 1.88 -> 1.89
SparcRegInfo.cpp updated: 1.95 -> 1.96

---
Log message:

Extensive changes to the way code generation occurs for function
call arguments and return values:
Now all copy operations before and after a call are generated during
selection instead of during register allocation.
The values are copied to virtual registers (or to the stack), but
in the former case these operands are marked with the correct physical
registers according to the calling convention.
Although this complicates scheduling and does not work well with
live range analysis, it simplifies the machine-dependent part of
register allocation.


---
Diffs of the changes:

Index: llvm/lib/Target/Sparc/SparcInstrInfo.cpp
diff -u llvm/lib/Target/Sparc/SparcInstrInfo.cpp:1.44 llvm/lib/Target/Sparc/SparcInstrInfo.cpp:1.45
--- llvm/lib/Target/Sparc/SparcInstrInfo.cpp:1.44	Tue May 27 17:35:43 2003
+++ llvm/lib/Target/Sparc/SparcInstrInfo.cpp	Sat May 31 02:30:29 2003
@@ -270,8 +270,7 @@
     CreateSETSWConst(target, (int32_t) C, dest, mvec);
   } else if (C > lo32) {
     // C does not fit in 32 bits
-    TmpInstruction* tmpReg = new TmpInstruction(Type::IntTy);
-    mcfi.addTemp(tmpReg);
+    TmpInstruction* tmpReg = new TmpInstruction(mcfi, Type::IntTy);
     CreateSETXConst(target, C, tmpReg, dest, mvec);
   }
 }
@@ -424,8 +423,7 @@
 
   if (isa<GlobalValue>(val)) {
       TmpInstruction* tmpReg =
-        new TmpInstruction(PointerType::get(val->getType()), val);
-      mcfi.addTemp(tmpReg);
+        new TmpInstruction(mcfi, PointerType::get(val->getType()), val);
       CreateSETXLabel(target, val, tmpReg, dest, mvec);
   } else if (valType->isIntegral()) {
     bool isValidConstant;
@@ -468,13 +466,11 @@
       
     // First, create a tmp register to be used by the SETX sequence.
     TmpInstruction* tmpReg =
-      new TmpInstruction(PointerType::get(val->getType()), val);
-    mcfi.addTemp(tmpReg);
+      new TmpInstruction(mcfi, PointerType::get(val->getType()), val);
       
     // Create another TmpInstruction for the address register
     TmpInstruction* addrReg =
-      new TmpInstruction(PointerType::get(val->getType()), val);
-    mcfi.addTemp(addrReg);
+      new TmpInstruction(mcfi, PointerType::get(val->getType()), val);
       
     // Put the address (a symbolic name) into a register
     CreateSETXLabel(target, val, tmpReg, addrReg, mvec);
@@ -526,7 +522,7 @@
   Value* storeVal = val;
   if (srcSize < target.getTargetData().getTypeSize(Type::FloatTy)) {
     // sign- or zero-extend respectively
-    storeVal = new TmpInstruction(storeType, val);
+    storeVal = new TmpInstruction(mcfi, storeType, val);
     if (val->getType()->isSigned())
       CreateSignExtensionInstructions(target, F, val, storeVal, 8*srcSize,
                                       mvec, mcfi);
@@ -552,8 +548,8 @@
 // Similarly, create an instruction sequence to copy an FP register
 // `val' to an integer register `dest' by copying to memory and back.
 // The generated instructions are returned in `mvec'.
-// Any temp. registers (TmpInstruction) created are recorded in mcfi.
-// Any stack space required is allocated via MachineFunction.
+// Any temp. virtual registers (TmpInstruction) created are recorded in mcfi.
+// Temporary stack space required is allocated via MachineFunction.
 // 
 void
 UltraSparcInstrInfo::CreateCodeToCopyFloatToInt(const TargetMachine& target,
@@ -570,6 +566,10 @@
   assert((destTy->isIntegral() || isa<PointerType>(destTy))
          && "Dest type must be integer, bool or pointer");
 
+  // FIXME: For now, we allocate permanent space because the stack frame
+  // manager does not allow locals to be allocated (e.g., for alloca) after
+  // a temp is allocated!
+  // 
   int offset = MachineFunction::get(F).getInfo()->allocateLocalVar(val); 
 
   unsigned FPReg = target.getRegInfo().getFramePointer();
@@ -639,14 +639,20 @@
     target.getInstrInfo().CreateCodeToLoadConst(target, F, src, dest,
                                                 mvec, mcfi);
   } else { 
-    // Create an add-with-0 instruction of the appropriate type.
-    // Make `src' the second operand, in case it is a constant
-    // Use (unsigned long) 0 for a NULL pointer value.
+    // Create a reg-to-reg copy instruction for the given type:
+    // -- For FP values, create a FMOVS or FMOVD instruction
+    // -- For non-FP values, create an add-with-0 instruction (opCode as above)
+    // Make `src' the second operand, in case it is a small constant!
     // 
-    const Type* Ty =isa<PointerType>(resultType) ? Type::ULongTy : resultType;
-    MachineInstr* MI =
-      BuildMI(opCode, 3).addReg(Constant::getNullValue(Ty))
-      .addReg(src).addRegDef(dest);
+    MachineInstr* MI;
+    if (resultType->isFloatingPoint())
+      MI = (BuildMI(resultType == Type::FloatTy? V9::FMOVS : V9::FMOVD, 2)
+            .addReg(src).addRegDef(dest));
+    else {
+        const Type* Ty =isa<PointerType>(resultType)? Type::ULongTy :resultType;
+        MI = (BuildMI(opCode, 3)
+              .addSImm((int64_t) 0).addReg(src).addRegDef(dest));
+    }
     mvec.push_back(MI);
   }
 }
@@ -670,9 +676,8 @@
 
   if (numLowBits < 32) {
     // SLL is needed since operand size is < 32 bits.
-    TmpInstruction *tmpI = new TmpInstruction(destVal->getType(),
+    TmpInstruction *tmpI = new TmpInstruction(mcfi, destVal->getType(),
                                               srcVal, destVal, "make32");
-    mcfi.addTemp(tmpI);
     mvec.push_back(BuildMI(V9::SLLXi6, 3).addReg(srcVal)
                    .addZImm(32-numLowBits).addRegDef(tmpI));
     srcVal = tmpI;


Index: llvm/lib/Target/Sparc/SparcInstrSelection.cpp
diff -u llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.98 llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.99
--- llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.98	Sat May 31 02:25:41 2003
+++ llvm/lib/Target/Sparc/SparcInstrSelection.cpp	Sat May 31 02:30:29 2003
@@ -126,12 +126,15 @@
       // Get pointer value out of ptrChild.
       ptrVal = gepInst->getPointerOperand();
 
-      // Remember if it has leading zero index: it will be discarded later.
-      lastInstHasLeadingNonZero = ! IsZero(*firstIdx);
-
       // Insert its index vector at the start, skipping any leading [0]
-      chainIdxVec.insert(chainIdxVec.begin(),
-                         firstIdx + !lastInstHasLeadingNonZero, lastIdx);
+      // Remember the old size to check if anything was inserted.
+      unsigned oldSize = chainIdxVec.size();
+      int firstIsZero = IsZero(*firstIdx);
+      chainIdxVec.insert(chainIdxVec.begin(), firstIdx + firstIsZero, lastIdx);
+
+      // Remember if it has leading zero index: it will be discarded later.
+      if (oldSize < chainIdxVec.size())
+        lastInstHasLeadingNonZero = !firstIsZero;
 
       // Mark the folded node so no code is generated for it.
       ((InstructionNode*) ptrChild)->markFoldedIntoParent();
@@ -143,7 +146,9 @@
   }
 
   // If the first getElementPtr instruction had a leading [0], add it back.
-  // Note that this instruction is the *last* one successfully folded above.
+  // Note that this instruction is the *last* one that was successfully
+  // folded *and* contributed any indices, in the loop above.
+  // 
   if (ptrVal && ! lastInstHasLeadingNonZero) 
     chainIdxVec.insert(chainIdxVec.begin(), ConstantSInt::get(Type::LongTy,0));
 
@@ -355,7 +360,8 @@
 // TmpInstructions will be freed along with the rest of the Function anyway.
 // 
 static TmpInstruction*
-GetTmpForCC(Value* boolVal, const Function *F, const Type* ccType)
+GetTmpForCC(Value* boolVal, const Function *F, const Type* ccType,
+            MachineCodeForInstruction& mcfi)
 {
   typedef hash_map<const Value*, TmpInstruction*> BoolTmpCache;
   static BoolTmpCache boolToTmpCache;     // Map boolVal -> TmpInstruction*
@@ -372,7 +378,7 @@
   // directly written to map using the ref returned by operator[].
   TmpInstruction*& tmpI = boolToTmpCache[boolVal];
   if (tmpI == NULL)
-    tmpI = new TmpInstruction(ccType, boolVal);
+    tmpI = new TmpInstruction(mcfi, ccType, boolVal);
   
   return tmpI;
 }
@@ -427,13 +433,9 @@
 // (The latter two cases do not seem to arise because SetNE needs nothing.)
 // 
 static MachineOpCode
-ChooseMovpccAfterSub(const InstructionNode* instrNode,
-                     bool& mustClearReg,
-                     int& valueToMove)
+ChooseMovpccAfterSub(const InstructionNode* instrNode)
 {
   MachineOpCode opCode = V9::INVALID_OPCODE;
-  mustClearReg = true;
-  valueToMove = 1;
   
   switch(instrNode->getInstruction()->getOpcode())
   {
@@ -442,8 +444,8 @@
   case Instruction::SetGE: opCode = V9::MOVGE; break;
   case Instruction::SetLT: opCode = V9::MOVL;  break;
   case Instruction::SetGT: opCode = V9::MOVG;  break;
-  case Instruction::SetNE: assert(0 && "No move required!"); break;
-  default:		     assert(0 && "Unrecognized VM instr!"); break; 
+  case Instruction::SetNE: opCode = V9::MOVNE; break;
+  default: assert(0 && "Unrecognized VM instr!"); break; 
   }
   
   return opCode;
@@ -452,45 +454,23 @@
 static inline MachineOpCode
 ChooseConvertToFloatInstr(OpLabel vopCode, const Type* opType)
 {
+  assert((vopCode == ToFloatTy || vopCode == ToDoubleTy) &&
+         "Unrecognized convert-to-float opcode!");
+
   MachineOpCode opCode = V9::INVALID_OPCODE;
   
-  switch(vopCode)
-  {
-  case ToFloatTy: 
-    if (opType == Type::SByteTy || opType == Type::ShortTy ||
-        opType == Type::IntTy)
-      opCode = V9::FITOS;
-    else if (opType == Type::LongTy)
-      opCode = V9::FXTOS;
-    else if (opType == Type::DoubleTy)
-      opCode = V9::FDTOS;
-    else if (opType == Type::FloatTy)
-      ;
-    else
-      assert(0 && "Cannot convert this type to FLOAT on SPARC");
-    break;
-      
-  case ToDoubleTy: 
-    // This is usually used in conjunction with CreateCodeToCopyIntToFloat().
-    // Both functions should treat the integer as a 32-bit value for types
-    // of 4 bytes or less, and as a 64-bit value otherwise.
-    if (opType == Type::SByteTy || opType == Type::UByteTy ||
-        opType == Type::ShortTy || opType == Type::UShortTy ||
-        opType == Type::IntTy   || opType == Type::UIntTy)
-      opCode = V9::FITOD;
-    else if (opType == Type::LongTy || opType == Type::ULongTy)
-      opCode = V9::FXTOD;
-    else if (opType == Type::FloatTy)
-      opCode = V9::FSTOD;
-    else if (opType == Type::DoubleTy)
-      ;
-    else
-      assert(0 && "Cannot convert this type to DOUBLE on SPARC");
-    break;
-      
-  default:
-    break;
-  }
+  if (opType == Type::SByteTy || opType == Type::UByteTy ||
+      opType == Type::ShortTy || opType == Type::UShortTy ||
+      opType == Type::IntTy   || opType == Type::UIntTy)
+      opCode = (vopCode == ToFloatTy? V9::FITOS : V9::FITOD);
+  else if (opType == Type::LongTy || opType == Type::ULongTy)
+      opCode = (vopCode == ToFloatTy? V9::FXTOS : V9::FXTOD);
+  else if (opType == Type::FloatTy)
+      opCode = (vopCode == ToFloatTy? V9::INVALID_OPCODE : V9::FSTOD);
+  else if (opType == Type::DoubleTy)
+      opCode = (vopCode == ToFloatTy? V9::FDTOS : V9::INVALID_OPCODE);
+  else
+    assert(0 && "Cannot convert this type to DOUBLE on SPARC");
   
   return opCode;
 }
@@ -503,6 +483,12 @@
   assert((opType == Type::FloatTy || opType == Type::DoubleTy)
          && "This function should only be called for FLOAT or DOUBLE");
 
+  // SPARC does not have a float-to-uint conversion, only a float-to-int.
+  // For converting an FP value to uint32_t, we first need to convert to
+  // uint64_t and then to uint32_t, or we may overflow the signed int
+  // representation even for legal uint32_t values.  This expansion is
+  // done by the Preselection pass.
+  // 
   if (tid == Type::UIntTyID) {
     assert(tid != Type::UIntTyID && "FP-to-uint conversions must be expanded"
            " into FP->long->uint for SPARC v9:  SO RUN PRESELECTION PASS!");
@@ -558,8 +544,7 @@
   // 
   size_t destSize = target.getTargetData().getTypeSize(destI->getType());
   const Type* destTypeToUse = (destSize > 4)? Type::DoubleTy : Type::FloatTy;
-  TmpInstruction* destForCast = new TmpInstruction(destTypeToUse, opVal);
-  mcfi.addTemp(destForCast);
+  TmpInstruction* destForCast = new TmpInstruction(mcfi, destTypeToUse, opVal);
 
   // Create the fp-to-int conversion code
   MachineInstr* M =CreateConvertFPToIntInstr(destI->getType()->getPrimitiveID(),
@@ -747,10 +732,10 @@
   // 
   Value* shiftDest = destVal;
   unsigned opSize = target.getTargetData().getTypeSize(argVal1->getType());
+
   if ((shiftOpCode == V9::SLLr6 || shiftOpCode == V9::SLLXr6) && opSize < 8) {
     // put SLL result into a temporary
-    shiftDest = new TmpInstruction(argVal1, optArgVal2, "sllTmp");
-    mcfi.addTemp(shiftDest);
+    shiftDest = new TmpInstruction(mcfi, argVal1, optArgVal2, "sllTmp");
   }
   
   MachineInstr* M = (optArgVal2 != NULL)
@@ -975,10 +960,8 @@
           TmpInstruction *srlTmp, *addTmp;
           MachineCodeForInstruction& mcfi
             = MachineCodeForInstruction::get(destVal);
-          srlTmp = new TmpInstruction(resultType, LHS, 0, "getSign");
-          addTmp = new TmpInstruction(resultType, LHS, srlTmp, "incIfNeg");
-          mcfi.addTemp(srlTmp);
-          mcfi.addTemp(addTmp);
+          srlTmp = new TmpInstruction(mcfi, resultType, LHS, 0, "getSign");
+          addTmp = new TmpInstruction(mcfi, resultType, LHS, srlTmp,"incIfNeg");
 
           // Create the SRL or SRLX instruction to get the sign bit
           mvec.push_back(BuildMI((resultType==Type::LongTy) ?
@@ -1055,12 +1038,9 @@
 
     // Create temporary values to hold the result of MUL, SLL, SRL
     // THIS CASE IS INCOMPLETE AND WILL BE FIXED SHORTLY.
-    TmpInstruction* tmpProd = new TmpInstruction(numElementsVal, tsizeVal);
-    TmpInstruction* tmpSLL  = new TmpInstruction(numElementsVal, tmpProd);
-    TmpInstruction* tmpSRL  = new TmpInstruction(numElementsVal, tmpSLL);
-    mcfi.addTemp(tmpProd);
-    mcfi.addTemp(tmpSLL);
-    mcfi.addTemp(tmpSRL);
+    TmpInstruction* tmpProd = new TmpInstruction(mcfi,numElementsVal, tsizeVal);
+    TmpInstruction* tmpSLL  = new TmpInstruction(mcfi,numElementsVal, tmpProd);
+    TmpInstruction* tmpSRL  = new TmpInstruction(mcfi,numElementsVal, tmpSLL);
 
     // Instruction 1: mul numElements, typeSize -> tmpProd
     // This will optimize the MUL as far as possible.
@@ -1195,8 +1175,9 @@
       Value* idxVal = idxVec[firstIdxIsZero];
 
       std::vector<MachineInstr*> mulVec;
-      Instruction* addr = new TmpInstruction(Type::ULongTy, memInst);
-      MachineCodeForInstruction::get(memInst).addTemp(addr);
+      Instruction* addr =
+        new TmpInstruction(MachineCodeForInstruction::get(memInst),
+                           Type::ULongTy, memInst);
 
       // Get the array type indexed by idxVal, and compute its element size.
       // The call to getTypeSize() will fail if size is not constant.
@@ -1463,24 +1444,62 @@
       case 2:	// stmt:   RetValue(reg)
       {         // NOTE: Prepass of register allocation is responsible
                 //	 for moving return value to appropriate register.
+                // Copy the return value to the required return register.
+                // Mark the return Value as an implicit ref of the RET instr..
                 // Mark the return-address register as a hidden virtual reg.
-                // Mark the return value   register as an implicit ref of
-                // the machine instruction.
          	// Finally put a NOP in the delay slot.
-        ReturnInst *returnInstr =
-          cast<ReturnInst>(subtreeRoot->getInstruction());
-        assert(returnInstr->getOpcode() == Instruction::Ret);
-        
-        Instruction* returnReg = new TmpInstruction(returnInstr);
-        MachineCodeForInstruction::get(returnInstr).addTemp(returnReg);
-        
-        M = BuildMI(V9::JMPLRETi, 3).addReg(returnReg).addSImm(8)
+        ReturnInst *returnInstr=cast<ReturnInst>(subtreeRoot->getInstruction());
+        Value* retVal = returnInstr->getReturnValue();
+        MachineCodeForInstruction& mcfi =
+          MachineCodeForInstruction::get(returnInstr);
+
+        // Create a hidden virtual reg to represent the return address register
+        // used by the machine instruction but not represented in LLVM.
+        // 
+        Instruction* returnAddrTmp = new TmpInstruction(mcfi, returnInstr);
+
+        MachineInstr* retMI = 
+          BuildMI(V9::JMPLRETi, 3).addReg(returnAddrTmp).addSImm(8)
           .addMReg(target.getRegInfo().getZeroRegNum(), MOTy::Def);
+      
+        // Insert a copy to copy the return value to the appropriate register
+        // -- For FP values, create a FMOVS or FMOVD instruction
+        // -- For non-FP values, create an add-with-0 instruction
+        // 
+        if (retVal != NULL) {
+          const UltraSparcRegInfo& regInfo =
+            (UltraSparcRegInfo&) target.getRegInfo();
+          const Type* retType = retVal->getType();
+          unsigned regClassID = regInfo.getRegClassIDOfType(retType);
+          unsigned retRegNum = (retType->isFloatingPoint()
+                                ? (unsigned) SparcFloatRegClass::f0
+                                : (unsigned) SparcIntRegClass::i0);
+          retRegNum = regInfo.getUnifiedRegNum(regClassID, retRegNum);
+
+          // Create a virtual register to represent it and mark
+          // this vreg as being an implicit operand of the ret MI
+          TmpInstruction* retVReg = 
+            new TmpInstruction(mcfi, retVal, NULL, "argReg");
+            
+          retMI->addImplicitRef(retVReg);
+            
+          if (retType->isFloatingPoint())
+            M = (BuildMI(retType==Type::FloatTy? V9::FMOVS : V9::FMOVD, 2)
+                 .addReg(retVal).addReg(retVReg, MOTy::Def));
+          else
+            M = (BuildMI(ChooseAddInstructionByType(retType), 3)
+                 .addReg(retVal).addSImm((int64_t) 0)
+                 .addReg(retVReg, MOTy::Def));
+
+          // Mark the operand with the register it should be assigned
+          M->SetRegForOperand(M->getNumOperands()-1, retRegNum);
+          retMI->SetRegForImplicitRef(retMI->getNumImplicitRefs()-1, retRegNum);
+
+          mvec.push_back(M);
+        }
         
-        if (returnInstr->getReturnValue() != NULL)
-          M->addImplicitRef(returnInstr->getReturnValue());
-        
-        mvec.push_back(M);
+        // Now insert the RET instruction and a NOP for the delay slot
+        mvec.push_back(retMI);
         mvec.push_back(BuildMI(V9::NOP, 0));
         
         break;
@@ -1560,7 +1579,8 @@
         unsigned Opcode = ChooseBccInstruction(subtreeRoot, isFPBranch);
         Value* ccValue = GetTmpForCC(subtreeRoot->leftChild()->getValue(),
                                      brInst->getParent()->getParent(),
-                                     isFPBranch? Type::FloatTy : Type::IntTy);
+                                     isFPBranch? Type::FloatTy : Type::IntTy,
+                                     MachineCodeForInstruction::get(brInst));
         M = BuildMI(Opcode, 2).addCCReg(ccValue)
                               .addPCDisp(brInst->getSuccessor(0));
         mvec.push_back(M);
@@ -1593,8 +1613,8 @@
       }
         
       case   8:	// stmt:   BrCond(boolreg)
-      { // boolreg   => boolean is stored in an existing register.
-        // Just use the branch-on-integer-register instruction!
+      { // boolreg   => boolean is recorded in an integer register.
+        //              Use branch-on-integer-register instruction.
         // 
         BranchInst *BI = cast<BranchInst>(subtreeRoot->getInstruction());
         M = BuildMI(V9::BRNZ, 2).addReg(subtreeRoot->leftChild()->getValue())
@@ -1769,10 +1789,9 @@
                 target.getTargetData().getTypeSize(leftVal->getType());
               Type* tmpTypeToUse =
                 (srcSize <= 4)? Type::FloatTy : Type::DoubleTy;
-              srcForCast = new TmpInstruction(tmpTypeToUse, dest);
               MachineCodeForInstruction &destMCFI = 
                 MachineCodeForInstruction::get(dest);
-              destMCFI.addTemp(srcForCast);
+              srcForCast = new TmpInstruction(destMCFI, tmpTypeToUse, dest);
 
               target.getInstrInfo().CreateCodeToCopyIntToFloat(target,
                          dest->getParent()->getParent(),
@@ -1878,14 +1897,14 @@
       {
         maskUnsignedResult = true;
         Instruction* remInstr = subtreeRoot->getInstruction();
-        
-        TmpInstruction* quot = new TmpInstruction(
+
+        MachineCodeForInstruction& mcfi=MachineCodeForInstruction::get(remInstr);
+        TmpInstruction* quot = new TmpInstruction(mcfi,
                                         subtreeRoot->leftChild()->getValue(),
                                         subtreeRoot->rightChild()->getValue());
-        TmpInstruction* prod = new TmpInstruction(
+        TmpInstruction* prod = new TmpInstruction(mcfi,
                                         quot,
                                         subtreeRoot->rightChild()->getValue());
-        MachineCodeForInstruction::get(remInstr).addTemp(quot).addTemp(prod); 
         
         M = BuildMI(ChooseDivInstruction(target, subtreeRoot), 3)
                              .addReg(subtreeRoot->leftChild()->getValue())
@@ -1982,34 +2001,21 @@
         // 
       case 42:	// bool:   SetCC(reg, reg):
       {
-        // This generates a SUBCC instruction, putting the difference in
-        // a result register, and setting a condition code.
+        // This generates a SUBCC instruction, putting the difference in a
+        // result reg. if needed, and/or setting a condition code if needed.
         // 
-        // If the boolean result of the SetCC is used by anything other
-        // than a branch instruction, or if it is used outside the current
-        // basic block, the boolean must be
-        // computed and stored in the result register.  Otherwise, discard
-        // the difference (by using %g0) and keep only the condition code.
-        // 
-        // To compute the boolean result in a register we use a conditional
-        // move, unless the result of the SUBCC instruction can be used as
-        // the bool!  This assumes that zero is FALSE and any non-zero
-        // integer is TRUE.
-        // 
-        InstructionNode* parentNode = (InstructionNode*) subtreeRoot->parent();
         Instruction* setCCInstr = subtreeRoot->getInstruction();
+        Value* leftVal = subtreeRoot->leftChild()->getValue();
+        bool isFPCompare = leftVal->getType()->isFloatingPoint();
         
-        bool keepBoolVal = parentNode == NULL ||
-                           ! AllUsesAreBranches(setCCInstr);
-        bool subValIsBoolVal = setCCInstr->getOpcode() == Instruction::SetNE;
-        bool keepSubVal = keepBoolVal && subValIsBoolVal;
-        bool computeBoolVal = keepBoolVal && ! subValIsBoolVal;
-        
-        bool mustClearReg;
-        int valueToMove;
-        MachineOpCode movOpCode = 0;
+        // If the boolean result of the SetCC is used outside the current basic
+        // block (so it must be computed as a boolreg) or is used by anything
+        // other than a branch, the boolean must be computed and stored
+        // in a result register.  We will use a conditional move to do this.
+        // 
+        bool computeBoolVal = (subtreeRoot->parent() == NULL ||
+                               ! AllUsesAreBranches(setCCInstr));
         
-        // Mark the 4th operand as being a CC register, and as a def
         // A TmpInstruction is created to represent the CC "result".
         // Unlike other instances of TmpInstruction, this one is used
         // by machine code of multiple LLVM instructions, viz.,
@@ -2019,74 +2025,47 @@
         // needs to be a floating point condition code, not an integer
         // condition code.  Think of this as casting the bool result to
         // a FP condition code register.
+        // Later, we mark the 4th operand as being a CC register, and as a def.
         // 
-        Value* leftVal = subtreeRoot->leftChild()->getValue();
-        bool isFPCompare = leftVal->getType()->isFloatingPoint();
-        
         TmpInstruction* tmpForCC = GetTmpForCC(setCCInstr,
-                                     setCCInstr->getParent()->getParent(),
-                                     isFPCompare ? Type::FloatTy : Type::IntTy);
-        MachineCodeForInstruction::get(setCCInstr).addTemp(tmpForCC);
-        
+                                    setCCInstr->getParent()->getParent(),
+                                    isFPCompare ? Type::FloatTy : Type::IntTy,
+                                    MachineCodeForInstruction::get(setCCInstr));
         if (! isFPCompare) {
-          // Integer condition: dest. should be %g0 or an integer register.
-          // If result must be saved but condition is not SetEQ then we need
-          // a separate instruction to compute the bool result, so discard
-          // result of SUBcc instruction anyway.
-          // 
-          if (keepSubVal) {
-            M = BuildMI(V9::SUBccr, 4)
-              .addReg(subtreeRoot->leftChild()->getValue())
-              .addReg(subtreeRoot->rightChild()->getValue())
-              .addRegDef(subtreeRoot->getValue())
-              .addCCReg(tmpForCC, MOTy::Def);
-          } else {
-            M = BuildMI(V9::SUBccr, 4)
-              .addReg(subtreeRoot->leftChild()->getValue())
-              .addReg(subtreeRoot->rightChild()->getValue())
-              .addMReg(target.getRegInfo().getZeroRegNum(), MOTy::Def)
-              .addCCReg(tmpForCC, MOTy::Def);
-          }
-          mvec.push_back(M);
-            
-          if (computeBoolVal) {
-            // recompute bool using the integer condition codes
-            movOpCode =
-              ChooseMovpccAfterSub(subtreeRoot,mustClearReg,valueToMove);
-          }
+          // Integer condition: set CC and discard result.
+          M = BuildMI(V9::SUBccr, 4)
+            .addReg(subtreeRoot->leftChild()->getValue())
+            .addReg(subtreeRoot->rightChild()->getValue())
+            .addMReg(target.getRegInfo().getZeroRegNum(), MOTy::Def)
+            .addCCReg(tmpForCC, MOTy::Def);
         } else {
           // FP condition: dest of FCMP should be some FCCn register
           M = BuildMI(ChooseFcmpInstruction(subtreeRoot), 3)
             .addCCReg(tmpForCC, MOTy::Def)
             .addReg(subtreeRoot->leftChild()->getValue())
-            .addRegDef(subtreeRoot->rightChild()->getValue());
-          mvec.push_back(M);
-            
-          if (computeBoolVal) {
-            // recompute bool using the FP condition codes
-            mustClearReg = true;
-            valueToMove = 1;
-            movOpCode = ChooseMovFpccInstruction(subtreeRoot);
-          }
+            .addReg(subtreeRoot->rightChild()->getValue());
         }
+        mvec.push_back(M);
         
         if (computeBoolVal) {
-          if (mustClearReg) {
-            // Unconditionally set register to 0
-            M = BuildMI(V9::SETHI, 2).addZImm(0).addRegDef(setCCInstr);
-            mvec.push_back(M);
-          }
-            
-          // Now conditionally move `valueToMove' (0 or 1) into the register
+          MachineOpCode movOpCode = (isFPCompare
+                                     ? ChooseMovFpccInstruction(subtreeRoot)
+                                     : ChooseMovpccAfterSub(subtreeRoot));
+
+          // Unconditionally set register to 0
+          M = BuildMI(V9::SETHI, 2).addZImm(0).addRegDef(setCCInstr);
+          mvec.push_back(M);
+          
+          // Now conditionally move 1 into the register.
           // Mark the register as a use (as well as a def) because the old
-          // value should be retained if the condition is false.
-          M = BuildMI(movOpCode, 3).addCCReg(tmpForCC).addZImm(valueToMove)
-            .addReg(setCCInstr, MOTy::UseAndDef);
+          // value will be retained if the condition is false.
+          M = (BuildMI(movOpCode, 3).addCCReg(tmpForCC).addZImm(1)
+               .addReg(setCCInstr, MOTy::UseAndDef));
           mvec.push_back(M);
         }
         break;
-      }
-
+      }    
+      
       case 51:	// reg:   Load(reg)
       case 52:	// reg:   Load(ptrreg)
         SetOperandsForMemInstr(ChooseLoadInstruction(
@@ -2125,18 +2104,17 @@
         Value* numElementsVal = NULL;
         bool isArray = instr->isArrayAllocation();
         
-        if (!isArray ||
-            isa<Constant>(numElementsVal = instr->getArraySize()))
-        { 
+        if (!isArray || isa<Constant>(numElementsVal = instr->getArraySize())) {
           // total size is constant: generate code for fixed-size alloca
           unsigned numElements = isArray? 
             cast<ConstantUInt>(numElementsVal)->getValue() : 1;
           CreateCodeForFixedSizeAlloca(target, instr, tsize,
                                        numElements, mvec);
-        }
-        else // total size is not constant.
+        } else {
+          // total size is not constant.
           CreateCodeForVariableSizeAlloca(target, instr, tsize,
                                           numElementsVal, mvec);
+        }
         break;
       }
 
@@ -2167,26 +2145,34 @@
         // This can also handle any intrinsics that are just function calls.
         // 
         if (! specialIntrinsic) {
+          MachineFunction& MF =
+            MachineFunction::get(callInstr->getParent()->getParent());
+          MachineCodeForInstruction& mcfi =
+            MachineCodeForInstruction::get(callInstr); 
+          const UltraSparcRegInfo& regInfo =
+            (UltraSparcRegInfo&) target.getRegInfo();
+          const TargetFrameInfo& frameInfo = target.getFrameInfo();
+
           // Create hidden virtual register for return address with type void*
           TmpInstruction* retAddrReg =
-            new TmpInstruction(PointerType::get(Type::VoidTy), callInstr);
-          MachineCodeForInstruction::get(callInstr).addTemp(retAddrReg);
+            new TmpInstruction(mcfi, PointerType::get(Type::VoidTy), callInstr);
 
           // Generate the machine instruction and its operands.
           // Use CALL for direct function calls; this optimistically assumes
           // the PC-relative address fits in the CALL address field (22 bits).
           // Use JMPL for indirect calls.
+          // This will be added to mvec later, after operand copies.
           // 
+          MachineInstr* callMI;
           if (calledFunc)             // direct function call
-            M = BuildMI(V9::CALL, 1).addPCDisp(callee);
+            callMI = BuildMI(V9::CALL, 1).addPCDisp(callee);
           else                        // indirect function call
-            M = BuildMI(V9::JMPLCALLi, 3).addReg(callee).addSImm((int64_t)0)
-              .addRegDef(retAddrReg);
-          mvec.push_back(M);
+            callMI = (BuildMI(V9::JMPLCALLi,3).addReg(callee)
+                      .addSImm((int64_t)0).addRegDef(retAddrReg));
 
           const FunctionType* funcType =
             cast<FunctionType>(cast<PointerType>(callee->getType())
-                                 ->getElementType());
+                               ->getElementType());
           bool isVarArgs = funcType->isVarArg();
           bool noPrototype = isVarArgs && funcType->getNumParams() == 0;
         
@@ -2194,64 +2180,213 @@
           // to the register allocator.  This descriptor will be "owned"
           // and freed automatically when the MachineCodeForInstruction
           // object for the callInstr goes away.
-          CallArgsDescriptor* argDesc = new CallArgsDescriptor(callInstr,
-                                             retAddrReg, isVarArgs,noPrototype);
-            
+          CallArgsDescriptor* argDesc =
+            new CallArgsDescriptor(callInstr, retAddrReg,isVarArgs,noPrototype);
           assert(callInstr->getOperand(0) == callee
                  && "This is assumed in the loop below!");
-            
+          
+          // Insert copy instructions to get all the arguments into
+          // all the places that they need to be.
+          // 
           for (unsigned i=1, N=callInstr->getNumOperands(); i < N; ++i) {
+            int argNo = i-1;
             Value* argVal = callInstr->getOperand(i);
-            Instruction* intArgReg = NULL;
-            
+            const Type* argType = argVal->getType();
+            unsigned regType = regInfo.getRegType(argType);
+            unsigned argSize = target.getTargetData().getTypeSize(argType);
+            int regNumForArg = TargetRegInfo::getInvalidRegNum();
+            unsigned regClassIDOfArgReg;
+            CallArgInfo& argInfo = argDesc->getArgInfo(argNo);
+
             // Check for FP arguments to varargs functions.
             // Any such argument in the first $K$ args must be passed in an
-            // integer register, where K = #integer argument registers.
-            if (isVarArgs && argVal->getType()->isFloatingPoint()) {
+            // integer register.  If there is no prototype, it must also
+            // be passed as an FP register.
+            // K = #integer argument registers.
+            bool isFPArg = argVal->getType()->isFloatingPoint();
+            if (isVarArgs && isFPArg) {
               // If it is a function with no prototype, pass value
               // as an FP value as well as a varargs value
               if (noPrototype)
-                argDesc->getArgInfo(i-1).setUseFPArgReg();
+                argInfo.setUseFPArgReg();
                 
-              // If this arg. is in the first $K$ regs, add a copy
-              // float-to-int instruction to pass the value as an integer.
-              if (i <= target.getRegInfo().getNumOfIntArgRegs()) {
-                MachineCodeForInstruction &destMCFI = 
-                  MachineCodeForInstruction::get(callInstr);   
-                intArgReg = new TmpInstruction(Type::IntTy, argVal);
-                destMCFI.addTemp(intArgReg);
-                    
-                std::vector<MachineInstr*> copyMvec;
-                target.getInstrInfo().CreateCodeToCopyFloatToInt(target,
-                                         callInstr->getParent()->getParent(),
-                                         argVal, (TmpInstruction*) intArgReg,
-                                         copyMvec, destMCFI);
-                mvec.insert(mvec.begin(),copyMvec.begin(),copyMvec.end());
+              // If this arg. is in the first $K$ regs, add copy-
+              // float-to-int instructions to pass the value as an int.
+              // To check if it is in teh first $K$, get the register
+              // number for the arg #i.
+              int copyRegNum = regInfo.regNumForIntArg(false, false,
+                                                       argNo, regClassIDOfArgReg);
+              if (copyRegNum != regInfo.getInvalidRegNum()) {
+                // Create a virtual register to represent copyReg. Mark
+                // this vreg as being an implicit operand of the call MI
+                const Type* loadTy = (argType == Type::FloatTy
+                                      ? Type::IntTy : Type::LongTy);
+                TmpInstruction* argVReg= new TmpInstruction(mcfi,loadTy,
+                                                            argVal, NULL, "argRegCopy");
+                callMI->addImplicitRef(argVReg);
+                        
+                // Get a temp stack location to use to copy
+                // float-to-int via the stack.
+                // 
+                // FIXME: For now, we allocate permanent space because
+                // the stack frame manager does not allow locals to be
+                // allocated (e.g., for alloca) after a temp is
+                // allocated!
+                // 
+                // int tmpOffset = MF.getInfo()->pushTempValue(argSize);
+                int tmpOffset = MF.getInfo()->allocateLocalVar(argVReg);
                     
-                argDesc->getArgInfo(i-1).setUseIntArgReg();
-                argDesc->getArgInfo(i-1).setArgCopy(intArgReg);
-              } else
+                // Generate the store from FP reg to stack
+                M = BuildMI(ChooseStoreInstruction(argType), 3)
+                  .addReg(argVal).addMReg(regInfo.getFramePointer())
+                  .addSImm(tmpOffset);
+                mvec.push_back(M);
+                        
+                // Generate the load from stack to int arg reg
+                M = BuildMI(ChooseLoadInstruction(loadTy), 3)
+                  .addMReg(regInfo.getFramePointer()).addSImm(tmpOffset)
+                  .addReg(argVReg, MOTy::Def);
+
+                // Mark operand with register it should be assigned
+                // both for copy and for the callMI
+                M->SetRegForOperand(M->getNumOperands()-1, copyRegNum);
+                callMI->SetRegForImplicitRef(
+                                             callMI->getNumImplicitRefs()-1, copyRegNum);
+
+                mvec.push_back(M);
+
+                // Add info about the argument to the CallArgsDescriptor
+                argInfo.setUseIntArgReg();
+                argInfo.setArgCopy(copyRegNum);
+              } else {
                 // Cannot fit in first $K$ regs so pass arg on stack
-                argDesc->getArgInfo(i-1).setUseStackSlot();
+                argInfo.setUseStackSlot();
+              }
+            } else if (isFPArg) {
+              // Get the outgoing arg reg to see if there is one.
+              regNumForArg = regInfo.regNumForFPArg(regType, false, false,
+                                                    argNo, regClassIDOfArgReg);
+              if (regNumForArg == regInfo.getInvalidRegNum())
+                argInfo.setUseStackSlot();
+              else {
+                argInfo.setUseFPArgReg();
+                regNumForArg =regInfo.getUnifiedRegNum(regClassIDOfArgReg,
+                                                       regNumForArg);
+              }
+            } else {
+              // Get the outgoing arg reg to see if there is one.
+              regNumForArg = regInfo.regNumForIntArg(false,false,
+                                                     argNo, regClassIDOfArgReg);
+              if (regNumForArg == regInfo.getInvalidRegNum())
+                argInfo.setUseStackSlot();
+              else {
+                argInfo.setUseIntArgReg();
+                regNumForArg =regInfo.getUnifiedRegNum(regClassIDOfArgReg,
+                                                       regNumForArg);
+              }
+            }                
+
+            // 
+            // Now insert copy instructions to stack slot or arg. register
+            // 
+            if (argInfo.usesStackSlot()) {
+              // Get the stack offset for this argument slot.
+              // FP args on stack are right justified so adjust offset!
+              // int arguments are also right justified but they are
+              // always loaded as a full double-word so the offset does
+              // not need to be adjusted.
+              int argOffset = frameInfo.getOutgoingArgOffset(MF, argNo);
+              if (argType->isFloatingPoint()) {
+                unsigned slotSize = frameInfo.getSizeOfEachArgOnStack();
+                assert(argSize <= slotSize && "Insufficient slot size!");
+                argOffset += slotSize - argSize;
+              }
+
+              // Now generate instruction to copy argument to stack
+              MachineOpCode storeOpCode =
+                (argType->isFloatingPoint()
+                 ? ((argSize == 4)? V9::STFi : V9::STDFi) : V9::STXi);
+
+              M = BuildMI(storeOpCode, 3).addReg(argVal)
+                .addMReg(regInfo.getStackPointer()).addSImm(argOffset);
+              mvec.push_back(M);
+            } else {
+              // Create a virtual register to represent the arg reg. Mark
+              // this vreg as being an implicit operand of the call MI.
+              TmpInstruction* argVReg = 
+                new TmpInstruction(mcfi, argVal, NULL, "argReg");
+
+              callMI->addImplicitRef(argVReg);
+                    
+              // Generate the reg-to-reg copy into the outgoing arg reg.
+              // -- For FP values, create a FMOVS or FMOVD instruction
+              // -- For non-FP values, create an add-with-0 instruction
+              if (argType->isFloatingPoint())
+                M=(BuildMI(argType==Type::FloatTy? V9::FMOVS :V9::FMOVD,2)
+                   .addReg(argVal).addReg(argVReg, MOTy::Def));
+              else
+                M = (BuildMI(ChooseAddInstructionByType(argType), 3)
+                     .addReg(argVal).addSImm((int64_t) 0)
+                     .addReg(argVReg, MOTy::Def));
+                    
+              // Mark the operand with the register it should be assigned
+              M->SetRegForOperand(M->getNumOperands()-1, regNumForArg);
+              callMI->SetRegForImplicitRef(callMI->getNumImplicitRefs()-1,
+                                           regNumForArg);
+
+              mvec.push_back(M);
             }
-            
-            if (intArgReg)
-              mvec.back()->addImplicitRef(intArgReg);
-            
-            mvec.back()->addImplicitRef(argVal);
           }
-        
+
+          // add call instruction and delay slot before copying return value
+          mvec.push_back(callMI);
+          mvec.push_back(BuildMI(V9::NOP, 0));
+
           // Add the return value as an implicit ref.  The call operands
-          // were added above.
-          if (callInstr->getType() != Type::VoidTy)
-            mvec.back()->addImplicitRef(callInstr, /*isDef*/ true);
-        
+          // were added above.  Also, add code to copy out the return value.
+          // This is always register-to-register for int or FP return values.
+          // 
+          if (callInstr->getType() != Type::VoidTy) { 
+            // Get the return value reg.
+            const Type* retType = callInstr->getType();
+
+            int regNum = (retType->isFloatingPoint()
+                          ? (unsigned) SparcFloatRegClass::f0 
+                          : (unsigned) SparcIntRegClass::o0);
+            unsigned regClassID = regInfo.getRegClassIDOfType(retType);
+            regNum = regInfo.getUnifiedRegNum(regClassID, regNum);
+
+            // Create a virtual register to represent it and mark
+            // this vreg as being an implicit operand of the call MI
+            TmpInstruction* retVReg = 
+              new TmpInstruction(mcfi, callInstr, NULL, "argReg");
+
+            callMI->addImplicitRef(retVReg, /*isDef*/ true);
+
+            // Generate the reg-to-reg copy from the return value reg.
+            // -- For FP values, create a FMOVS or FMOVD instruction
+            // -- For non-FP values, create an add-with-0 instruction
+            if (retType->isFloatingPoint())
+              M = (BuildMI(retType==Type::FloatTy? V9::FMOVS : V9::FMOVD, 2)
+                   .addReg(retVReg).addReg(callInstr, MOTy::Def));
+            else
+              M = (BuildMI(ChooseAddInstructionByType(retType), 3)
+                   .addReg(retVReg).addSImm((int64_t) 0)
+                   .addReg(callInstr, MOTy::Def));
+
+            // Mark the operand with the register it should be assigned
+            // Also mark the implicit ref of the call defining this operand
+            M->SetRegForOperand(0, regNum);
+            callMI->SetRegForImplicitRef(callMI->getNumImplicitRefs()-1,regNum);
+
+            mvec.push_back(M);
+          }
+
           // For the CALL instruction, the ret. addr. reg. is also implicit
           if (isa<Function>(callee))
-            mvec.back()->addImplicitRef(retAddrReg, /*isDef*/ true);
-        
-          // delay slot
-          mvec.push_back(BuildMI(V9::NOP, 0));
+            callMI->addImplicitRef(retAddrReg, /*isDef*/ true);
+
+          MF.getInfo()->popAllTempValues();  // free temps used for this inst
         }
 
         break;
@@ -2345,9 +2480,9 @@
         // intermediate result before masking.  Since those instructions
         // have already been generated, go back and substitute tmpI
         // for dest in the result position of each one of them.
-        TmpInstruction *tmpI = new TmpInstruction(dest->getType(), dest,
-                                                  NULL, "maskHi");
-        MachineCodeForInstruction::get(dest).addTemp(tmpI);
+        TmpInstruction *tmpI =
+          new TmpInstruction(MachineCodeForInstruction::get(dest),
+                             dest->getType(), dest, NULL, "maskHi");
 
         for (unsigned i=0, N=mvec.size(); i < N; ++i)
           mvec[i]->substituteValue(dest, tmpI);


Index: llvm/lib/Target/Sparc/SparcInternals.h
diff -u llvm/lib/Target/Sparc/SparcInternals.h:1.88 llvm/lib/Target/Sparc/SparcInternals.h:1.89
--- llvm/lib/Target/Sparc/SparcInternals.h:1.88	Fri May 30 15:12:42 2003
+++ llvm/lib/Target/Sparc/SparcInternals.h	Sat May 31 02:30:29 2003
@@ -272,12 +272,6 @@
   //
   unsigned const NumOfFloatArgRegs;
 
-  // An out of bound register number that can be used to initialize register
-  // numbers. Useful for error detection.
-  //
-  int const InvalidRegNum;
-
-
   // ========================  Private Methods =============================
 
   // The following methods are used to color special live ranges (e.g.
@@ -295,13 +289,9 @@
                              int  UniArgReg, unsigned int argNo,
                              std::vector<MachineInstr *>& AddedInstrnsBefore)
     const;
-  
-  // Get the register type for a register identified different ways.
-  // The first function is a helper used by the all the hoter functions.
+
+  // Helper used by the all the getRegType() functions.
   int getRegTypeForClassAndType(unsigned regClassID, const Type* type) const;
-  int getRegType(const Type* type) const;
-  int getRegType(const LiveRange *LR) const;
-  int getRegType(int unifiedRegNum) const;
 
   // Used to generate a copy instruction based on the register class of
   // value.
@@ -322,17 +312,6 @@
                          std::vector<MachineInstr *> &OrdVec,
                          PhyRegAlloc &PRA) const;
 
-
-  // Compute which register can be used for an argument, if any
-  // 
-  int regNumForIntArg(bool inCallee, bool isVarArgsCall,
-                      unsigned argNo, unsigned intArgNo, unsigned fpArgNo,
-                      unsigned& regClassId) const;
-
-  int regNumForFPArg(unsigned RegType, bool inCallee, bool isVarArgsCall,
-                     unsigned argNo, unsigned intArgNo, unsigned fpArgNo,
-                     unsigned& regClassId) const;
-  
 public:
   // Type of registers available in Sparc. There can be several reg types
   // in the same class. For instace, the float reg class has Single/Double
@@ -380,6 +359,14 @@
   unsigned const getNumOfIntArgRegs() const   { return NumOfIntArgRegs; }
   unsigned const getNumOfFloatArgRegs() const { return NumOfFloatArgRegs; }
   
+  // Compute which register can be used for an argument, if any
+  // 
+  int regNumForIntArg(bool inCallee, bool isVarArgsCall,
+                      unsigned argNo, unsigned& regClassId) const;
+
+  int regNumForFPArg(unsigned RegType, bool inCallee, bool isVarArgsCall,
+                     unsigned argNo, unsigned& regClassId) const;
+  
   // The following methods are used to color special live ranges (e.g.
   // function args and return values etc.) with specific hardware registers
   // as required. See SparcRegInfo.cpp for the implementation for Sparc.
@@ -458,13 +445,13 @@
     return MachineRegClassArr[RegClassID]->isRegVolatile(Reg);
   }
 
+  // Get the register type for a register identified different ways.
+  int getRegType(const Type* type) const;
+  int getRegType(const LiveRange *LR) const;
+  int getRegType(int unifiedRegNum) const;
 
   virtual unsigned getFramePointer() const;
   virtual unsigned getStackPointer() const;
-
-  virtual int getInvalidRegNum() const {
-    return InvalidRegNum;
-  }
 
   // This method inserts the caller saving code for call instructions
   //


Index: llvm/lib/Target/Sparc/SparcRegInfo.cpp
diff -u llvm/lib/Target/Sparc/SparcRegInfo.cpp:1.95 llvm/lib/Target/Sparc/SparcRegInfo.cpp:1.96
--- llvm/lib/Target/Sparc/SparcRegInfo.cpp:1.95	Tue May 27 17:40:34 2003
+++ llvm/lib/Target/Sparc/SparcRegInfo.cpp	Sat May 31 02:30:29 2003
@@ -25,9 +25,8 @@
 };
 
 UltraSparcRegInfo::UltraSparcRegInfo(const UltraSparc &tgt)
-  : TargetRegInfo(tgt), NumOfIntArgRegs(6), 
-    NumOfFloatArgRegs(32), InvalidRegNum(1000) {
-   
+  : TargetRegInfo(tgt), NumOfIntArgRegs(6), NumOfFloatArgRegs(32)
+{
   MachineRegClassArr.push_back(new SparcIntRegClass(IntRegClassID));
   MachineRegClassArr.push_back(new SparcFloatRegClass(FloatRegClassID));
   MachineRegClassArr.push_back(new SparcIntCCRegClass(IntCCRegClassID));
@@ -157,56 +156,48 @@
 }
 
 
-// Get the register number for the specified integer arg#,
-// assuming there are argNum total args, intArgNum int args,
-// and fpArgNum FP args preceding (and not including) this one.
-// Use INT regs for FP args if this is a varargs call.
+// Get the register number for the specified argument #argNo,
 // 
 // Return value:
-//      InvalidRegNum,  if there is no int register available for the arg. 
-//      regNum,         otherwise (this is NOT the unified reg. num).
+//      getInvalidRegNum(),  if there is no int register available for the arg. 
+//      regNum,              otherwise (this is NOT the unified reg. num).
+//                           regClassId is set to the register class ID.
 // 
-inline int
+int
 UltraSparcRegInfo::regNumForIntArg(bool inCallee, bool isVarArgsCall,
-                                   unsigned argNo,
-                                   unsigned intArgNo, unsigned fpArgNo,
-                                   unsigned& regClassId) const
+                                   unsigned argNo, unsigned& regClassId) const
 {
   regClassId = IntRegClassID;
   if (argNo >= NumOfIntArgRegs)
-    return InvalidRegNum;
+    return getInvalidRegNum();
   else
     return argNo + (inCallee? SparcIntRegClass::i0 : SparcIntRegClass::o0);
 }
 
-// Get the register number for the specified FP arg#,
-// assuming there are argNum total args, intArgNum int args,
-// and fpArgNum FP args preceding (and not including) this one.
+// Get the register number for the specified FP argument #argNo,
 // Use INT regs for FP args if this is a varargs call.
 // 
 // Return value:
-//      InvalidRegNum,  if there is no int register available for the arg. 
-//      regNum,         otherwise (this is NOT the unified reg. num).
+//      getInvalidRegNum(),  if there is no int register available for the arg. 
+//      regNum,              otherwise (this is NOT the unified reg. num).
+//                           regClassId is set to the register class ID.
 // 
-inline int
+int
 UltraSparcRegInfo::regNumForFPArg(unsigned regType,
                                   bool inCallee, bool isVarArgsCall,
-                                  unsigned argNo,
-                                  unsigned intArgNo, unsigned fpArgNo,
-                                  unsigned& regClassId) const
+                                  unsigned argNo, unsigned& regClassId) const
 {
   if (isVarArgsCall)
-    return regNumForIntArg(inCallee, isVarArgsCall, argNo, intArgNo, fpArgNo,
-                           regClassId);
+    return regNumForIntArg(inCallee, isVarArgsCall, argNo, regClassId);
   else
     {
       regClassId = FloatRegClassID;
       if (regType == FPSingleRegType)
         return (argNo*2+1 >= NumOfFloatArgRegs)?
-          InvalidRegNum : SparcFloatRegClass::f0 + (argNo * 2 + 1);
+          getInvalidRegNum() : SparcFloatRegClass::f0 + (argNo * 2 + 1);
       else if (regType == FPDoubleRegType)
         return (argNo*2 >= NumOfFloatArgRegs)?
-          InvalidRegNum : SparcFloatRegClass::f0 + (argNo * 2);
+          getInvalidRegNum() : SparcFloatRegClass::f0 + (argNo * 2);
       else
         assert(0 && "Illegal FP register type");
 	return 0;
@@ -379,11 +370,11 @@
     
     int regNum = (regType == IntRegType)
       ? regNumForIntArg(/*inCallee*/ true, isVarArgs,
-                        argNo, intArgNo++, fpArgNo, regClassIDOfArgReg)
+                        argNo, regClassIDOfArgReg)
       : regNumForFPArg(regType, /*inCallee*/ true, isVarArgs,
-                       argNo, intArgNo, fpArgNo++, regClassIDOfArgReg); 
+                       argNo, regClassIDOfArgReg); 
     
-    if(regNum != InvalidRegNum)
+    if(regNum != getInvalidRegNum())
       LR->setSuggestedColor(regNum);
   }
 }
@@ -418,16 +409,16 @@
     // Also find the correct register the argument must use (UniArgReg)
     //
     bool isArgInReg = false;
-    unsigned UniArgReg = InvalidRegNum;	// reg that LR MUST be colored with
+    unsigned UniArgReg = getInvalidRegNum(); // reg that LR MUST be colored with
     unsigned regClassIDOfArgReg = BadRegClass; // reg class of chosen reg
     
     int regNum = (regType == IntRegType)
       ? regNumForIntArg(/*inCallee*/ true, isVarArgs,
-                        argNo, intArgNo++, fpArgNo, regClassIDOfArgReg)
+                        argNo, regClassIDOfArgReg)
       : regNumForFPArg(regType, /*inCallee*/ true, isVarArgs,
-                       argNo, intArgNo, fpArgNo++, regClassIDOfArgReg);
+                       argNo, regClassIDOfArgReg);
     
-    if(regNum != InvalidRegNum) {
+    if(regNum != getInvalidRegNum()) {
       isArgInReg = true;
       UniArgReg = getUnifiedRegNum( regClassIDOfArgReg, regNum);
     }
@@ -482,7 +473,17 @@
 	int offsetFromFP =
           frameInfo.getIncomingArgOffset(MachineFunction::get(Meth),
                                          argNo);
-        
+
+        // float arguments on stack are right justified so adjust the offset!
+        // int arguments are also right justified but they are always loaded as
+        // a full double-word so the offset does not need to be adjusted.
+        if (regType == FPSingleRegType) {
+          unsigned argSize = target.getTargetData().getTypeSize(LR->getType());
+          unsigned slotSize = frameInfo.getSizeOfEachArgOnStack();
+          assert(argSize <= slotSize && "Insufficient slot size!");
+          offsetFromFP += slotSize - argSize;
+        }
+
 	cpMem2RegMI(FirstAI->InstrnsBefore,
                     getFramePointer(), offsetFromFP, UniLRReg, regType);
       }
@@ -525,11 +526,21 @@
 	// can simply change the stack position of the LR. We can do this,
 	// since this method is called before any other method that makes
 	// uses of the stack pos of the LR (e.g., updateMachineInstr)
-
+        // 
         const TargetFrameInfo& frameInfo = target.getFrameInfo();
 	int offsetFromFP =
           frameInfo.getIncomingArgOffset(MachineFunction::get(Meth),
                                          argNo);
+
+        // FP arguments on stack are right justified so adjust offset!
+        // int arguments are also right justified but they are always loaded as
+        // a full double-word so the offset does not need to be adjusted.
+        if (regType == FPSingleRegType) {
+          unsigned argSize = target.getTargetData().getTypeSize(LR->getType());
+          unsigned slotSize = frameInfo.getSizeOfEachArgOnStack();
+          assert(argSize <= slotSize && "Insufficient slot size!");
+          offsetFromFP += slotSize - argSize;
+        }
         
 	LR->modifySpillOffFromFP( offsetFromFP );
       }
@@ -586,11 +597,11 @@
     
     // get the LR of call operand (parameter)
     LiveRange *const LR = LRI.getLiveRangeForValue(CallArg); 
-    assert (LR && "Must have a LR for all arguments since "
-                  "all args (even consts) must be defined before");
+    if (!LR)
+      continue;                    // no live ranges for constants and labels
 
     unsigned regType = getRegType(LR);
-    unsigned regClassIDOfArgReg = BadRegClass; // reg class of chosen reg (unused)
+    unsigned regClassIDOfArgReg = BadRegClass; // chosen reg class (unused)
 
     // Choose a register for this arg depending on whether it is
     // an INT or FP value.  Here we ignore whether or not it is a
@@ -598,15 +609,16 @@
     // to an integer Value and handled under (argCopy != NULL) below.
     int regNum = (regType == IntRegType)
       ? regNumForIntArg(/*inCallee*/ false, /*isVarArgs*/ false,
-                        argNo, intArgNo++, fpArgNo, regClassIDOfArgReg)
+                        argNo, regClassIDOfArgReg)
       : regNumForFPArg(regType, /*inCallee*/ false, /*isVarArgs*/ false,
-                       argNo, intArgNo, fpArgNo++, regClassIDOfArgReg); 
+                       argNo, regClassIDOfArgReg); 
     
     // If a register could be allocated, use it.
     // If not, do NOTHING as this will be colored as a normal value.
-    if(regNum != InvalidRegNum)
+    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();
@@ -615,12 +627,12 @@
         assert(regType != IntRegType && argCopy->getType()->isInteger()
                && "Must be passing copy of FP argument in int register");
         int copyRegNum = regNumForIntArg(/*inCallee*/false, /*isVarArgs*/false,
-                                         argNo, intArgNo, fpArgNo-1,
-                                         regClassIDOfArgReg);
-        assert(copyRegNum != InvalidRegNum); 
+                                         argNo, regClassIDOfArgReg);
+        assert(copyRegNum != getInvalidRegNum()); 
         LiveRange *const copyLR = LRI.getLiveRangeForValue(argCopy); 
         copyLR->setSuggestedColor(copyRegNum);
       }
+#endif
     
   } // for all call arguments
 
@@ -640,14 +652,15 @@
                              std::vector<MachineInstr*> &AddedInstrnsBefore)
   const
 {
+  assert(0 && "Should never get here because we are now using precopying!");
+
   MachineInstr *AdMI;
   bool isArgInReg = false;
   unsigned UniArgReg = BadRegClass;          // unused unless initialized below
-  if (UniArgRegOrNone != InvalidRegNum)
+  if (UniArgRegOrNone != getInvalidRegNum())
     {
       isArgInReg = true;
       UniArgReg = (unsigned) UniArgRegOrNone;
-      CallMI->insertUsedReg(UniArgReg); // mark the reg as used
     }
   
   if (LR->hasColor()) {
@@ -748,35 +761,24 @@
 
   if (RetVal) {
     LiveRange *RetValLR = LRI.getLiveRangeForValue( RetVal );
+    assert(RetValLR && "ERROR: No LR for non-void return value");
 
-    if (!RetValLR) {
-      std::cerr << "\nNo LR for:" << RAV(RetVal) << "\n";
-      assert(RetValLR && "ERR:No LR for non-void return value");
-    }
-
+    // Mark the return value register as used by this instruction
     unsigned RegClassID = RetValLR->getRegClassID();
-    bool recvCorrectColor;
-    unsigned CorrectCol;                // correct color for ret value
-    unsigned UniRetReg;                 // unified number for CorrectCol
-    
-    if(RegClassID == IntRegClassID)
-      CorrectCol = SparcIntRegClass::o0;
-    else if(RegClassID == FloatRegClassID)
-      CorrectCol = SparcFloatRegClass::f0;
-    else {
-      assert( 0 && "Unknown RegClass");
-      return;
-    }
+    unsigned CorrectCol = (RegClassID == IntRegClassID
+                           ? (unsigned) SparcIntRegClass::o0
+                           : (unsigned) SparcFloatRegClass::f0);
     
-    // convert to unified number
-    UniRetReg = getUnifiedRegNum(RegClassID, CorrectCol);	
-
-    // Mark the register as used by this instruction
-    CallMI->insertUsedReg(UniRetReg);
+    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
-    recvCorrectColor = RetValLR->hasColor()? RetValLR->getColor() == CorrectCol
-      : false;
+    bool recvCorrectColor = (RetValLR->hasColor()
+                             ? RetValLR->getColor() == CorrectCol : false);
     
     // if we didn't receive the correct color for some reason, 
     // put copy instruction
@@ -802,8 +804,8 @@
         cpReg2MemMI(CallAI->InstrnsAfter, UniRetReg,
                     getFramePointer(),RetValLR->getSpillOffFromFP(), regType);
       }
-
     } // the LR didn't receive the suggested color  
+#endif
     
   } // if there a return value
   
@@ -818,56 +820,62 @@
   
   for(unsigned argNo=0, i=0, intArgNo=0, fpArgNo=0;
       i < NumOfCallArgs; ++i, ++argNo) {    
-
-    const Value *CallArg = argDesc->getArgInfo(i).getArgVal();
     
-    // get the LR of call operand (parameter)
-    LiveRange *const LR = LRI.getLiveRangeForValue(CallArg); 
-
-    unsigned RegClassID = getRegClassIDOfType(CallArg->getType());
+    const Value *CallArg = argDesc->getArgInfo(i).getArgVal();
     unsigned regType = getRegType(CallArg->getType());
-    
+
     // Find whether this argument is coming in a register (if not, on stack)
     // Also find the correct register the argument must use (UniArgReg)
     //
     bool isArgInReg = false;
-    unsigned UniArgReg = InvalidRegNum;	  // reg that LR MUST be colored with
+    int UniArgReg = getInvalidRegNum();	  // reg that LR MUST be colored with
     unsigned regClassIDOfArgReg = BadRegClass; // reg class of chosen reg
     
     // Find the register that must be used for this arg, depending on
     // whether it is an INT or FP value.  Here we ignore whether or not it
     // is a varargs calls, because FP arguments will be explicitly copied
     // to an integer Value and handled under (argCopy != NULL) below.
+    // 
     int regNum = (regType == IntRegType)
       ? regNumForIntArg(/*inCallee*/ false, /*isVarArgs*/ false,
-                        argNo, intArgNo++, fpArgNo, regClassIDOfArgReg)
+                        argNo, regClassIDOfArgReg)
       : regNumForFPArg(regType, /*inCallee*/ false, /*isVarArgs*/ false,
-                       argNo, intArgNo, fpArgNo++, regClassIDOfArgReg); 
+                       argNo, regClassIDOfArgReg); 
     
-    if(regNum != InvalidRegNum) {
+    if (regNum != getInvalidRegNum()) {
       isArgInReg = true;
-      UniArgReg = getUnifiedRegNum( regClassIDOfArgReg, regNum);
-      assert(regClassIDOfArgReg == RegClassID &&
-             "Moving values between reg classes must happen during selection");
+      UniArgReg = getUnifiedRegNum(regClassIDOfArgReg, regNum);
+      CallMI->insertUsedReg(UniArgReg);         // mark the reg as used
     }
+
+#ifdef CANNOT_PRECOPY_CALLARGS
     
-    // not possible to have a null LR since all args (even consts)  
-    // must be defined before
-    if (!LR) {          
-      std::cerr <<" ERROR: In call instr, no LR for arg: " <<RAV(CallArg)<<"\n";
-      assert(LR && "NO LR for call arg");  
+    // 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
     // (in argCopy), or on the stack (useStackSlot).
-    const Value *argCopy = argDesc->getArgInfo(i).getArgCopy();
-    if (argCopy != NULL)
+    int argCopyReg = argDesc->getArgInfo(i).getArgCopy();
+    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");
         
@@ -875,9 +883,8 @@
         unsigned copyRegType = getRegType(argCopy->getType());
         
         int copyRegNum = regNumForIntArg(/*inCallee*/false, /*isVarArgs*/false,
-                                         argNo, intArgNo, fpArgNo-1,
-                                         regClassIDOfArgReg);
-        assert(copyRegNum != InvalidRegNum); 
+                                         argNo, regClassIDOfArgReg);
+        assert(copyRegNum != getInvalidRegNum()); 
         assert(regClassIDOfArgReg == copyRegClassID &&
            "Moving values between reg classes must happen during selection");
         
@@ -885,17 +892,20 @@
                               LRI.getLiveRangeForValue(argCopy), copyRegType,
                               copyRegClassID, copyRegNum, argNo,
                               AddedInstrnsBefore);
+#endif
       }
     
-    if (regNum != InvalidRegNum &&
+#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,
-                              InvalidRegNum, argNo, AddedInstrnsBefore);
+                              getInvalidRegNum(), argNo, AddedInstrnsBefore);
       }
+#endif
   }  // for each parameter in call instruction
 
   // If we added any instruction before the call instruction, verify
@@ -943,25 +953,15 @@
 
   suggestReg4RetAddr(RetMI, LRI);
 
-  // if there is an implicit ref, that has to be the ret value
-  if(  RetMI->getNumImplicitRefs() > 0 ) {
-
-    // The first implicit operand is the return value of a return instr
-    const Value *RetVal =  RetMI->getImplicitRef(0);
-
-    LiveRange *const LR = LRI.getLiveRangeForValue( RetVal ); 
-
-    if (!LR) {
-      std::cerr << "\nNo LR for:" << RAV(RetVal) << "\n";
-      assert(0 && "No LR for return value of non-void method");
-    }
-
-    unsigned RegClassID = LR->getRegClassID();
-    if (RegClassID == IntRegClassID) 
-      LR->setSuggestedColor(SparcIntRegClass::i0);
-    else if (RegClassID == FloatRegClassID) 
-      LR->setSuggestedColor(SparcFloatRegClass::f0);
-  }
+  // To find the return value (if any), we can get the LLVM return instr.
+  // from the return address register, which is the first operand
+  Value* tmpI = RetMI->getOperand(0).getVRegValue();
+  ReturnInst* retI=cast<ReturnInst>(cast<TmpInstruction>(tmpI)->getOperand(0));
+  if (const Value *RetVal = retI->getReturnValue())
+    if (LiveRange *const LR = LRI.getLiveRangeForValue(RetVal))
+      LR->setSuggestedColor(LR->getRegClassID() == IntRegClassID
+                            ? (unsigned) SparcIntRegClass::i0
+                            : (unsigned) SparcFloatRegClass::f0);
 }
 
 
@@ -978,47 +978,34 @@
 
   assert((target.getInstrInfo()).isReturn( RetMI->getOpCode()));
 
-  // if there is an implicit ref, that has to be the ret value
-  if(RetMI->getNumImplicitRefs() > 0) {
-
-    // The first implicit operand is the return value of a return instr
-    const Value *RetVal =  RetMI->getImplicitRef(0);
-
-    LiveRange *LR = LRI.getLiveRangeForValue(RetVal); 
-
-    if (!LR) {
-      std::cerr << "\nNo LR for:" << RAV(RetVal) << "\n";
-      // assert( LR && "No LR for return value of non-void method");
-      return;
-    }
+  // To find the return value (if any), we can get the LLVM return instr.
+  // from the return address register, which is the first operand
+  Value* tmpI = RetMI->getOperand(0).getVRegValue();
+  ReturnInst* retI=cast<ReturnInst>(cast<TmpInstruction>(tmpI)->getOperand(0));
+  if (const Value *RetVal = retI->getReturnValue()) {
 
     unsigned RegClassID = getRegClassIDOfType(RetVal->getType());
     unsigned regType = getRegType(RetVal->getType());
-
-    unsigned CorrectCol;
-    if(RegClassID == IntRegClassID)
-      CorrectCol = SparcIntRegClass::i0;
-    else if(RegClassID == FloatRegClassID)
-      CorrectCol = SparcFloatRegClass::f0;
-    else {
-      assert (0 && "Unknown RegClass");
-      return;
-    }
+    unsigned CorrectCol = (RegClassID == IntRegClassID
+                           ? (unsigned) SparcIntRegClass::i0
+                           : (unsigned) SparcFloatRegClass::f0);
 
     // convert to unified number
     unsigned UniRetReg = getUnifiedRegNum(RegClassID, CorrectCol);
 
     // Mark the register as used by this instruction
     RetMI->insertUsedReg(UniRetReg);
-    
-    // if the LR received the correct color, NOTHING to do
-    
-    if (LR->hasColor() && LR->getColor() == CorrectCol)
-      return;
-    
-    if (LR->hasColor()) {
 
-      // We are here because the LR was allocted a regiter
+#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
@@ -1034,6 +1021,7 @@
                   LR->getSpillOffFromFP(), UniRetReg, regType);
       //std::cerr << "\nCopied the return value from stack\n";
     }
+#endif
   
   } // if there is a return value
 
@@ -1070,7 +1058,7 @@
                                unsigned SrcReg,
                                unsigned DestReg,
                                int RegType) const {
-  assert( ((int)SrcReg != InvalidRegNum) && ((int)DestReg != InvalidRegNum) &&
+  assert( ((int)SrcReg != getInvalidRegNum()) && ((int)DestReg != getInvalidRegNum()) &&
 	  "Invalid Register");
   
   MachineInstr * MI = NULL;
@@ -1297,18 +1285,24 @@
 
   CallArgsDescriptor* argDesc = CallArgsDescriptor::get(CallMI);
   
-  // Now find the LR of the return value of the call
-  // The last *implicit operand* is the return value of a call
-  // Insert it to to he PushedRegSet since we must not save that register
+  // Now check if the call has a return value (using argDesc) and if so,
+  // find the LR of the TmpInstruction representing the return value register.
+  // (using the last or second-last *implicit operand* of the call MI).
+  // Insert it to to the PushedRegSet since we must not save that register
   // and restore it after 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 we must not save/restore it.
-
-  const Value *RetVal = argDesc->getReturnValue();
-
-  if (RetVal) {
-    LiveRange *RetValLR = PRA.LRI.getLiveRangeForValue( RetVal );
+  // 
+  if (const Value *origRetVal = argDesc->getReturnValue()) {
+    unsigned retValRefNum = (CallMI->getNumImplicitRefs() -
+                             (argDesc->getIndirectFuncPtr()? 1 : 2));
+    const TmpInstruction* tmpRetVal =
+      cast<TmpInstruction>(CallMI->getImplicitRef(retValRefNum));
+    assert(tmpRetVal->getOperand(0) == origRetVal &&
+           tmpRetVal->getType() == origRetVal->getType() &&
+           "Wrong implicit ref?");
+    LiveRange *RetValLR = PRA.LRI.getLiveRangeForValue( tmpRetVal );
     assert(RetValLR && "No LR for RetValue of call");
 
     if (RetValLR->hasColor())
@@ -1351,8 +1345,8 @@
 	    // and add them to InstrnsBefore and InstrnsAfter of the
 	    // call instruction
             // 
-	    int StackOff = 
-	      PRA.MF.getInfo()->pushTempValue(getSpilledRegSize(RegType));
+	    int StackOff =
+              PRA.MF.getInfo()->pushTempValue(getSpilledRegSize(RegType));
             
 	    std::vector<MachineInstr*> AdIBef, AdIAft;
             
@@ -1361,7 +1355,9 @@
             // We may need a scratch register to copy the saved value
             // to/from memory.  This may itself have to insert code to
             // free up a scratch register.  Any such code should go before
-            // the save code.
+            // the save code.  The scratch register, if any, is by default
+            // temporary and not "used" by the instruction unless the
+            // copy code itself decides to keep the value in the scratch reg.
             int scratchRegType = -1;
             int scratchReg = -1;
             if (regTypeNeedsScratchReg(RegType, scratchRegType))
@@ -1371,7 +1367,6 @@
                 scratchReg = PRA.getUsableUniRegAtMI(scratchRegType, &LVSetBef,
                                                    CallMI, AdIBef, AdIAft);
                 assert(scratchReg != getInvalidRegNum());
-                CallMI->insertUsedReg(scratchReg); 
               }
             
             if (AdIBef.size() > 0)
@@ -1390,7 +1385,7 @@
             // We may need a scratch register to copy the saved value
             // from memory.  This may itself have to insert code to
             // free up a scratch register.  Any such code should go
-            // after the save code.
+            // after the save code.  As above, scratch is not marked "used".
             // 
             scratchRegType = -1;
             scratchReg = -1;
@@ -1399,7 +1394,6 @@
                 scratchReg = PRA.getUsableUniRegAtMI(scratchRegType, &LVSetAft,
                                                  CallMI, AdIBef, AdIAft);
                 assert(scratchReg != getInvalidRegNum());
-                CallMI->insertUsedReg(scratchReg); 
               }
             
             if (AdIBef.size() > 0)





More information about the llvm-commits mailing list