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:
parent
5e5a37f750
commit
8d30b76da6
@ -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>";
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user