[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
Chris Lattner
lattner at cs.uiuc.edu
Wed Feb 1 16:25:35 PST 2006
Changes in directory llvm/lib/CodeGen/SelectionDAG:
SelectionDAGISel.cpp updated: 1.145 -> 1.146
---
Log message:
Implement matching constraints. We can now say things like this:
%C = call int asm "xyz $0, $1, $2, $3", "=r,r,r,0"(int %A, int %B, int 4)
and get:
xyz r2, r3, r4, r2
note that the r2's are pinned together. Yaay for 2-address instructions.
2342 ----------------------------------------------------------------------
---
Diffs of the changes: (+28 -15)
SelectionDAGISel.cpp | 43 ++++++++++++++++++++++++++++---------------
1 files changed, 28 insertions(+), 15 deletions(-)
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.145 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.146
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.145 Wed Feb 1 12:59:47 2006
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Wed Feb 1 18:25:23 2006
@@ -1232,6 +1232,7 @@
for (unsigned i = 0, e = Constraints.size(); i != e; ++i) {
assert(Constraints[i].Codes.size() == 1 && "Only handles one code so far!");
std::string &ConstraintCode = Constraints[i].Codes[0];
+
std::vector<unsigned> Regs =
TLI.getRegForInlineAsmConstraint(ConstraintCode);
if (Regs.size() != 1) continue; // Not assigned a fixed reg.
@@ -1243,7 +1244,7 @@
OutputRegs.insert(TheReg);
// If this is an early-clobber output, it cannot be assigned to the same
// value as the input reg.
- if (Constraints[i].isEarlyClobber)
+ if (Constraints[i].isEarlyClobber || Constraints[i].hasMatchingInput)
InputRegs.insert(TheReg);
break;
case InlineAsm::isClobber:
@@ -1263,7 +1264,6 @@
std::string &ConstraintCode = Constraints[i].Codes[0];
switch (Constraints[i].Type) {
case InlineAsm::isOutput: {
-
// Copy the output from the appropriate register.
std::vector<unsigned> Regs =
TLI.getRegForInlineAsmConstraint(ConstraintCode);
@@ -1272,10 +1272,17 @@
unsigned DestReg;
if (Regs.size() == 1)
DestReg = Regs[0];
- else
- DestReg = GetAvailableRegister(true, Constraints[i].isEarlyClobber,
+ else {
+ bool UsesInputRegister = false;
+ // If this is an early-clobber output, or if there is an input
+ // constraint that matches this, we need to reserve the input register
+ // so no other inputs allocate to it.
+ if (Constraints[i].isEarlyClobber || Constraints[i].hasMatchingInput)
+ UsesInputRegister = true;
+ DestReg = GetAvailableRegister(true, UsesInputRegister,
Regs, OutputRegs, InputRegs);
-
+ }
+
assert(DestReg && "Couldn't allocate output reg!");
const Type *OpTy;
@@ -1307,17 +1314,23 @@
Value *Operand = I.getOperand(OpNum);
const Type *OpTy = Operand->getType();
OpNum++; // Consumes a call operand.
-
- // Copy the input into the appropriate register.
- std::vector<unsigned> Regs =
- TLI.getRegForInlineAsmConstraint(ConstraintCode);
+
unsigned SrcReg;
- if (Regs.size() == 1)
- SrcReg = Regs[0];
- else
- SrcReg = GetAvailableRegister(false, true, Regs,
- OutputRegs, InputRegs);
-
+ if (isdigit(ConstraintCode[0])) { // Matching constraint?
+ // If this is required to match an output register we have already set,
+ // just use its register.
+ unsigned OperandNo = atoi(ConstraintCode.c_str());
+ SrcReg = cast<RegisterSDNode>(AsmNodeOperands[OperandNo*2+2])->getReg();
+ } else {
+ // Copy the input into the appropriate register.
+ std::vector<unsigned> Regs =
+ TLI.getRegForInlineAsmConstraint(ConstraintCode);
+ if (Regs.size() == 1)
+ SrcReg = Regs[0];
+ else
+ SrcReg = GetAvailableRegister(false, true, Regs,
+ OutputRegs, InputRegs);
+ }
assert(SrcReg && "Couldn't allocate input reg!");
Chain = DAG.getCopyToReg(Chain, SrcReg, getValue(Operand), Flag);
More information about the llvm-commits
mailing list