1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 11:42:57 +01:00

Several fixes to handling of int CC register:

(1) An int CC live range must be spilled if there are any interferences,
    even if no other "neighbour" in the interf. graph has been allocated
    that reg. yet.  This is actually true of any class with only one reg!

(2) SparcIntCCRegClass::colorIGNode sets the color even if the LR must
    be spilled so that the machine-independent spill code doesn't have to
    make the machine-dependent decision of which CC name to use based on
    operand type: %xcc or %icc.  (These are two halves of the same register.)

(3) LR->isMarkedForSpill() is no longer the same as LR->hasColor().
    These should never have been the same, and this is necessary now for #2.

(4) All RDCCR and WRCCR instructions are directly generated with the
    phony number for %ccr so that EmitAssembly/EmitBinary doesn't have to
    deal with this.

llvm-svn: 7151
This commit is contained in:
Vikram S. Adve 2003-07-10 19:42:11 +00:00
parent 5e5a37f750
commit 8d30b76da6
3 changed files with 48 additions and 179 deletions

View File

@ -393,27 +393,12 @@ SparcFunctionAsmPrinter::printOneOperand(const MachineOperand &mop,
switch (mop.getType())
{
case MachineOperand::MO_CCRegister:
{
// We need to print %icc or %xcc as %ccr for certain opcodes.
int regNum = (int)mop.getAllocatedRegNum();
if (regNum != Target.getRegInfo().getInvalidRegNum() &&
Target.getRegInfo().getRegClassIDOfReg(regNum)
== UltraSparcRegInfo::IntCCRegClassID)
{
if (opCode == V9::RDCCR || opCode == V9::WRCCRi || opCode == V9::WRCCRr)
{
toAsm << "%" << Target.getRegInfo().getMachineRegClass(UltraSparcRegInfo::IntCCRegClassID)->getRegName(SparcIntCCRegClass::ccr);
break;
}
}
// all other cases can be handled like any other register
}
case MachineOperand::MO_VirtualRegister:
case MachineOperand::MO_CCRegister:
case MachineOperand::MO_MachineRegister:
{
int regNum = (int)mop.getAllocatedRegNum();
if (regNum == Target.getRegInfo().getInvalidRegNum()) {
// better to print code with NULL registers than to die
toAsm << "<NULL VALUE>";

View File

@ -117,7 +117,8 @@ void SparcIntRegClass::colorIGNode(IGNode * Node,
//
// Algorithm:
//
// If the single int CC register is used (either as icc or xcc)
// If (node has any interferences)
// /* all interference operations can use only one register! */
// mark the LR for spilling
// else {
// if (the LR is a 64-bit comparison) use %xcc
@ -130,30 +131,33 @@ void SparcIntRegClass::colorIGNode(IGNode * Node,
void SparcIntCCRegClass::colorIGNode(IGNode *Node,
std::vector<bool> &IsColorUsedArr) const
{
if (IsColorUsedArr[xcc] && IsColorUsedArr[icc])
if (Node->getNumOfNeighbors() > 0)
Node->getParentLR()->markForSpill();
else {
// Choose whether to use %xcc or %icc based on type of value compared
const LiveRange* ccLR = Node->getParentLR();
const Type* setCCType = (* ccLR->begin())->getType(); // any Value in LR
assert(setCCType->isIntegral() || isa<PointerType>(setCCType));
int ccReg = ((isa<PointerType>(setCCType) || setCCType == Type::LongTy)
? xcc : icc);
// Mark the appropriate register in any case (even if it needs to be spilled)
// because there is only one possible register, but more importantly, the
// spill algorithm cannot find it. In particular, we have to choose
// whether to use %xcc or %icc based on type of value compared
//
const LiveRange* ccLR = Node->getParentLR();
const Type* setCCType = (* ccLR->begin())->getType(); // any Value in LR
assert(setCCType->isIntegral() || isa<PointerType>(setCCType));
int ccReg = ((isa<PointerType>(setCCType) || setCCType == Type::LongTy)
? xcc : icc);
#ifndef NDEBUG
// Let's just make sure values of two different types have not been
// coalesced into this LR.
for (ValueSet::const_iterator I=ccLR->begin(), E=ccLR->end(); I!=E; ++I) {
const Type* ccType = (*I)->getType();
assert((ccReg == xcc && (isa<PointerType>(ccType)
|| ccType == Type::LongTy)) ||
(ccReg == icc && ccType->isIntegral() && ccType != Type::LongTy)
&& "Comparisons needing different intCC regs coalesced in LR!");
}
// Let's just make sure values of two different types have not been
// coalesced into this LR.
for (ValueSet::const_iterator I=ccLR->begin(), E=ccLR->end(); I!=E; ++I) {
const Type* ccType = (*I)->getType();
assert((ccReg == xcc && (isa<PointerType>(ccType)
|| ccType == Type::LongTy)) ||
(ccReg == icc && ccType->isIntegral() && ccType != Type::LongTy)
&& "Comparisons needing different intCC regs coalesced in LR!");
}
#endif
Node->setColor(ccReg); // only one int cc reg is available
}
Node->setColor(ccReg); // only one int cc reg is available
}

View File

@ -424,7 +424,7 @@ void UltraSparcRegInfo::colorMethodArgs(const Function *Meth,
UniArgReg = getUnifiedRegNum( regClassIDOfArgReg, regNum);
}
if( LR->hasColor() ) { // if this arg received a register
if( ! LR->isMarkedForSpill() ) { // if this arg received a register
unsigned UniLRReg = getUnifiedRegNum( RegClassID, LR->getColor() );
@ -618,25 +618,7 @@ void UltraSparcRegInfo::suggestRegs4CallArgs(MachineInstr *CallMI,
// If not, do NOTHING as this will be colored as a normal value.
if(regNum != getInvalidRegNum())
LR->setSuggestedColor(regNum);
#ifdef CANNOT_PRECOPY_CALLARGS
// Repeat for the second copy of the argument, which would be
// an FP argument being passed to a function with no prototype
const Value *argCopy = argDesc->getArgInfo(i).getArgCopy();
if (argCopy != NULL)
{
assert(regType != IntRegType && argCopy->getType()->isInteger()
&& "Must be passing copy of FP argument in int register");
int copyRegNum = regNumForIntArg(/*inCallee*/false, /*isVarArgs*/false,
argNo, regClassIDOfArgReg);
assert(copyRegNum != getInvalidRegNum());
LiveRange *const copyLR = LRI.getLiveRangeForValue(argCopy);
copyLR->setSuggestedColor(copyRegNum);
}
#endif
} // for all call arguments
}
@ -664,7 +646,7 @@ UltraSparcRegInfo::InitializeOutgoingArg(MachineInstr* CallMI,
UniArgReg = (unsigned) UniArgRegOrNone;
}
if (LR->hasColor()) {
if (! LR->isMarkedForSpill()) {
unsigned UniLRReg = getUnifiedRegNum(RegClassID, LR->getColor());
// if LR received the correct color, nothing to do
@ -772,42 +754,6 @@ void UltraSparcRegInfo::colorCallArgs(MachineInstr *CallMI,
CallMI->insertUsedReg(getUnifiedRegNum(RegClassID, CorrectCol));
#ifdef CANNOT_PRECOPY_CALLARGS
// unified number for CorrectCol
unsigned UniRetReg = getUnifiedRegNum(RegClassID, CorrectCol);
recvCorrectColor;
// if the LR received the correct color, NOTHING to do
bool recvCorrectColor = (RetValLR->hasColor()
? RetValLR->getColor() == CorrectCol : false);
// if we didn't receive the correct color for some reason,
// put copy instruction
if( !recvCorrectColor ) {
unsigned regType = getRegType(RetValLR);
if( RetValLR->hasColor() ) {
unsigned UniRetLRReg=getUnifiedRegNum(RegClassID,RetValLR->getColor());
// the return value is coming in UniRetReg but has to go into
// the UniRetLRReg
cpReg2RegMI(CallAI->InstrnsAfter, UniRetReg, UniRetLRReg, regType);
} // if LR has color
else {
// if the LR did NOT receive a color, we have to move the return
// value coming in UniRetReg to the stack pos of spilled LR
cpReg2MemMI(CallAI->InstrnsAfter, UniRetReg,
getFramePointer(),RetValLR->getSpillOffFromFP(), regType);
}
} // the LR didn't receive the suggested color
#endif
} // if there a return value
@ -849,24 +795,6 @@ void UltraSparcRegInfo::colorCallArgs(MachineInstr *CallMI,
CallMI->insertUsedReg(UniArgReg); // mark the reg as used
}
#ifdef CANNOT_PRECOPY_CALLARGS
// Get the LR of call operand (parameter). There must be one because
// all args (even constants) must be defined before.
LiveRange *const LR = LRI.getLiveRangeForValue(CallArg);
assert(LR && "NO LR for call arg");
unsigned RegClassID = getRegClassIDOfType(CallArg->getType());
if (regNum != getInvalidRegNum()) {
assert(regClassIDOfArgReg == RegClassID &&
"Moving values between reg classes must happen during selection");
}
InitializeOutgoingArg(CallMI, CallAI, PRA, LR, regType, RegClassID,
UniArgReg, argNo, AddedInstrnsBefore);
#endif
// Repeat for the second copy of the argument, which would be
// an FP argument being passed to a function with no prototype.
// It may either be passed as a copy in an integer register
@ -875,38 +803,7 @@ void UltraSparcRegInfo::colorCallArgs(MachineInstr *CallMI,
if (argCopyReg != TargetRegInfo::getInvalidRegNum())
{
CallMI->insertUsedReg(argCopyReg); // mark the reg as used
#ifdef CANNOT_PRECOPY_CALLARGS
assert(regType != IntRegType && argCopy->getType()->isInteger()
&& "Must be passing copy of FP argument in int register");
unsigned copyRegClassID = getRegClassIDOfType(argCopy->getType());
unsigned copyRegType = getRegType(argCopy->getType());
int copyRegNum = regNumForIntArg(/*inCallee*/false, /*isVarArgs*/false,
argNo, regClassIDOfArgReg);
assert(copyRegNum != getInvalidRegNum());
assert(regClassIDOfArgReg == copyRegClassID &&
"Moving values between reg classes must happen during selection");
InitializeOutgoingArg(CallMI, CallAI, PRA,
LRI.getLiveRangeForValue(argCopy), copyRegType,
copyRegClassID, copyRegNum, argNo,
AddedInstrnsBefore);
#endif
}
#ifdef CANNOT_PRECOPY_CALLARGS
if (regNum != getInvalidRegNum() &&
argDesc->getArgInfo(i).usesStackSlot())
{
// Pass the argument via the stack in addition to regNum
assert(regType != IntRegType && "Passing an integer arg. twice?");
assert(!argCopy && "Passing FP arg in FP reg, INT reg, and stack?");
InitializeOutgoingArg(CallMI, CallAI, PRA, LR, regType, RegClassID,
getInvalidRegNum(), argNo, AddedInstrnsBefore);
}
#endif
} // for each parameter in call instruction
// If we added any instruction before the call instruction, verify
@ -1014,34 +911,6 @@ void UltraSparcRegInfo::colorRetValue(MachineInstr *RetMI,
// Mark the register as used by this instruction
RetMI->insertUsedReg(UniRetReg);
#ifdef CANNOT_PRECOPY_CALLARGS
LiveRange *LR = LRI.getLiveRangeForValue(RetVal);
assert(LR && "No LR for return value of non-void method?");
if (LR->hasColor()) {
// if the LR received the correct color, NOTHING to do
if (LR->getColor() == CorrectCol)
return;
// We are here because the LR was allocated a register
// It may be the suggested register or not
// copy the LR of retun value to i0 or f0
unsigned UniLRReg =getUnifiedRegNum( RegClassID, LR->getColor());
// the LR received UniLRReg but must be colored with UniRetReg
// to pass as the return value
cpReg2RegMI(RetAI->InstrnsBefore, UniLRReg, UniRetReg, regType);
}
else { // if the LR is spilled
cpMem2RegMI(RetAI->InstrnsBefore, getFramePointer(),
LR->getSpillOffFromFP(), UniRetReg, regType);
//std::cerr << "\nCopied the return value from stack\n";
}
#endif
} // if there is a return value
}
@ -1088,14 +957,19 @@ UltraSparcRegInfo::cpReg2RegMI(std::vector<MachineInstr*>& mvec,
case IntCCRegType:
if (getRegType(DestReg) == IntRegType) {
// copy intCC reg to int reg
MI = (BuildMI(V9::RDCCR, 2).addMReg(SparcIntCCRegClass::ccr).
addMReg(DestReg,MOTy::Def));
MI = (BuildMI(V9::RDCCR, 2)
.addMReg(getUnifiedRegNum(UltraSparcRegInfo::IntCCRegClassID,
SparcIntCCRegClass::ccr))
.addMReg(DestReg,MOTy::Def));
} else {
// copy int reg to intCC reg
assert(getRegType(SrcReg) == IntRegType
&& "Can only copy CC reg to/from integer reg");
MI = (BuildMI(V9::WRCCRr, 3).addMReg(SrcReg).addMReg(SparcIntRegClass::g0)
.addMReg(SparcIntCCRegClass::ccr, MOTy::Def));
MI = (BuildMI(V9::WRCCRr, 3)
.addMReg(SrcReg)
.addMReg(SparcIntRegClass::g0)
.addMReg(getUnifiedRegNum(UltraSparcRegInfo::IntCCRegClassID,
SparcIntCCRegClass::ccr), MOTy::Def));
}
break;
@ -1160,7 +1034,9 @@ UltraSparcRegInfo::cpReg2MemMI(std::vector<MachineInstr*>& mvec,
case IntCCRegType:
assert(scratchReg >= 0 && "Need scratch reg to store %ccr to memory");
assert(getRegType(scratchReg) ==IntRegType && "Invalid scratch reg");
MI = (BuildMI(V9::RDCCR, 2).addMReg(SparcIntCCRegClass::ccr)
MI = (BuildMI(V9::RDCCR, 2)
.addMReg(getUnifiedRegNum(UltraSparcRegInfo::IntCCRegClassID,
SparcIntCCRegClass::ccr))
.addMReg(scratchReg, MOTy::Def));
mvec.push_back(MI);
@ -1219,8 +1095,11 @@ UltraSparcRegInfo::cpMem2RegMI(std::vector<MachineInstr*>& mvec,
assert(scratchReg >= 0 && "Need scratch reg to load %ccr from memory");
assert(getRegType(scratchReg) ==IntRegType && "Invalid scratch reg");
cpMem2RegMI(mvec, SrcPtrReg, Offset, scratchReg, IntRegType);
MI = BuildMI(V9::WRCCRr, 3).addMReg(scratchReg)
.addMReg(SparcIntRegClass::g0).addMReg(SparcIntCCRegClass::ccr,MOTy::Def);
MI = (BuildMI(V9::WRCCRr, 3)
.addMReg(scratchReg)
.addMReg(SparcIntRegClass::g0)
.addMReg(getUnifiedRegNum(UltraSparcRegInfo::IntCCRegClassID,
SparcIntCCRegClass::ccr), MOTy::Def));
break;
case FloatCCRegType: {
@ -1323,7 +1202,7 @@ UltraSparcRegInfo::insertCallerSavingCode
LiveRange *RetValLR = PRA.LRI.getLiveRangeForValue( tmpRetVal );
assert(RetValLR && "No LR for RetValue of call");
if (RetValLR->hasColor())
if (! RetValLR->isMarkedForSpill())
PushedRegSet.insert(getUnifiedRegNum(RetValLR->getRegClassID(),
RetValLR->getColor()));
}
@ -1341,8 +1220,9 @@ UltraSparcRegInfo::insertCallerSavingCode
// doesn't have a dominating def - see Assumptions above
if( LR ) {
if( LR->hasColor() ) {
if(! LR->isMarkedForSpill()) {
assert(LR->hasColor() && "LR is neither spilled nor colored?");
unsigned RCID = LR->getRegClassID();
unsigned Color = LR->getColor();