aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2006-11-02 01:41:49 +0000
committerChris Lattner <sabre@nondot.org>2006-11-02 01:41:49 +0000
commit2a821601f1db665fbb825727aacf1a54d17b91ef (patch)
tree91a31776181a0452fba0725daee566bfa0ca8e06
parenta74b4a3ddc0aadbcf6bf35754cf1c6d4b2d96e67 (diff)
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
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp36
1 files changed, 32 insertions, 4 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 087e25bfa9..9be3a16975 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -2231,6 +2231,8 @@ GetRegistersForValue(const std::string &ConstrCode,
MVT::ValueType RegVT;
MVT::ValueType ValueVT = VT;
+ // If this is a constraint for a specific physical register, like {r17},
+ // assign it now.
if (PhysReg.first) {
if (VT == MVT::Other)
ValueVT = *PhysReg.second->vt_begin();
@@ -2260,10 +2262,36 @@ GetRegistersForValue(const std::string &ConstrCode,
return RegsForValue(Regs, RegVT, ValueVT);
}
- // This is a reference to a register class. Allocate NumRegs consecutive,
- // available, registers from the class.
- std::vector<unsigned> RegClassRegs =
- TLI.getRegClassForInlineAsmConstraint(ConstrCode, VT);
+ // Otherwise, if this was a reference to an LLVM register class, create vregs
+ // for this reference.
+ std::vector<unsigned> RegClassRegs;
+ 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();
MachineFunction &MF = *CurMBB->getParent();