[llvm] [CodeGen][NFC] Refactor inline asm constraint determination (PR #195104)
Bill Wendling via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 30 08:30:22 PDT 2026
================
@@ -10548,75 +10526,157 @@ void SelectionDAGBuilder::visitInlineAsm(const CallBase &Call,
if (isFunction(InOperandVal)) {
auto *GA = cast<GlobalAddressSDNode>(InOperandVal);
ResOpType = InlineAsm::Flag(InlineAsm::Kind::Func, 1);
- AsmOp = DAG.getTargetGlobalAddress(GA->getGlobal(), getCurSDLoc(),
+ AsmOp = DAG.getTargetGlobalAddress(GA->getGlobal(), DL,
InOperandVal.getValueType(),
GA->getOffset());
}
// Add information to the INLINEASM node to know about this input.
ResOpType.setMemConstraint(ConstraintID);
- AsmNodeOperands.push_back(
- DAG.getTargetConstant(ResOpType, getCurSDLoc(), MVT::i32));
-
- AsmNodeOperands.push_back(AsmOp);
+ Info.AsmNodeOperands.push_back(
+ DAG.getTargetConstant(ResOpType, DL, MVT::i32));
+ Info.AsmNodeOperands.push_back(AsmOp);
break;
}
if (OpInfo.ConstraintType != TargetLowering::C_RegisterClass &&
OpInfo.ConstraintType != TargetLowering::C_Register) {
- emitInlineAsmError(Call, "unknown asm constraint '" +
- Twine(OpInfo.ConstraintCode) + "'");
- return;
+ Info.ErrorMsg << "unknown asm constraint '" << OpInfo.ConstraintCode
+ << "'";
+ return true;
}
// TODO: Support this.
if (OpInfo.isIndirect) {
- emitInlineAsmError(
- Call, "Don't know how to handle indirect register inputs yet "
- "for constraint '" +
- Twine(OpInfo.ConstraintCode) + "'");
- return;
+ Info.ErrorMsg << "Don't know how to handle indirect register inputs "
+ << "yet for constraint '" << OpInfo.ConstraintCode << "'";
+ return true;
}
// Copy the input into the appropriate registers.
if (OpInfo.AssignedRegs.Regs.empty()) {
- emitInlineAsmError(Call,
- "couldn't allocate input reg for constraint '" +
- Twine(OpInfo.ConstraintCode) + "'");
- return;
+ Info.ErrorMsg << "couldn't allocate input reg for constraint '"
+ << OpInfo.ConstraintCode << "'";
+ return true;
}
if (DetectWriteToReservedRegister())
- return;
-
- SDLoc dl = getCurSDLoc();
-
- OpInfo.AssignedRegs.getCopyToRegs(InOperandVal, DAG, dl, Chain, &Glue,
- &Call);
+ return true;
- OpInfo.AssignedRegs.AddInlineAsmOperands(InlineAsm::Kind::RegUse, false,
- 0, dl, DAG, AsmNodeOperands);
+ OpInfo.AssignedRegs.getCopyToRegs(InOperandVal, DAG, DL, Info.Chain,
+ &Info.Glue, &Call);
+ OpInfo.AssignedRegs.AddInlineAsmOperands(
+ InlineAsm::Kind::RegUse, false, 0, DL, DAG, Info.AsmNodeOperands);
break;
}
+
case InlineAsm::isClobber:
// Add the clobbered value to the operand list, so that the register
// allocator is aware that the physreg got clobbered.
if (!OpInfo.AssignedRegs.Regs.empty())
- OpInfo.AssignedRegs.AddInlineAsmOperands(InlineAsm::Kind::Clobber,
- false, 0, getCurSDLoc(), DAG,
- AsmNodeOperands);
+ OpInfo.AssignedRegs.AddInlineAsmOperands(
+ InlineAsm::Kind::Clobber, false, 0, DL, DAG, Info.AsmNodeOperands);
break;
}
}
+ return false;
+}
+
+/// DetermineConstraints - ASM operands may have more than one constraint. We
+/// want to choose the "best" constraint for each operand to avoid horrible
+/// code generation---e.g., for "rm" we would like to use "r". This function
+/// tries different constraints in order from best to worst. If a given
+/// constraint isn't possible, e.g., because no registers are available, then
+/// the function returns 'true' and is rerun on the next constraint.
+///
+/// Each operand which has a suitable constraint is marked as "finalized". This
+/// helps reduce the number of times we need to run this function, keeping the
+/// complexity at O(n), where 'n' is the total number of constraints on inputs
+/// and outputs (i.e., for "rm", n == 2).
+static bool
+DetermineConstraints(ConstraintDecisionInfo &Info,
----------------
bwendling wrote:
Done.
https://github.com/llvm/llvm-project/pull/195104
More information about the llvm-commits
mailing list