| commit 0291e2c9330930bd74bfb8206cf6447a84bf492c |
| Author: Arthur Eubanks <aeubanks@google.com> |
| Date: Tue Sep 1 15:55:05 2020 -0700 |
| |
| [Inliner] Run always-inliner in inliner-wrapper |
| |
| An alwaysinline function may not get inlined in inliner-wrapper due to |
| the inlining order. |
| |
| Previously for the following, the inliner would first inline @a() into @b(), |
| |
| ``` |
| define void @a() { |
| entry: |
| call void @b() |
| ret void |
| } |
| |
| define void @b() alwaysinline { |
| entry: |
| br label %for.cond |
| |
| for.cond: |
| call void @a() |
| br label %for.cond |
| } |
| ``` |
| |
| making @b() recursive and unable to be inlined into @a(), ending at |
| |
| ``` |
| define void @a() { |
| entry: |
| call void @b() |
| ret void |
| } |
| |
| define void @b() alwaysinline { |
| entry: |
| br label %for.cond |
| |
| for.cond: |
| call void @b() |
| br label %for.cond |
| } |
| ``` |
| |
| Running always-inliner first makes sure that we respect alwaysinline in more cases. |
| |
| Fixes https://bugs.llvm.org/show_bug.cgi?id=46945. |
| |
| Reviewed By: davidxl, rnk |
| |
| Differential Revision: https://reviews.llvm.org/D86988 |
| |
| diff --git a/llvm/lib/Transforms/IPO/Inliner.cpp b/llvm/lib/Transforms/IPO/Inliner.cpp |
| index 7d2260f4c169..540042e5f069 100644 |
| --- a/llvm/lib/Transforms/IPO/Inliner.cpp |
| +++ b/llvm/lib/Transforms/IPO/Inliner.cpp |
| @@ -58,6 +58,7 @@ |
| #include "llvm/Support/CommandLine.h" |
| #include "llvm/Support/Debug.h" |
| #include "llvm/Support/raw_ostream.h" |
| +#include "llvm/Transforms/IPO/AlwaysInliner.h" |
| #include "llvm/Transforms/Utils/CallPromotionUtils.h" |
| #include "llvm/Transforms/Utils/Cloning.h" |
| #include "llvm/Transforms/Utils/ImportedFunctionsInliningStatistics.h" |
| @@ -91,6 +92,11 @@ static cl::opt<bool> |
| DisableInlinedAllocaMerging("disable-inlined-alloca-merging", |
| cl::init(false), cl::Hidden); |
| |
| +/// Flag to disable adding AlwaysInlinerPass to ModuleInlinerWrapperPass. |
| +/// TODO: remove this once this has is baked in for long enough. |
| +static cl::opt<bool> DisableAlwaysInlinerInModuleWrapper( |
| + "disable-always-inliner-in-module-wrapper", cl::init(false), cl::Hidden); |
| + |
| namespace { |
| |
| enum class InlinerFunctionImportStatsOpts { |
| @@ -1055,6 +1061,8 @@ PreservedAnalyses ModuleInlinerWrapperPass::run(Module &M, |
| return PreservedAnalyses::all(); |
| } |
| |
| + if (!DisableAlwaysInlinerInModuleWrapper) |
| + MPM.addPass(AlwaysInlinerPass()); |
| // We wrap the CGSCC pipeline in a devirtualization repeater. This will try |
| // to detect when we devirtualize indirect calls and iterate the SCC passes |
| // in that case to try and catch knock-on inlining or function attrs |