[llvm] [CodeGen] Parse frame-pointer attribute once when creating MachineFunction (PR #191974)
Cullen Rhodes via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 14 00:11:58 PDT 2026
https://github.com/c-rhodes created https://github.com/llvm/llvm-project/pull/191974
TargetOptions::DisableFramePointerElim is hot and showing up in compile-time profiles via AArch64FrameLowering::hasFPImpl on aarch64-O0-g builds. Repeatedly looking up the function attribute is expensive. Parsing it once at MachineFunction initialisation and storing as FramePointerKind on MachineFrameInfo is a -0.21% geomean improvement on CTMark stage1-aarch64-O0-g. Also helps debug builds on other targets.
https://llvm-compile-time-tracker.com/compare.php?from=215f35eb8f1c313ac135ad47db1cc0b99b3ae694&to=51f6617517177bea1cc49baeab3acaf62d5e9df9&stat=instructions%3Au
>From 056e2230eca86d1362452178012fb33aeb806362 Mon Sep 17 00:00:00 2001
From: Cullen Rhodes <cullen.rhodes at arm.com>
Date: Mon, 13 Apr 2026 10:13:19 +0000
Subject: [PATCH] [CodeGen] Parse frame-pointer attribute once when creating
MachineFunction
TargetOptions::DisableFramePointerElim is hot and showing up in
compile-time profiles via AArch64FrameLowering::hasFPImpl on
aarch64-O0-g builds. Repeatedly looking up the function attribute is
expensive. Parsing it once at MachineFunction initialisation and storing
as FramePointerKind on MachineFrameInfo is a -0.21% geomean improvement
on CTMark stage1-aarch64-O0-g. Also helps debug builds on other targets.
https://llvm-compile-time-tracker.com/compare.php?from=215f35eb8f1c313ac135ad47db1cc0b99b3ae694&to=51f6617517177bea1cc49baeab3acaf62d5e9df9&stat=instructions%3Au
---
llvm/include/llvm/CodeGen/MachineFrameInfo.h | 10 ++++++
llvm/lib/CodeGen/MachineFunction.cpp | 17 +++++++++
llvm/lib/CodeGen/TargetOptionsImpl.cpp | 37 ++++++++++----------
3 files changed, 46 insertions(+), 18 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/MachineFrameInfo.h b/llvm/include/llvm/CodeGen/MachineFrameInfo.h
index c4852f84be352..22729e736fbd3 100644
--- a/llvm/include/llvm/CodeGen/MachineFrameInfo.h
+++ b/llvm/include/llvm/CodeGen/MachineFrameInfo.h
@@ -17,6 +17,7 @@
#include "llvm/CodeGen/Register.h"
#include "llvm/CodeGen/TargetFrameLowering.h"
#include "llvm/Support/Alignment.h"
+#include "llvm/Support/CodeGen.h"
#include "llvm/Support/Compiler.h"
#include <cassert>
#include <vector>
@@ -279,6 +280,10 @@ class MachineFrameInfo {
/// Set to true if this function has any function calls.
bool HasCalls = false;
+ /// Frame-pointer policy for this function to avoid repeated attribute
+ /// lookups in hot paths.
+ FramePointerKind FramePointerPolicy = FramePointerKind::None;
+
/// The frame index for the stack protector.
int StackProtectorIdx = -1;
@@ -641,6 +646,11 @@ class MachineFrameInfo {
bool hasCalls() const { return HasCalls; }
void setHasCalls(bool V) { HasCalls = V; }
+ FramePointerKind getFramePointerPolicy() const { return FramePointerPolicy; }
+ void setFramePointerPolicy(FramePointerKind Kind) {
+ FramePointerPolicy = Kind;
+ }
+
/// Returns true if the function contains opaque dynamic stack adjustments.
bool hasOpaqueSPAdjustment() const { return HasOpaqueSPAdjustment; }
void setHasOpaqueSPAdjustment(bool B) { HasOpaqueSPAdjustment = B; }
diff --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp
index a2dd9c425370c..71179ed9f743d 100644
--- a/llvm/lib/CodeGen/MachineFunction.cpp
+++ b/llvm/lib/CodeGen/MachineFunction.cpp
@@ -20,6 +20,7 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/ProfileSummaryInfo.h"
@@ -161,6 +162,21 @@ static inline Align getFnStackAlignment(const TargetSubtargetInfo &STI,
return STI.getFrameLowering()->getStackAlign();
}
+static FramePointerKind getFramePointerPolicy(const Function &F) {
+ Attribute FPAttr = F.getFnAttribute("frame-pointer");
+ if (!FPAttr.isValid())
+ return FramePointerKind::None;
+
+ StringRef FP = FPAttr.getValueAsString();
+ return StringSwitch<FramePointerKind>(FP)
+ .Case("all", FramePointerKind::All)
+ .Case("non-leaf", FramePointerKind::NonLeaf)
+ .Case("non-leaf-no-reserve", FramePointerKind::NonLeafNoReserve)
+ .Case("reserved", FramePointerKind::Reserved)
+ .Case("none", FramePointerKind::None)
+ .Default(FramePointerKind::None);
+}
+
MachineFunction::MachineFunction(Function &F, const TargetMachine &Target,
const TargetSubtargetInfo &STI, MCContext &Ctx,
unsigned FunctionNum)
@@ -202,6 +218,7 @@ void MachineFunction::init() {
FrameInfo = new (Allocator) MachineFrameInfo(
getFnStackAlignment(STI, F), /*StackRealignable=*/CanRealignSP,
/*ForcedRealign=*/ForceRealignSP && CanRealignSP);
+ FrameInfo->setFramePointerPolicy(getFramePointerPolicy(F));
setUnsafeStackSize(F, *FrameInfo);
diff --git a/llvm/lib/CodeGen/TargetOptionsImpl.cpp b/llvm/lib/CodeGen/TargetOptionsImpl.cpp
index 16d86b42db4a3..2dbde46ac62e3 100644
--- a/llvm/lib/CodeGen/TargetOptionsImpl.cpp
+++ b/llvm/lib/CodeGen/TargetOptionsImpl.cpp
@@ -10,7 +10,6 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/ADT/StringSwitch.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/TargetFrameLowering.h"
@@ -22,31 +21,33 @@ using namespace llvm;
/// DisableFramePointerElim - This returns true if frame pointer elimination
/// optimization should be disabled for the given machine function.
bool TargetOptions::DisableFramePointerElim(const MachineFunction &MF) const {
- const Function &F = MF.getFunction();
-
- Attribute FPAttr = F.getFnAttribute("frame-pointer");
- if (!FPAttr.isValid())
- return false;
- StringRef FP = FPAttr.getValueAsString();
- if (FP == "all")
+ FramePointerKind FP = MF.getFrameInfo().getFramePointerPolicy();
+ switch (FP) {
+ case FramePointerKind::All:
return true;
- if (FP == "non-leaf" || FP == "non-leaf-no-reserve")
+ case FramePointerKind::NonLeaf:
+ case FramePointerKind::NonLeafNoReserve:
return MF.getFrameInfo().hasCalls();
- if (FP == "none" || FP == "reserved")
+ case FramePointerKind::None:
+ case FramePointerKind::Reserved:
return false;
+ }
llvm_unreachable("unknown frame pointer flag");
}
bool TargetOptions::FramePointerIsReserved(const MachineFunction &MF) const {
- const Function &F = MF.getFunction();
- Attribute FPAttr = F.getFnAttribute("frame-pointer");
- if (!FPAttr.isValid())
+ FramePointerKind FP = MF.getFrameInfo().getFramePointerPolicy();
+ switch (FP) {
+ case FramePointerKind::All:
+ case FramePointerKind::NonLeaf:
+ case FramePointerKind::Reserved:
+ return true;
+ case FramePointerKind::NonLeafNoReserve:
+ return MF.getFrameInfo().hasCalls();
+ case FramePointerKind::None:
return false;
-
- return StringSwitch<bool>(FPAttr.getValueAsString())
- .Cases({"all", "non-leaf", "reserved"}, true)
- .Case(("non-leaf-no-reserve"), MF.getFrameInfo().hasCalls())
- .Case("none", false);
+ }
+ llvm_unreachable("unknown frame pointer flag");
}
/// HonorSignDependentRoundingFPMath - Return true if the codegen must assume
More information about the llvm-commits
mailing list