aeubanks created this revision.
aeubanks added a reviewer: mtrofin.
Herald added subscribers: ormris, hiraditya, eraman.
aeubanks requested review of this revision.
Herald added projects: clang, LLVM.
Herald added subscribers: llvm-commits, cfe-commits.

For PR46945 we added an extra alwaysinline inliner pass that runs before
the normal inliner pass. This was to fix the issue where we have two
mutually recursive functions, one marked alwaysinline, but due to inline
ordering, the other function may have been inlined into the alwaysinline
function first, causing the alwaysinline function to not be inlined into
the other function.

Adding a whole new pass is quite a bit of work. Rather, we can just
choose to handle alwaysinline calls first before inlining normal calls.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D110607

Files:
  clang/test/Frontend/optimization-remark-line-directive.c
  clang/test/Frontend/optimization-remark-new-pm.c
  clang/test/Frontend/optimization-remark-with-hotness-new-pm.c
  clang/test/Frontend/optimization-remark.c
  llvm/include/llvm/Analysis/InlineAdvisor.h
  llvm/include/llvm/Analysis/InlineOrder.h
  llvm/include/llvm/Transforms/IPO/Inliner.h
  llvm/lib/Analysis/InlineAdvisor.cpp
  llvm/lib/Passes/PassBuilder.cpp
  llvm/lib/Passes/PassBuilderPipelines.cpp
  llvm/lib/Passes/PassRegistry.def
  llvm/lib/Transforms/IPO/Inliner.cpp
  llvm/test/Other/new-pm-print-pipeline.ll
  llvm/test/Transforms/Inline/inline_nossp.ll
  llvm/test/Transforms/Inline/inline_stats.ll
  llvm/test/Transforms/Inline/no-inline-line-tables.ll
  llvm/test/Transforms/Inline/optimization-remarks-with-hotness.ll
  llvm/test/Transforms/Inline/optimization-remarks.ll

Index: llvm/test/Transforms/Inline/optimization-remarks.ll
===================================================================
--- llvm/test/Transforms/Inline/optimization-remarks.ll
+++ llvm/test/Transforms/Inline/optimization-remarks.ll
@@ -19,13 +19,6 @@
 ; RUN:       -pass-remarks-analysis=inline -pass-remarks-with-hotness -S 2>&1 | \
 ; RUN:       FileCheck -check-prefixes=CHECK,HOTNESS,ALWAYS %s
 
-; RUN: opt < %s -passes=inliner-wrapper-no-mandatory-first -pass-remarks=inline -pass-remarks-missed=inline \
-; RUN:       -pass-remarks-analysis=inline -S 2>&1 | \
-; RUN:       FileCheck -check-prefixes=CHECK,NO_HOTNESS,ALWAYS %s
-; RUN: opt < %s -passes=inliner-wrapper-no-mandatory-first -pass-remarks=inline -pass-remarks-missed=inline \
-; RUN:       -pass-remarks-analysis=inline -pass-remarks-with-hotness -S 2>&1 | \
-; RUN:       FileCheck -check-prefixes=CHECK,HOTNESS,ALWAYS %s
-
 ; HOTNESS-DAG: fox will not be inlined into bar because its definition is unavailable
 ; NO_HOTNESS-NOT: fox will not be inlined into bar because its definition is unavailable
 ; ALWAYS-DAG: 'foo' inlined into 'bar' with (cost=always): always inline attribute
Index: llvm/test/Transforms/Inline/optimization-remarks-with-hotness.ll
===================================================================
--- llvm/test/Transforms/Inline/optimization-remarks-with-hotness.ll
+++ llvm/test/Transforms/Inline/optimization-remarks-with-hotness.ll
@@ -4,9 +4,6 @@
 ; RUN: opt < %s -passes=inline -pass-remarks=inline -pass-remarks-missed=inline \
 ; RUN:     -pass-remarks-analysis=inline -pass-remarks-with-hotness -S 2>&1 \
 ; RUN:     | FileCheck %s
-; RUN: opt < %s -passes=inliner-wrapper-no-mandatory-first -pass-remarks=inline -pass-remarks-missed=inline \
-; RUN:     -pass-remarks-analysis=inline -pass-remarks-with-hotness -S 2>&1 \
-; RUN:     | FileCheck %s
 
 ; CHECK: 'foo' inlined into 'bar' with (cost=always): always inline attribute (hotness: 30)
 ; CHECK: 'foz' not inlined into 'bar' because it should never be inlined (cost=never): noinline function attribute (hotness: 30)
