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