[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