Index: llvm/test/Transforms/Inline/no-inline-line-tables.ll
===================================================================
--- llvm/test/Transforms/Inline/no-inline-line-tables.ll
+++ llvm/test/Transforms/Inline/no-inline-line-tables.ll
@@ -22,17 +22,17 @@
 declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
 
 ; Function Attrs: alwaysinline nounwind
-define i32 @g(i32 %x) #0 !dbg !15 {
+define i32 @g(i32 %y) #0 !dbg !15 {
 entry:
-  %x.addr = alloca i32, align 4
-  store i32 %x, i32* %x.addr, align 4
-  call void @llvm.dbg.declare(metadata i32* %x.addr, metadata !16, metadata !DIExpression()), !dbg !17
+  %y.addr = alloca i32, align 4
+  store i32 %y, i32* %y.addr, align 4
+  call void @llvm.dbg.declare(metadata i32* %y.addr, metadata !16, metadata !DIExpression()), !dbg !17
   br label %L, !dbg !17
 
 L:                                                ; preds = %entry
   call void @llvm.dbg.label(metadata !18), !dbg !19
-  store i32 42, i32* %x.addr, align 4, !dbg !20
-  %0 = load i32, i32* %x.addr, align 4, !dbg !21
+  store i32 42, i32* %y.addr, align 4, !dbg !20
+  %0 = load i32, i32* %y.addr, align 4, !dbg !21
   ret i32 %0, !dbg !21
 }
 
@@ -54,7 +54,7 @@
 ; start of the basic block.
 ; CHECK-NOT: @g
 ; CHECK-NOT: @llvm.dbg.label
-; CHECK: %{{[0-9]+}} = load i32, i32* %x.addr.i1, align 4, !dbg ![[VAR2:[0-9]+]]
+; CHECK: %{{[0-9]+}} = load i32, i32* %y.addr.i, align 4, !dbg ![[VAR2:[0-9]+]]
   %call1 = call i32 @g(i32 340), !dbg !26
   ret i32 0, !dbg !27
 }
Index: llvm/test/Transforms/Inline/inline_stats.ll
===================================================================
--- llvm/test/Transforms/Inline/inline_stats.ll
+++ llvm/test/Transforms/Inline/inline_stats.ll
@@ -6,9 +6,6 @@
 ; RUN: opt -S -passes=inline -inliner-function-import-stats=basic < %s 2>&1 | FileCheck %s --check-prefixes=CHECK-BASIC,CHECK
 ; RUN: opt -S -passes=inline -inliner-function-import-stats=verbose < %s 2>&1 | FileCheck %s --check-prefixes="CHECK-VERBOSE",CHECK
 
-; RUN: opt -S -passes=inliner-wrapper-no-mandatory-first -inliner-function-import-stats=basic < %s 2>&1 | FileCheck %s --check-prefixes=CHECK-BASIC,CHECK
-; RUN: opt -S -passes=inliner-wrapper-no-mandatory-first -inliner-function-import-stats=verbose < %s 2>&1 | FileCheck %s --check-prefixes="CHECK-VERBOSE",CHECK
-
 ; RUN: opt -S -passes=inliner-wrapper -inliner-function-import-stats=basic < %s 2>&1 | FileCheck %s --check-prefixes=CHECK-BASIC,CHECK
 ; RUN: opt -S -passes=inliner-wrapper -inliner-function-import-stats=verbose < %s 2>&1 | FileCheck %s --check-prefixes=CHECK-VERBOSE,CHECK
 
Index: llvm/test/Transforms/Inline/inline_nossp.ll
===================================================================
--- llvm/test/Transforms/Inline/inline_nossp.ll
+++ llvm/test/Transforms/Inline/inline_nossp.ll
@@ -2,36 +2,70 @@
 ; RUN: opt -passes='cgscc(inline)' %s -S -pass-remarks-missed=inline 2>&1 | FileCheck --check-prefixes=CHECK,CHECK-INLINE %s
 ; RUN: opt -passes=always-inline -o - -S %s | FileCheck %s
 
-; CHECK-INLINE: 'ssp' not inlined into 'nossp_caller' because it should never be inlined (cost=never): stack protected callee but caller requested no stack protector
-; CHECK-INLINE: 'nossp' not inlined into 'ssp_caller' because it should never be inlined (cost=never): stack protected caller but callee requested no stack protector
+; CHECK-INLINE: 'ssp' not inlined into 'nossp_caller1' because it should never be inlined (cost=never): stack protected callee but caller requested no stack protector
+; CHECK-INLINE: 'nossp' not inlined into 'ssp_caller1' because it should never be inlined (cost=never): stack protected caller but callee requested no stack protector
 
