[llvm] [AArch64][GlobalISel] Fast-path simple common calls (NFC) (PR #217615)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 20 06:21:25 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-aarch64
Author: Cullen Rhodes (c-rhodes)
<details>
<summary>Changes</summary>
Instrumentation of aarch64-O0-g CTMark shows the most common argument and return types are pointer, i32, and i64, with Pointer the only common flag.
Fast-path these values when they map directly to w0-w7/x0-x7 or w0/x0. Fall back to the generic assignment machinery for all other cases.
Improves aarch64-O0-g CTMark geomean by -0.31%.
https://llvm-compile-time-tracker.com/compare.php?from=a49d90627bd44d2e76c20b9d4e0cafb339fb806f&to=10b3020aca621c4d21158180efe6d798b3edd22a&stat=instructions%3Au
Assisted-by: codex
---
Full diff: https://github.com/llvm/llvm-project/pull/217615.diff
1 Files Affected:
- (modified) llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp (+62-2)
``````````diff
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp b/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp
index b0a409d153fd2..12a291595de0d 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp
@@ -20,6 +20,7 @@
#include "AArch64SMEAttributes.h"
#include "AArch64Subtarget.h"
#include "AArch64TargetMachine.h"
+#include "Utils/AArch64BaseInfo.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/ObjCARCUtil.h"
@@ -58,6 +59,58 @@ using namespace AArch64GISelUtils;
extern cl::opt<bool> EnableSVEGISel;
+static bool isSimpleGPRCallValue(const CallLowering::ArgInfo &Arg) {
+ if (Arg.Regs.size() != 1 || any_of(Arg.Flags, [](ISD::ArgFlagsTy Flags) {
+ auto FlagVals = Flags.getFlags();
+ return FlagVals != ISD::ArgFlagsTy::NoFlags &&
+ FlagVals != ISD::ArgFlagsTy::Pointer;
+ }))
+ return false;
+
+ Type *Ty = Arg.Ty;
+ return Ty->isPointerTy() || Ty->isIntegerTy(32) || Ty->isIntegerTy(64);
+}
+
+// Avoid the generic assignment machinery when every argument maps directly to
+// w0-w7/x0-x7. Fast path for compile-time.
+static bool tryAssignSimpleGPRCallArgs(MachineIRBuilder &MIRBuilder,
+ MachineInstrBuilder MIB,
+ ArrayRef<CallLowering::ArgInfo> Args) {
+ if (Args.size() > 8)
+ return false;
+
+ for (const CallLowering::ArgInfo &Arg : Args)
+ if (!isSimpleGPRCallValue(Arg))
+ return false;
+
+ for (unsigned I = 0, E = Args.size(); I != E; ++I) {
+ const CallLowering::ArgInfo &Arg = Args[I];
+ MCRegister XReg = AArch64::getGPRArgRegs()[I];
+ Register PhysReg = Arg.Ty->isIntegerTy(32) ? getWRegFromXReg(XReg) : XReg;
+ MIB.addUse(PhysReg, RegState::Implicit);
+ MIRBuilder.buildCopy(PhysReg, Arg.Regs[0]);
+ }
+ return true;
+}
+
+// Avoid the generic assignment machinery when the return value maps directly
+// to w0/x0. Fast path for compile-time.
+static bool tryAssignSimpleGPRCallReturn(MachineIRBuilder &MIRBuilder,
+ MachineInstrBuilder MIB,
+ ArrayRef<CallLowering::ArgInfo> Rets) {
+ if (Rets.size() != 1)
+ return false;
+
+ const CallLowering::ArgInfo &Ret = Rets[0];
+ if (!isSimpleGPRCallValue(Ret))
+ return false;
+
+ Register PhysReg = Ret.Ty->isIntegerTy(32) ? AArch64::W0 : AArch64::X0;
+ MIB.addDef(PhysReg, RegState::Implicit);
+ MIRBuilder.buildCopy(Ret.Regs[0], PhysReg);
+ return true;
+}
+
AArch64CallLowering::AArch64CallLowering(const AArch64TargetLowering &TLI)
: CallLowering(&TLI) {}
@@ -1444,7 +1497,10 @@ bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
Subtarget, /*IsReturn*/ false);
// Do the actual argument marshalling.
OutgoingArgHandler Handler(MIRBuilder, MRI, MIB, /*IsReturn*/ false);
- if (!determineAndHandleAssignments(Handler, Assigner, OutArgs, MIRBuilder,
+ bool AssignedCallArgs = Info.CallConv == CallingConv::C &&
+ tryAssignSimpleGPRCallArgs(MIRBuilder, MIB, OutArgs);
+ if (!AssignedCallArgs &&
+ !determineAndHandleAssignments(Handler, Assigner, OutArgs, MIRBuilder,
Info.CallConv, Info.IsVarArg))
return false;
@@ -1513,7 +1569,11 @@ bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
AArch64OutgoingValueAssigner Assigner(RetAssignFn, RetAssignFn, Subtarget,
/*IsReturn*/ false);
ReturnedArgCallReturnHandler ReturnedArgHandler(MIRBuilder, MRI, MIB);
- if (!determineAndHandleAssignments(
+ bool AssignedCallReturn =
+ Info.CallConv == CallingConv::C && !UsingReturnedArg &&
+ tryAssignSimpleGPRCallReturn(MIRBuilder, MIB, InArgs);
+ if (!AssignedCallReturn &&
+ !determineAndHandleAssignments(
UsingReturnedArg ? ReturnedArgHandler : Handler, Assigner, InArgs,
MIRBuilder, Info.CallConv, Info.IsVarArg,
UsingReturnedArg ? ArrayRef(OutArgs[0].Regs)
``````````
</details>
https://github.com/llvm/llvm-project/pull/217615
More information about the llvm-commits
mailing list