[llvm] d828281 - [AlwaysInliner] Respect noinline call site attribute
Dávid Bolvanský via llvm-commits
llvm-commits at lists.llvm.org
Fri Feb 11 10:23:17 PST 2022
Author: Dávid Bolvanský
Date: 2022-02-11T19:23:11+01:00
New Revision: d828281e7860b5e812474212bfc49cc57d52dae0
URL: https://github.com/llvm/llvm-project/commit/d828281e7860b5e812474212bfc49cc57d52dae0
DIFF: https://github.com/llvm/llvm-project/commit/d828281e7860b5e812474212bfc49cc57d52dae0.diff
LOG: [AlwaysInliner] Respect noinline call site attribute
```
always_inline foo() { }
bar () {
noinline foo();
}
```
We should prefer call site attribute over attribute on decl. This is fix for AlwaysInliner, similar fix is needed for normal Inliner (follow up).
Related to https://reviews.llvm.org/D119061
Reviewed By: aeubanks
Differential Revision: https://reviews.llvm.org/D119553
Added:
Modified:
llvm/lib/Transforms/IPO/AlwaysInliner.cpp
llvm/test/Transforms/Inline/always-inline.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/IPO/AlwaysInliner.cpp b/llvm/lib/Transforms/IPO/AlwaysInliner.cpp
index a6d9ce1033f3c..e6bccd97e0e78 100644
--- a/llvm/lib/Transforms/IPO/AlwaysInliner.cpp
+++ b/llvm/lib/Transforms/IPO/AlwaysInliner.cpp
@@ -1,4 +1,4 @@
-//===- InlineAlways.cpp - Code to inline always_inline functions ----------===//
+//===- AlwaysInliner.cpp - Code to inline always_inline functions ----------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -59,9 +59,16 @@ PreservedAnalyses AlwaysInlinerPass::run(Module &M,
for (User *U : F.users())
if (auto *CB = dyn_cast<CallBase>(U))
- if (CB->getCalledFunction() == &F &&
- CB->hasFnAttr(Attribute::AlwaysInline))
- Calls.insert(CB);
+ if (CB->getCalledFunction() == &F) {
+ if (F.hasFnAttribute(Attribute::AlwaysInline)) {
+ // Avoid inlining if noinline call site attribute.
+ if (!CB->isNoInline())
+ Calls.insert(CB);
+ } else if (CB->hasFnAttr(Attribute::AlwaysInline)) {
+ // Ok, alwaysinline call site attribute.
+ Calls.insert(CB);
+ }
+ }
for (CallBase *CB : Calls) {
Function *Caller = CB->getCaller();
@@ -210,6 +217,9 @@ InlineCost AlwaysInlinerLegacyPass::getInlineCost(CallBase &CB) {
if (!CB.hasFnAttr(Attribute::AlwaysInline))
return InlineCost::getNever("no alwaysinline attribute");
+ if (Callee->hasFnAttribute(Attribute::AlwaysInline) && CB.isNoInline())
+ return InlineCost::getNever("noinline call site attribute");
+
auto IsViable = isInlineViable(*Callee);
if (!IsViable.isSuccess())
return InlineCost::getNever(IsViable.getFailureReason());
diff --git a/llvm/test/Transforms/Inline/always-inline.ll b/llvm/test/Transforms/Inline/always-inline.ll
index f947bdbd87347..37e890532375c 100644
--- a/llvm/test/Transforms/Inline/always-inline.ll
+++ b/llvm/test/Transforms/Inline/always-inline.ll
@@ -314,3 +314,57 @@ define void @outer14() {
call void @inner14()
ret void
}
+
+define internal i32 @inner15() {
+; CHECK: @inner15(
+ ret i32 1
+}
+
+define i32 @outer15() {
+; CHECK-LABEL: @outer15(
+; CHECK: call
+
+ %r = call i32 @inner15() noinline
+ ret i32 %r
+}
+
+define internal i32 @inner16() alwaysinline {
+; CHECK: @inner16(
+ ret i32 1
+}
+
+define i32 @outer16() {
+; CHECK-LABEL: @outer16(
+; CHECK: call
+
+ %r = call i32 @inner16() noinline
+ ret i32 %r
+}
+
+define i32 @inner17() alwaysinline {
+; CHECK: @inner17(
+ ret i32 1
+}
+
+define i32 @outer17() {
+; CHECK-LABEL: @outer17(
+; CHECK: call
+
+ %r = call i32 @inner17() noinline
+ ret i32 %r
+}
+
+define i32 @inner18() noinline {
+; CHECK: @inner18(
+ ret i32 1
+}
+
+define i32 @outer18() {
+; CHECK-LABEL: @outer18(
+; CHECK-NOT: call
+; CHECK: ret
+
+ %r = call i32 @inner18() alwaysinline
+
+ ret i32 %r
+}
More information about the llvm-commits
mailing list