-; Not interesting to test.
-define i32 @nossp() { ret i32 41 }
-define i32 @ssp() sspstrong { ret i32 42 }
-define i32 @nossp_alwaysinline() alwaysinline { ret i32 43 }
-define i32 @ssp_alwaysinline() sspstrong alwaysinline { ret i32 44 }
+define void @nossp() {
+; CHECK-LABEL: @nossp(
+; CHECK-NEXT:    ret void
+;
+  ret void
+}
+define void @ssp() sspstrong {
+; CHECK-LABEL: @ssp(
+; CHECK-NEXT:    ret void
+;
+  ret void
+}
+define void @nossp_alwaysinline() alwaysinline {
+; CHECK-LABEL: @nossp_alwaysinline(
+; CHECK-NEXT:    ret void
+;
+  ret void
+}
+define void @ssp_alwaysinline() sspstrong alwaysinline {
+; CHECK-LABEL: @ssp_alwaysinline(
+; CHECK-NEXT:    ret void
+;
+  ret void
+}
 
 ; @ssp should not be inlined due to mismatch stack protector.
+define void @nossp_caller1() {
+; CHECK-LABEL: @nossp_caller1(
+; CHECK-NEXT:    call void @ssp()
+; CHECK-NEXT:    ret void
+;
+  call void @ssp()
+  ret void
+}
+
 ; @ssp_alwaysinline should be inlined due to alwaysinline.
-define i32 @nossp_caller() {
-; CHECK-LABEL: @nossp_caller(
-; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @ssp()
-; CHECK-NEXT:    ret i32 44
+define void @nossp_caller2() {
+; CHECK-LABEL: @nossp_caller2(
+; CHECK-NEXT:    ret void
 ;
-  call i32 @ssp()
-  %2 = call i32 @ssp_alwaysinline()
-  ret i32 %2
+  call void @ssp_alwaysinline()
+  ret void
 }
+
 ; @nossp should not be inlined due to mismatch stack protector.
+define void @ssp_caller1() sspstrong {
+; CHECK-LABEL: @ssp_caller1(
+; CHECK-NEXT:    call void @nossp()
+; CHECK-NEXT:    ret void
+;
+  call void @nossp()
+  ret void
+}
+
 ; @nossp_alwaysinline should be inlined due to alwaysinline.
-define i32 @ssp_caller() sspstrong {
-; CHECK-LABEL: @ssp_caller(
-; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @nossp()
-; CHECK-NEXT:    ret i32 43
+define void @ssp_caller2() sspstrong {
+; CHECK-LABEL: @ssp_caller2(
+; CHECK-NEXT:    ret void
 ;
-  call i32 @nossp()
-  %2 = call i32 @nossp_alwaysinline()
-  ret i32 %2
+  call void @nossp_alwaysinline()
+  ret void
 }
 
 ; The alwaysinline attribute can also appear on the CallBase (ie. the call
@@ -41,10 +75,10 @@
 ;
 ; Curiously, the always_inline attribute on a CallInst is only expanded by the
 ; inline pass, but not always_inline pass!
-define i32 @nossp_alwaysinline_caller() {
+define void @nossp_alwaysinline_caller() {
 ; CHECK-INLINE-LABEL: @nossp_alwaysinline_caller(
-; CHECK-INLINE-NEXT:    ret i32 42
+; CHECK-INLINE-NEXT:    ret void
 ;
-  %1 = call i32 @ssp() alwaysinline
-  ret i32 %1
+  call void @ssp() alwaysinline
+  ret void
 }
Index: llvm/test/Other/new-pm-print-pipeline.ll
===================================================================
--- llvm/test/Other/new-pm-print-pipeline.ll
+++ llvm/test/Other/new-pm-print-pipeline.ll
@@ -61,8 +61,8 @@
 ; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='function(loop-vectorize<no-interleave-forced-only;no-vectorize-forced-only>,loop-vectorize<interleave-forced-only;vectorize-forced-only>)' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-19
 ; CHECK-19: function(loop-vectorize<no-interleave-forced-only;no-vectorize-forced-only;>,loop-vectorize<interleave-forced-only;vectorize-forced-only;>)
 
-; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='inliner-wrapper,inliner-wrapper-no-mandatory-first' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-20
-; CHECK-20: cgscc(inline<only-mandatory>,inline),cgscc(inline)
+; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='inliner-wrapper' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-20
+; CHECK-20: cgscc(inline)
 
 ; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='scc-oz-module-inliner' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-21
 ; CHECK-21: require<globals-aa>,function(invalidate<aa>),require<profile-summary>,cgscc(devirt<4>(inline<only-mandatory>,inline,{{.*}},instcombine{{.*}}))
Index: llvm/lib/Transforms/IPO/Inliner.cpp
===================================================================
--- llvm/lib/Transforms/IPO/Inliner.cpp
+++ llvm/lib/Transforms/IPO/Inliner.cpp
@@ -739,9 +739,12 @@
     for (Instruction &I : instructions(N.getFunction()))
       if (auto *CB = dyn_cast<CallBase>(&I))
         if (Function *Callee = CB->getCalledFunction()) {
-          if (!Callee->isDeclaration())
-            Calls->push({CB, -1});
-          else if (!isa<IntrinsicInst>(I)) {
+          if (!Callee->isDeclaration()) {
+            if (Callee->hasFnAttribute(Attribute::AlwaysInline))
+              Calls->push_front({CB, -1});
+            else
+              Calls->push({CB, -1});
+          } else if (!isa<IntrinsicInst>(I)) {
             using namespace ore;
             setInlineRemark(*CB, "unavailable definition");
             ORE.emit([&]() {
@@ -826,7 +829,7 @@
         continue;
       }
 
-      auto Advice = Advisor.getAdvice(*CB, OnlyMandatory);
+      auto Advice = Advisor.getAdvice(*CB);
       // Check whether we want to inline this callsite.
       if (!Advice->isInliningRecommended()) {
         Advice->recordUnattemptedInlining();
@@ -872,8 +875,12 @@
               NewCallee = ICB->getCalledFunction();
           }
           if (NewCallee)
-            if (!NewCallee->isDeclaration())
-              Calls->push({ICB, NewHistoryID});
+            if (!NewCallee->isDeclaration()) {
+              if (NewCallee->hasFnAttribute(Attribute::AlwaysInline))
+                Calls->push_front({ICB, NewHistoryID});
+              else
+                Calls->push({ICB, NewHistoryID});
+            }
         }
       }
 
@@ -1009,7 +1016,6 @@
 }
 
 ModuleInlinerWrapperPass::ModuleInlinerWrapperPass(InlineParams Params,
-                                                   bool MandatoryFirst,
                                                    InliningAdvisorMode Mode,
                                                    unsigned MaxDevirtIterations)
     : Params(Params), Mode(Mode), MaxDevirtIterations(MaxDevirtIterations),
@@ -1019,8 +1025,6 @@
   // into the callers so that our optimizations can reflect that.
   // For PreLinkThinLTO pass, we disable hot-caller heuristic for sample PGO
   // because it makes profile annotation in the backend inaccurate.
-  if (MandatoryFirst)
-    PM.addPass(InlinerPass(/*OnlyMandatory*/ true));
   PM.addPass(InlinerPass());
 }
 
@@ -1054,14 +1058,6 @@
   return PreservedAnalyses::all();
 }
 
-void InlinerPass::printPipeline(
-    raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
-  static_cast<PassInfoMixin<InlinerPass> *>(this)->printPipeline(
-      OS, MapClassName2PassName);
-  if (OnlyMandatory)
-    OS << "<only-mandatory>";
-}
-
 void ModuleInlinerWrapperPass::printPipeline(
     raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
   // Print some info about passes added to the wrapper. This is however
Index: llvm/lib/Passes/PassRegistry.def
===================================================================
--- llvm/lib/Passes/PassRegistry.def
+++ llvm/lib/Passes/PassRegistry.def
@@ -62,9 +62,6 @@
 MODULE_PASS("hotcoldsplit", HotColdSplittingPass())
 MODULE_PASS("inferattrs", InferFunctionAttrsPass())
 MODULE_PASS("inliner-wrapper", ModuleInlinerWrapperPass())
-MODULE_PASS("inliner-wrapper-no-mandatory-first", ModuleInlinerWrapperPass(
-  getInlineParams(),
-  false))
 MODULE_PASS("insert-gcov-profiling", GCOVProfilerPass())
 MODULE_PASS("instrorderfile", InstrOrderFilePass())
 MODULE_PASS("instrprof", InstrProfiling())
@@ -165,18 +162,12 @@
 CGSCC_PASS("openmp-opt-cgscc", OpenMPOptCGSCCPass())
 CGSCC_PASS("coro-split", CoroSplitPass())
 CGSCC_PASS("no-op-cgscc", NoOpCGSCCPass())
+CGSCC_PASS("inline", InlinerPass())
 #undef CGSCC_PASS
 
 #ifndef CGSCC_PASS_WITH_PARAMS
 #define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS)
 #endif
-CGSCC_PASS_WITH_PARAMS("inline",
-                       "InlinerPass",
-                       [](bool OnlyMandatory) {
-                         return InlinerPass(OnlyMandatory);
-                       },
-                       parseInlinerPassOptions,
-                       "only-mandatory")
 #undef CGSCC_PASS_WITH_PARAMS
 
 #ifndef FUNCTION_ANALYSIS
Index: llvm/lib/Passes/PassBuilderPipelines.cpp
===================================================================
--- llvm/lib/Passes/PassBuilderPipelines.cpp
+++ llvm/lib/Passes/PassBuilderPipelines.cpp
@@ -153,11 +153,6 @@
                                        cl::Hidden, cl::ZeroOrMore,
                                        cl::desc("Enable memory profiler"));
 
-static cl::opt<bool> PerformMandatoryInliningsFirst(
-    "mandatory-inlining-first", cl::init(true), cl::Hidden, cl::ZeroOrMore,
-    cl::desc("Perform mandatory inlinings module-wide, before performing "
-             "inlining."));
-
 static cl::opt<bool> EnableO3NonTrivialUnswitching(
     "enable-npm-O3-nontrivial-unswitch", cl::init(true), cl::Hidden,
     cl::ZeroOrMore, cl::desc("Enable non-trivial loop unswitching for -O3"));
@@ -675,8 +670,7 @@
   if (PGOOpt)
     IP.EnableDeferral = EnablePGOInlineDeferral;
 
-  ModuleInlinerWrapperPass MIWP(IP, PerformMandatoryInliningsFirst,
-                                UseInlineAdvisor, MaxDevirtIterations);
+  ModuleInlinerWrapperPass MIWP(IP, UseInlineAdvisor, MaxDevirtIterations);
 
   // Require the GlobalsAA analysis for the module so we can query it within
   // the CGSCC pipeline.
Index: llvm/lib/Passes/PassBuilder.cpp
===================================================================
--- llvm/lib/Passes/PassBuilder.cpp
+++ llvm/lib/Passes/PassBuilder.cpp
@@ -560,10 +560,6 @@
   return Result;
 }
 
-Expected<bool> parseInlinerPassOptions(StringRef Params) {
-  return parseSinglePassOption(Params, "only-mandatory", "InlinerPass");
-}
-
 Expected<bool> parseEarlyCSEPassOptions(StringRef Params) {
   return parseSinglePassOption(Params, "memssa", "EarlyCSE");
 }
Index: llvm/lib/Analysis/InlineAdvisor.cpp
===================================================================
--- llvm/lib/Analysis/InlineAdvisor.cpp
+++ llvm/lib/Analysis/InlineAdvisor.cpp
@@ -473,42 +473,8 @@
   freeDeletedFunctions();
 }
 
-std::unique_ptr<InlineAdvice> InlineAdvisor::getMandatoryAdvice(CallBase &CB,
-                                                                bool Advice) {
-  return std::make_unique<InlineAdvice>(this, CB, getCallerORE(CB), Advice);
-}
-
-InlineAdvisor::MandatoryInliningKind
-InlineAdvisor::getMandatoryKind(CallBase &CB, FunctionAnalysisManager &FAM,
-                                OptimizationRemarkEmitter &ORE) {
-  auto &Callee = *CB.getCalledFunction();
-
-  auto GetTLI = [&](Function &F) -> const TargetLibraryInfo & {
-    return FAM.getResult<TargetLibraryAnalysis>(F);
-  };
-
-  auto &TIR = FAM.getResult<TargetIRAnalysis>(Callee);
-
-  auto TrivialDecision =
-      llvm::getAttributeBasedInliningDecision(CB, &Callee, TIR, GetTLI);
-
-  if (TrivialDecision.hasValue()) {
-    if (TrivialDecision->isSuccess())
-      return MandatoryInliningKind::Always;
-    else
-      return MandatoryInliningKind::Never;
-  }
-  return MandatoryInliningKind::NotMandatory;
-}
-
-std::unique_ptr<InlineAdvice> InlineAdvisor::getAdvice(CallBase &CB,
-                                                       bool MandatoryOnly) {
-  if (!MandatoryOnly)
-    return getAdviceImpl(CB);
-  bool Advice = CB.getCaller() != CB.getCalledFunction() &&
-                MandatoryInliningKind::Always ==
-                    getMandatoryKind(CB, FAM, getCallerORE(CB));
-  return getMandatoryAdvice(CB, Advice);
+std::unique_ptr<InlineAdvice> InlineAdvisor::getAdvice(CallBase &CB) {
+  return getAdviceImpl(CB);
 }
 
 OptimizationRemarkEmitter &InlineAdvisor::getCallerORE(CallBase &CB) {
Index: llvm/include/llvm/Transforms/IPO/Inliner.h
===================================================================
--- llvm/include/llvm/Transforms/IPO/Inliner.h
+++ llvm/include/llvm/Transforms/IPO/Inliner.h
@@ -97,20 +97,16 @@
 /// passes be composed to achieve the same end result.
 class InlinerPass : public PassInfoMixin<InlinerPass> {
 public:
-  InlinerPass(bool OnlyMandatory = false) : OnlyMandatory(OnlyMandatory) {}
+  InlinerPass() = default;
   InlinerPass(InlinerPass &&Arg) = default;
 
   PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
                         LazyCallGraph &CG, CGSCCUpdateResult &UR);
 
-  void printPipeline(raw_ostream &OS,
-                     function_ref<StringRef(StringRef)> MapClassName2PassName);
-
 private:
   InlineAdvisor &getAdvisor(const ModuleAnalysisManagerCGSCCProxy::Result &MAM,
                             FunctionAnalysisManager &FAM, Module &M);
   std::unique_ptr<InlineAdvisor> OwnedAdvisor;
-  const bool OnlyMandatory;
 };
 
 /// Module pass, wrapping the inliner pass. This works in conjunction with the
@@ -122,7 +118,7 @@
     : public PassInfoMixin<ModuleInlinerWrapperPass> {
 public:
   ModuleInlinerWrapperPass(
-      InlineParams Params = getInlineParams(), bool MandatoryFirst = true,
+      InlineParams Params = getInlineParams(),
       InliningAdvisorMode Mode = InliningAdvisorMode::Default,
       unsigned MaxDevirtIterations = 0);
   ModuleInlinerWrapperPass(ModuleInlinerWrapperPass &&Arg) = default;
Index: llvm/include/llvm/Analysis/InlineOrder.h
===================================================================
--- llvm/include/llvm/Analysis/InlineOrder.h
+++ llvm/include/llvm/Analysis/InlineOrder.h
@@ -33,6 +33,8 @@
 
   virtual void push(const T &Elt) = 0;
 
+  virtual void push_front(const T &Elt) = 0;
+
   virtual T pop() = 0;
 
   virtual const_reference front() = 0;
@@ -52,6 +54,10 @@
 
   void push(const T &Elt) override { Calls.push_back(Elt); }
 
+  void push_front(const T &Elt) override {
+    Calls.insert(Calls.begin() + FirstIndex, Elt);
+  }
+
   T pop() override {
     assert(size() > 0);
     return Calls[FirstIndex++];
@@ -136,6 +142,8 @@
     InlineHistoryMap[CB] = InlineHistoryID;
   }
 
+  void push_front(const T &Elt) override { push(Elt); }
+
   T pop() override {
     assert(size() > 0);
     adjust();
Index: llvm/include/llvm/Analysis/InlineAdvisor.h
===================================================================
--- llvm/include/llvm/Analysis/InlineAdvisor.h
+++ llvm/include/llvm/Analysis/InlineAdvisor.h
@@ -140,12 +140,9 @@
 
   /// Get an InlineAdvice containing a recommendation on whether to
   /// inline or not. \p CB is assumed to be a direct call. \p FAM is assumed to
-  /// be up-to-date wrt previous inlining decisions. \p MandatoryOnly indicates
-  /// only mandatory (always-inline) call sites should be recommended - this
-  /// allows the InlineAdvisor track such inlininings.
+  /// be up-to-date wrt previous inlining decisions.
   /// Returns an InlineAdvice with the inlining recommendation.
-  std::unique_ptr<InlineAdvice> getAdvice(CallBase &CB,
-                                          bool MandatoryOnly = false);
+  std::unique_ptr<InlineAdvice> getAdvice(CallBase &CB);
 
   /// This must be called when the Inliner pass is entered, to allow the
   /// InlineAdvisor update internal state, as result of function passes run
@@ -160,8 +157,6 @@
 protected:
   InlineAdvisor(Module &M, FunctionAnalysisManager &FAM);
   virtual std::unique_ptr<InlineAdvice> getAdviceImpl(CallBase &CB) = 0;
-  virtual std::unique_ptr<InlineAdvice> getMandatoryAdvice(CallBase &CB,
-                                                           bool Advice);
 
   Module &M;
   FunctionAnalysisManager &FAM;
@@ -180,12 +175,6 @@
     return DeletedFunctions.count(F);
   }
 
-  enum class MandatoryInliningKind { NotMandatory, Always, Never };
-
-  static MandatoryInliningKind getMandatoryKind(CallBase &CB,
-                                                FunctionAnalysisManager &FAM,
-                                                OptimizationRemarkEmitter &ORE);
-
   OptimizationRemarkEmitter &getCallerORE(CallBase &CB);
 
 private:
Index: clang/test/Frontend/optimization-remark.c
===================================================================
--- clang/test/Frontend/optimization-remark.c
+++ clang/test/Frontend/optimization-remark.c
@@ -19,12 +19,12 @@
 //
 // The inliner for the new PM does not seem to be enabled at O0, but we still
 // get the same remarks with at least O1.
-// RUN: %clang_cc1 %s -Rpass=inline -fexperimental-new-pass-manager -O1 -emit-llvm -mllvm -mandatory-inlining-first=false -o - 2>&1 | FileCheck %s --check-prefix=CHECK-REMARKS
-// RUN: %clang_cc1 %s -Rpass=inline -fexperimental-new-pass-manager -O1 -Rno-everything -Reverything -emit-llvm -mllvm -mandatory-inlining-first=false -o -  2>&1 | FileCheck %s --check-prefix=CHECK-REMARKS
+// RUN: %clang_cc1 %s -Rpass=inline -fexperimental-new-pass-manager -O1 -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK-REMARKS
+// RUN: %clang_cc1 %s -Rpass=inline -fexperimental-new-pass-manager -O1 -Rno-everything -Reverything -emit-llvm -o -  2>&1 | FileCheck %s --check-prefix=CHECK-REMARKS
 //
 // Check that -w doesn't disable remarks.
 // RUN: %clang_cc1 %s -Rpass=inline -fno-experimental-new-pass-manager -w -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK-REMARKS
-// RUN: %clang_cc1 %s -Rpass=inline -fexperimental-new-pass-manager -O1 -w -emit-llvm -mllvm -mandatory-inlining-first=false -o - 2>&1 | FileCheck %s --check-prefix=CHECK-REMARKS
+// RUN: %clang_cc1 %s -Rpass=inline -fexperimental-new-pass-manager -O1 -w -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK-REMARKS
 //
 // -Reverything implies -Rpass=.*.
 // RUN: %clang_cc1 %s -Reverything -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK-REMARKS
Index: clang/test/Frontend/optimization-remark-with-hotness-new-pm.c
===================================================================
--- clang/test/Frontend/optimization-remark-with-hotness-new-pm.c
+++ clang/test/Frontend/optimization-remark-with-hotness-new-pm.c
@@ -18,47 +18,47 @@
 // RUN:     -fprofile-instrument-use-path=%t.profdata -Rpass=inline \
 // RUN:     -fexperimental-new-pass-manager -O1 \
 // RUN:     -Rpass-analysis=inline -Rpass-missed=inline \
-// RUN:     -fdiagnostics-show-hotness -verify -mllvm -mandatory-inlining-first=false
+// RUN:     -fdiagnostics-show-hotness -verify
 // The clang version of the previous test.
 // RUN: %clang -target x86_64-apple-macosx10.9 %s -c -emit-llvm -o /dev/null \
 // RUN:     -fprofile-instr-use=%t.profdata -Rpass=inline \
 // RUN:     -fexperimental-new-pass-manager -O1 \
 // RUN:     -Rpass-analysis=inline -Rpass-missed=inline \
-// RUN:     -fdiagnostics-show-hotness -Xclang -verify -mllvm -mandatory-inlining-first=false
+// RUN:     -fdiagnostics-show-hotness -Xclang -verify
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name \
 // RUN:     optimization-remark-with-hotness.c %s -emit-llvm-only \
 // RUN:     -fprofile-sample-use=%t-sample.profdata -Rpass=inline \
 // RUN:     -fexperimental-new-pass-manager -O1 \
 // RUN:     -Rpass-analysis=inline -Rpass-missed=inline \
 // RUN:     -fdiagnostics-show-hotness -fdiagnostics-hotness-threshold=10 \
-// RUN:     -verify -mllvm -mandatory-inlining-first=false
+// RUN:     -verify
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name \
 // RUN:     optimization-remark-with-hotness.c %s -emit-llvm-only \
 // RUN:     -fprofile-instrument-use-path=%t.profdata -Rpass=inline \
 // RUN:     -fexperimental-new-pass-manager -O1 \
 // RUN:     -Rpass-analysis=inline -Rpass-missed=inline \
-// RUN:     -fdiagnostics-show-hotness -fdiagnostics-hotness-threshold=10 -verify -mllvm -mandatory-inlining-first=false
+// RUN:     -fdiagnostics-show-hotness -fdiagnostics-hotness-threshold=10 -verify
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name \
 // RUN:     optimization-remark-with-hotness.c %s -emit-llvm-only \
 // RUN:     -fprofile-instrument-use-path=%t.profdata -Rpass=inline \
 // RUN:     -fexperimental-new-pass-manager -O1 \
-// RUN:     -Rpass-analysis=inline -mllvm -mandatory-inlining-first=false 2>&1 | FileCheck -check-prefix=HOTNESS_OFF %s
+// RUN:     -Rpass-analysis=inline 2>&1 | FileCheck -check-prefix=HOTNESS_OFF %s
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name \
 // RUN:     optimization-remark-with-hotness.c %s -emit-llvm-only \
 // RUN:     -fprofile-instrument-use-path=%t.profdata -Rpass=inline \
 // RUN:     -fexperimental-new-pass-manager -O1 \
-// RUN:     -Rpass-analysis=inline -Rno-pass-with-hotness -mllvm -mandatory-inlining-first=false 2>&1 | FileCheck \
+// RUN:     -Rpass-analysis=inline -Rno-pass-with-hotness 2>&1 | FileCheck \
 // RUN:     -check-prefix=HOTNESS_OFF %s
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name \
 // RUN:     optimization-remark-with-hotness.c %s -emit-llvm-only \
 // RUN:     -fprofile-instrument-use-path=%t.profdata -Rpass=inline \
 // RUN:     -Rpass-analysis=inline -fdiagnostics-show-hotness \
-// RUN:     -fdiagnostics-hotness-threshold=100 -mllvm -mandatory-inlining-first=false 2>&1 \
+// RUN:     -fdiagnostics-hotness-threshold=100 2>&1 \
 // RUN:     | FileCheck -allow-empty -check-prefix=THRESHOLD %s
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name \
 // RUN:     optimization-remark-with-hotness.c %s -emit-llvm-only \
 // RUN:     -Rpass=inline -Rpass-analysis=inline \
-// RUN:     -fdiagnostics-show-hotness -fdiagnostics-hotness-threshold=10 -mllvm -mandatory-inlining-first=false 2>&1 \
+// RUN:     -fdiagnostics-show-hotness -fdiagnostics-hotness-threshold=10 2>&1 \
 // RUN:     | FileCheck -check-prefix=NO_PGO %s
 
 int foo(int x, int y) __attribute__((always_inline));
Index: clang/test/Frontend/optimization-remark-new-pm.c
===================================================================
--- clang/test/Frontend/optimization-remark-new-pm.c
+++ clang/test/Frontend/optimization-remark-new-pm.c
@@ -1,8 +1,8 @@
 // Verify that remarks for the inliner appear. The remarks under the new PM will
 // be slightly different than those emitted by the legacy PM. The new PM inliner
 // also doesnot appear to be added at O0, so we test at O1.
-// RUN: %clang_cc1 %s -Rpass=inline -Rpass-analysis=inline -Rpass-missed=inline -O1 -fexperimental-new-pass-manager -emit-llvm-only -mllvm -mandatory-inlining-first=false -verify
-// RUN: %clang_cc1 %s -Rpass=inline -Rpass-analysis=inline -Rpass-missed=inline -O1 -fexperimental-new-pass-manager -emit-llvm-only -debug-info-kind=line-tables-only -mllvm -mandatory-inlining-first=false -verify
+// RUN: %clang_cc1 %s -Rpass=inline -Rpass-analysis=inline -Rpass-missed=inline -O1 -fexperimental-new-pass-manager -emit-llvm-only -verify
+// RUN: %clang_cc1 %s -Rpass=inline -Rpass-analysis=inline -Rpass-missed=inline -O1 -fexperimental-new-pass-manager -emit-llvm-only -debug-info-kind=line-tables-only -verify
 
 int foo(int x, int y) __attribute__((always_inline));
 int foo(int x, int y) { return x + y; }
Index: clang/test/Frontend/optimization-remark-line-directive.c
===================================================================
--- clang/test/Frontend/optimization-remark-line-directive.c
+++ clang/test/Frontend/optimization-remark-line-directive.c
@@ -6,7 +6,7 @@
 
 // The new PM inliner is not added to the default pipeline at O0, so we add
 // some optimizations to trigger it.
-// RUN: %clang_cc1 %s -Rpass=inline -fexperimental-new-pass-manager -O1 -debug-info-kind=line-tables-only -emit-llvm-only -mllvm -mandatory-inlining-first=false -verify
+// RUN: %clang_cc1 %s -Rpass=inline -fexperimental-new-pass-manager -O1 -debug-info-kind=line-tables-only -emit-llvm-only -verify
 
 int foo(int x, int y) __attribute__((always_inline));
 int foo(int x, int y) { return x + y; }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D110607: [Inliner] ... Arthur Eubanks via Phabricator via cfe-commits

Reply via email to