From 2223aea6ed33e4261d506afdcfbf30ccd8f52bfb Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 2 Feb 2006 00:25:23 +0000 Subject: [PATCH] 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 ---------------------------------------------------------------------- git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25893 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 43 ++++++++++++------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 8b7dca3f132..da84b38634e 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -1232,6 +1232,7 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) { 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 Regs = TLI.getRegForInlineAsmConstraint(ConstraintCode); if (Regs.size() != 1) continue; // Not assigned a fixed reg. @@ -1243,7 +1244,7 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) { 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 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) { std::string &ConstraintCode = Constraints[i].Codes[0]; switch (Constraints[i].Type) { case InlineAsm::isOutput: { - // Copy the output from the appropriate register. std::vector Regs = TLI.getRegForInlineAsmConstraint(ConstraintCode); @@ -1272,10 +1272,17 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) { 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 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) { Value *Operand = I.getOperand(OpNum); const Type *OpTy = Operand->getType(); OpNum++; // Consumes a call operand. - - // Copy the input into the appropriate register. - std::vector 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(AsmNodeOperands[OperandNo*2+2])->getReg(); + } else { + // Copy the input into the appropriate register. + std::vector 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); -- 2.34.1