Added support for both call/jmpl instructions

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@930 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Ruchira Sasanka 2001-10-21 16:43:41 +00:00
parent 5ab1f87786
commit b3b6f5338c
5 changed files with 250 additions and 141 deletions

View File

@ -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;

View File

@ -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() ) );
}

View File

@ -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() ) );
}

View File

@ -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<RegClass *> 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;

View File

@ -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<RegClass *> 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 ) {