Allow the getRegForInlineAsmConstraint method to return a register class with

no fixes physreg.  Treat this as permission to use any register in the register
class.  When this happens and it is safe, allow the llvm register allcoator to
allocate the register instead of doing it at isel time.  This eliminates a ton
of copies around common inline asms.  For example:

int test2(int Y, int X) {
  asm("foo %0, %1" : "=r"(X): "r"(X));
  return X;
}

now compiles to:

_test2:
        foo r3, r4
        blr

instead of:

_test2:
        mr r2, r4
        foo r2, r2
        mr r3, r2
        blr

GCC produces:

_test2:
        foo r4, r4
        mr r3,r4
        blr


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31366 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2006-11-02 01:41:49 +00:00
parent a74b4a3ddc
commit 2a821601f1

View File

@ -2231,6 +2231,8 @@ GetRegistersForValue(const std::string &ConstrCode,
MVT::ValueType RegVT; MVT::ValueType RegVT;
MVT::ValueType ValueVT = VT; MVT::ValueType ValueVT = VT;
// If this is a constraint for a specific physical register, like {r17},
// assign it now.
if (PhysReg.first) { if (PhysReg.first) {
if (VT == MVT::Other) if (VT == MVT::Other)
ValueVT = *PhysReg.second->vt_begin(); ValueVT = *PhysReg.second->vt_begin();
@ -2260,10 +2262,36 @@ GetRegistersForValue(const std::string &ConstrCode,
return RegsForValue(Regs, RegVT, ValueVT); return RegsForValue(Regs, RegVT, ValueVT);
} }
// This is a reference to a register class. Allocate NumRegs consecutive, // Otherwise, if this was a reference to an LLVM register class, create vregs
// available, registers from the class. // for this reference.
std::vector<unsigned> RegClassRegs = std::vector<unsigned> RegClassRegs;
TLI.getRegClassForInlineAsmConstraint(ConstrCode, VT); if (PhysReg.second) {
// If this is an early clobber or tied register, our regalloc doesn't know
// how to maintain the constraint. If it isn't, go ahead and create vreg
// and let the regalloc do the right thing.
if (!isOutReg || !isInReg) {
if (VT == MVT::Other)
ValueVT = *PhysReg.second->vt_begin();
RegVT = *PhysReg.second->vt_begin();
// Create the appropriate number of virtual registers.
SSARegMap *RegMap = DAG.getMachineFunction().getSSARegMap();
for (; NumRegs; --NumRegs)
Regs.push_back(RegMap->createVirtualRegister(PhysReg.second));
return RegsForValue(Regs, RegVT, ValueVT);
}
// Otherwise, we can't allocate it. Let the code below figure out how to
// maintain these constraints.
RegClassRegs.assign(PhysReg.second->begin(), PhysReg.second->end());
} else {
// This is a reference to a register class that doesn't directly correspond
// to an LLVM register class. Allocate NumRegs consecutive, available,
// registers from the class.
RegClassRegs = TLI.getRegClassForInlineAsmConstraint(ConstrCode, VT);
}
const MRegisterInfo *MRI = DAG.getTarget().getRegisterInfo(); const MRegisterInfo *MRI = DAG.getTarget().getRegisterInfo();
MachineFunction &MF = *CurMBB->getParent(); MachineFunction &MF = *CurMBB->getParent();