[llvm] 7ddfb4d - [Inlining] Introduce the function attribute "inline-max-stacksize"

Wolfgang Pieb via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 12 11:07:29 PDT 2022


Author: Wolfgang Pieb
Date: 2022-08-12T11:07:18-07:00
New Revision: 7ddfb4dfeb1c52fa0714f1a0784899d7ccd23900

URL: https://github.com/llvm/llvm-project/commit/7ddfb4dfeb1c52fa0714f1a0784899d7ccd23900
DIFF: https://github.com/llvm/llvm-project/commit/7ddfb4dfeb1c52fa0714f1a0784899d7ccd23900.diff

LOG: [Inlining] Introduce the function attribute "inline-max-stacksize"

The value of the attribute is a size in bytes. It has the effect of
suppressing inlining of functions whose stacksizes exceed the given value.

Reviewed By: mtrofin

Differential Revision: https://reviews.llvm.org/D129904

Added: 
    

Modified: 
    llvm/include/llvm/Analysis/InlineCost.h
    llvm/lib/Analysis/InlineCost.cpp
    llvm/test/Transforms/Inline/inline-stacksize.ll

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Analysis/InlineCost.h b/llvm/include/llvm/Analysis/InlineCost.h
index 4ccb2c8f47f3c..a0a5cb8bf356c 100644
--- a/llvm/include/llvm/Analysis/InlineCost.h
+++ b/llvm/include/llvm/Analysis/InlineCost.h
@@ -58,6 +58,8 @@ const uint64_t MaxSimplifiedDynamicAllocaToInline = 65536;
 
 const char FunctionInlineCostMultiplierAttributeName[] =
     "function-inline-cost-multiplier";
+
+const char MaxInlineStackSizeAttributeName[] = "inline-max-stacksize";
 } // namespace InlineConstants
 
 // The cost-benefit pair computed by cost-benefit analysis.

diff  --git a/llvm/lib/Analysis/InlineCost.cpp b/llvm/lib/Analysis/InlineCost.cpp
index ebb1f20641bd0..0992a4f119d6f 100644
--- a/llvm/lib/Analysis/InlineCost.cpp
+++ b/llvm/lib/Analysis/InlineCost.cpp
@@ -161,12 +161,21 @@ static cl::opt<bool> DisableGEPConstOperand(
     cl::desc("Disables evaluation of GetElementPtr with constant operands"));
 
 namespace llvm {
+Optional<int> getStringFnAttrAsInt(const Attribute &Attr) {
+  if (Attr.isValid()) {
+    int AttrValue = 0;
+    if (!Attr.getValueAsString().getAsInteger(10, AttrValue))
+      return AttrValue;
+  }
+  return None;
+}
+
 Optional<int> getStringFnAttrAsInt(CallBase &CB, StringRef AttrKind) {
-  Attribute Attr = CB.getFnAttr(AttrKind);
-  int AttrValue;
-  if (Attr.getValueAsString().getAsInteger(10, AttrValue))
-    return None;
-  return AttrValue;
+  return getStringFnAttrAsInt(CB.getFnAttr(AttrKind));
+}
+
+Optional<int> getStringFnAttrAsInt(Function *F, StringRef AttrKind) {
+  return getStringFnAttrAsInt(F->getFnAttribute(AttrKind));
 }
 
 namespace InlineConstants {
@@ -2713,7 +2722,13 @@ InlineResult CallAnalyzer::analyze() {
 
   // If the callee's stack size exceeds the user-specified threshold,
   // do not let it be inlined.
-  if (AllocatedSize > StackSizeThreshold)
+  // The command line option overrides a limit set in the function attributes.
+  size_t FinalStackSizeThreshold = StackSizeThreshold;
+  if (!StackSizeThreshold.getNumOccurrences())
+    if (Optional<int> AttrMaxStackSize = getStringFnAttrAsInt(
+            Caller, InlineConstants::MaxInlineStackSizeAttributeName))
+      FinalStackSizeThreshold = *AttrMaxStackSize;
+  if (AllocatedSize > FinalStackSizeThreshold)
     return InlineResult::failure("stacksize");
 
   return finalizeAnalysis();

diff  --git a/llvm/test/Transforms/Inline/inline-stacksize.ll b/llvm/test/Transforms/Inline/inline-stacksize.ll
index d39c0ff75c341..a71a2d02ecdda 100644
--- a/llvm/test/Transforms/Inline/inline-stacksize.ll
+++ b/llvm/test/Transforms/Inline/inline-stacksize.ll
@@ -12,22 +12,44 @@ define internal i32 @foo() {
   ret i32 %3
 }
 
-define i32 @bar() {
+define i32 @barNoAttr() {
   %1 = call i32 @foo()
   ret i32 %1
-; ALL: define {{.*}}@bar
+; ALL: define {{.*}}@barNoAttr
 ; ALL-NOT: define
 ; UNLIMITED-NOT: call {{.*}}@foo
 ; LIMITED: call {{.*}}@foo
 }
 
 ; Check that, under the imposed limit, baz() inlines bar(), but not foo().
-define i32 @baz() {
-  %1 = call i32 @bar()
+define i32 @bazNoAttr() {
+  %1 = call i32 @barNoAttr()
   ret i32 %1
 ; ALL: define {{.*}}@baz
-; UNLIMITED-NOT: call {{.*}}@bar
+; UNLIMITED-NOT: call {{.*}}@barNoAttr
 ; UNLIMITED-NOT: call {{.*}}@foo
-; LIMITED-NOT: call {{.*}}@bar
+; LIMITED-NOT: call {{.*}}@barNoAttr
 ; LIMITED: call {{.*}}@foo
 }
+
+; Check that the function attribute prevents inlining of foo().
+define i32 @barAttr() #0 {
+  %1 = call i32 @foo()
+  ret i32 %1
+; ALL: define {{.*}}@barAttr
+; ALL-NOT: define
+; ALL: call {{.*}}@foo
+}
+
+; Check that the commandline option overrides the function attribute.
+define i32 @bazAttr() #1 {
+  %1 = call i32 @barAttr()
+  ret i32 %1
+; ALL: define {{.*}}@bazAttr
+; UNLIMITED-NOT: call {{.*}}@barAttr
+; UNLIMITED-NOT: call {{.*}}@foo
+; LIMITED: call {{.*}}@foo
+}
+
+attributes #0 = { "inline-max-stacksize"="256" }
+attributes #1 = { "inline-max-stacksize"="512" }


        


More information about the llvm-commits mailing list