Skip to content

[BOLT] Introduce skip-inline flag #128135

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 21, 2025

Conversation

aaupov
Copy link
Contributor

@aaupov aaupov commented Feb 21, 2025

Introduce exclusion list for inlining, allowing more fine-grained
control than using skip-funcs.

Test Plan: added skip-inline.s

Created using spr 1.3.4
@llvmbot
Copy link
Member

llvmbot commented Feb 21, 2025

@llvm/pr-subscribers-bolt

Author: Amir Ayupov (aaupov)

Changes

Introduce exclusion list for inlining, allowing more fine-grained
control than using skip-funcs.

Test Plan: added skip-inline.s


Full diff: https://github.com/llvm/llvm-project/pull/128135.diff

2 Files Affected:

  • (modified) bolt/lib/Passes/Inliner.cpp (+13-1)
  • (added) bolt/test/X86/skip-inline.s (+26)
diff --git a/bolt/lib/Passes/Inliner.cpp b/bolt/lib/Passes/Inliner.cpp
index 1793f4ff1f148..9b28c7efde5bf 100644
--- a/bolt/lib/Passes/Inliner.cpp
+++ b/bolt/lib/Passes/Inliner.cpp
@@ -49,6 +49,12 @@ ForceInlineFunctions("force-inline",
   cl::Hidden,
   cl::cat(BoltOptCategory));
 
+static cl::list<std::string> SkipInlineFunctions(
+    "skip-inline", cl::CommaSeparated,
+    cl::desc("list of functions to never consider for inlining"),
+    cl::value_desc("func1,func2,func3,..."), cl::Hidden,
+    cl::cat(BoltOptCategory));
+
 static cl::opt<bool> InlineAll("inline-all", cl::desc("inline all functions"),
                                cl::cat(BoltOptCategory));
 
@@ -105,6 +111,12 @@ bool mustConsider(const llvm::bolt::BinaryFunction &Function) {
   return false;
 }
 
+bool mustSkip(const llvm::bolt::BinaryFunction &Function) {
+  return llvm::any_of(opts::SkipInlineFunctions, [&](const std::string &Name) {
+    return Function.hasName(Name);
+  });
+}
+
 void syncOptions() {
   if (opts::InlineIgnoreCFI)
     opts::InlineIgnoreLeafCFI = true;
@@ -223,7 +235,7 @@ InliningInfo getInliningInfo(const BinaryFunction &BF) {
 void Inliner::findInliningCandidates(BinaryContext &BC) {
   for (const auto &BFI : BC.getBinaryFunctions()) {
     const BinaryFunction &Function = BFI.second;
-    if (!shouldOptimize(Function))
+    if (!shouldOptimize(Function) || opts::mustSkip(Function))
       continue;
     const InliningInfo InlInfo = getInliningInfo(Function);
     if (InlInfo.Type != INL_NONE)
diff --git a/bolt/test/X86/skip-inline.s b/bolt/test/X86/skip-inline.s
new file mode 100644
index 0000000000000..748990a0cd587
--- /dev/null
+++ b/bolt/test/X86/skip-inline.s
@@ -0,0 +1,26 @@
+## Check skip-inline flag behavior
+
+# RUN: llvm-mc --filetype=obj --triple=x86_64-unknown-unknown %s -o %t.o
+# RUN: ld.lld %t.o -o %t.exe -q
+# RUN: llvm-bolt %t.exe --inline-small-functions --print-finalized --print-only=main \
+# RUN:   -o %t.null | FileCheck %s --check-prefix=CHECK-INLINE
+# RUN: llvm-bolt %t.exe --inline-small-functions --skip-inline=foo --print-finalized \
+# RUN:   --print-only=main -o %t.null | FileCheck %s --check-prefix=CHECK-NO-INLINE
+# CHECK-INLINE: Binary Function "main"
+# CHECK-INLINE: ud2
+# CHECK-NO-INLINE: Binary Function "main"
+# CHECK-NO-INLINE: callq foo
+
+.globl _start
+_start:
+  call main
+
+.globl main
+main:
+  call foo
+  ret
+
+.globl foo
+foo:
+  ud2
+  ret

Copy link
Member

@dcci dcci left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine to me, but I wonder if we want to potentially build something more general (in the future). LLVM has a concept of -opt-bisect-limit that allows the opt pipeline to stop after N optimizations.

Maybe something like skip=<pass_name>,{list_of_funcs}. Just a random thought, I don't think this PR should be blocked on it.

@aaupov
Copy link
Contributor Author

aaupov commented Feb 21, 2025

This is fine to me, but I wonder if we want to potentially build something more general (in the future). LLVM has a concept of -opt-bisect-limit that allows the opt pipeline to stop after N optimizations.

We have several options (-max-funcs, -inline-limit) that serve a similar purpose. I think we're covered here.

Maybe something like skip=<pass_name>,{list_of_funcs}. Just a random thought, I don't think this PR should be blocked on it.

I agree, currently we don't have a uniform selection mechanism, with several passes accepting inclusion/exclusion lists.

@aaupov aaupov merged commit 209252f into main Feb 21, 2025
12 checks passed
@aaupov aaupov deleted the users/aaupov/spr/bolt-introduce-skip-inline-flag branch February 21, 2025 17:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants