-//---------------------------------------------------------------------------
-// After graph coloring, we have call this method to see whehter the return
-// value and the call args received the correct colors. If not, we have
-// to instert copy instructions.
-//---------------------------------------------------------------------------
-
-void UltraSparcRegInfo::colorCallArgs(MachineInstr *CallMI,
- LiveRangeInfo &LRI,
- AddedInstrns *CallAI,
- PhyRegAlloc &PRA,
- const BasicBlock *BB) const {
-
- assert ( (target.getInstrInfo()).isCall(CallMI->getOpCode()) );
-
- CallArgsDescriptor* argDesc = CallArgsDescriptor::get(CallMI);
-
- // First color the return value of the call.
- // If there is a LR for the return value, it means this
- // method returns a value
-
- MachineInstr *AdMI;
-
- const Value *RetVal = argDesc->getReturnValue();
-
- if (RetVal) {
- LiveRange *RetValLR = LRI.getLiveRangeForValue( RetVal );
-
- if (!RetValLR) {
- cerr << "\nNo LR for:" << RAV(RetVal) << "\n";
- assert(RetValLR && "ERR:No LR for non-void return value");
- }
-
- 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;
- }
-
- // convert to unified number
- UniRetReg = getUnifiedRegNum(RegClassID, CorrectCol);
-
- // Mark the register as used by this instruction
- CallMI->insertUsedReg(UniRetReg);
-
- // if the LR received the correct color, NOTHING to do
- 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
-
- } // if there a return value
-
-
- //-------------------------------------------
- // Now color all args of the call instruction
- //-------------------------------------------
-
- std::vector<MachineInstr *> AddedInstrnsBefore;
-
- unsigned NumOfCallArgs = argDesc->getNumArgs();
-
- 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());
- 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
- 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)
- : regNumForFPArg(regType, /*inCallee*/ false, /*isVarArgs*/ false,
- argNo, intArgNo, fpArgNo++, regClassIDOfArgReg);
-
- if(regNum != InvalidRegNum) {
- isArgInReg = true;
- UniArgReg = getUnifiedRegNum( regClassIDOfArgReg, regNum);
- assert(regClassIDOfArgReg == RegClassID &&
- "Moving values between reg classes must happen during selection");
- }
-
- // not possible to have a null LR since all args (even consts)
- // must be defined before
- if (!LR) {
- cerr << " ERROR: In call instr, no LR for arg: " << RAV(CallArg) <<"\n";
- assert(LR && "NO LR for call arg");
- }
-
- InitializeOutgoingArg(CallMI, CallAI, PRA, LR, regType, RegClassID,
- UniArgReg, argNo, AddedInstrnsBefore);
-
- // 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)
- {
- 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, intArgNo, fpArgNo-1,
- regClassIDOfArgReg);
- assert(copyRegNum != InvalidRegNum);
- assert(regClassIDOfArgReg == copyRegClassID &&
- "Moving values between reg classes must happen during selection");
-
- InitializeOutgoingArg(CallMI, CallAI, PRA,
- LRI.getLiveRangeForValue(argCopy), copyRegType,
- copyRegClassID, copyRegNum, argNo,
- AddedInstrnsBefore);
- }
-
- if (regNum != InvalidRegNum &&
- 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);
- }
- } // for each parameter in call instruction
-
- // If we added any instruction before the call instruction, verify
- // that they are in the proper order and if not, reorder them
- //
- std::vector<MachineInstr *> ReorderedVec;
- if (!AddedInstrnsBefore.empty()) {
-
- if (DEBUG_RA) {
- cerr << "\nCalling reorder with instrns: \n";
- for(unsigned i=0; i < AddedInstrnsBefore.size(); i++)
- cerr << *(AddedInstrnsBefore[i]);
- }
-
- OrderAddedInstrns(AddedInstrnsBefore, ReorderedVec, PRA);
- assert(ReorderedVec.size() >= AddedInstrnsBefore.size()
- && "Dropped some instructions when reordering!");
-
- if (DEBUG_RA) {
- cerr << "\nAfter reordering instrns: \n";
- for(unsigned i = 0; i < ReorderedVec.size(); i++)
- cerr << *ReorderedVec[i];
- }
- }
-
- // Now insert caller saving code for this call instruction
- //
- insertCallerSavingCode(CallAI->InstrnsBefore, CallAI->InstrnsAfter,
- CallMI, BB, PRA);
-
- // Then insert the final reordered code for the call arguments.
- //
- for(unsigned i=0; i < ReorderedVec.size(); i++)
- CallAI->InstrnsBefore.push_back( ReorderedVec[i] );
-}