[llvm] r290590 - [PM] Add one of the features left out of the initial inliner patch:

Chandler Carruth via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 26 22:46:21 PST 2016


Author: chandlerc
Date: Tue Dec 27 00:46:20 2016
New Revision: 290590

URL: http://llvm.org/viewvc/llvm-project?rev=290590&view=rev
Log:
[PM] Add one of the features left out of the initial inliner patch:
skipping indirectly recursive inline chains.

To do this, we implicitly build an inline stack for each callsite and
check prior to inlining that doing so would not form a cycle. This uses
the exact same technique and even shares some code with the legacy PM
inliner.

This solution remains deeply unsatisfying to me because it means we
cannot actually iterate the inliner externally. Doing so would not be
able to easily detect and avoid such cycles. Some day I would very much
like to have a solution that works without this internal state to detect
cycles, but this is not that day.

Modified:
    llvm/trunk/lib/Transforms/IPO/Inliner.cpp
    llvm/trunk/test/Transforms/Inline/noinline-recursive-fn.ll

Modified: llvm/trunk/lib/Transforms/IPO/Inliner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/Inliner.cpp?rev=290590&r1=290589&r2=290590&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/Inliner.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/Inliner.cpp Tue Dec 27 00:46:20 2016
@@ -788,7 +788,13 @@ PreservedAnalyses InlinerPass::run(LazyC
   // We also use a secondary worklist of call sites within a particular node to
   // allow quickly continuing to inline through newly inlined call sites where
   // possible.
-  SmallVector<CallSite, 16> Calls;
+  SmallVector<std::pair<CallSite, int>, 16> Calls;
+
+  // When inlining a callee produces new call sites, we want to keep track of
+  // the fact that they were inlined from the callee.  This allows us to avoid
+  // infinite inlining in some obscure cases.  To represent this, we use an
+  // index into the InlineHistory vector.
+  SmallVector<std::pair<Function *, int>, 16> InlineHistory;
 
   // Track a set vector of inlined callees so that we can augment the caller
   // with all of their edges in the call graph before pruning out the ones that
@@ -820,13 +826,19 @@ PreservedAnalyses InlinerPass::run(LazyC
       if (auto CS = CallSite(&I))
         if (Function *Callee = CS.getCalledFunction())
           if (!Callee->isDeclaration())
-            Calls.push_back(CS);
+            Calls.push_back({CS, -1});
 
     bool DidInline = false;
     while (!Calls.empty()) {
-      CallSite CS = Calls.pop_back_val();
+      int InlineHistoryID;
+      CallSite CS;
+      std::tie(CS, InlineHistoryID) = Calls.pop_back_val();
       Function &Callee = *CS.getCalledFunction();
 
+      if (InlineHistoryID != -1 &&
+          InlineHistoryIncludes(&Callee, InlineHistoryID, InlineHistory))
+        continue;
+
       // Check whether we want to inline this callsite.
       if (!shouldInline(CS, GetInlineCost, ORE))
         continue;
@@ -837,10 +849,14 @@ PreservedAnalyses InlinerPass::run(LazyC
       InlinedCallees.insert(&Callee);
 
       // Add any new callsites to defined functions to the worklist.
-      for (CallSite &CS : reverse(IFI.InlinedCallSites))
-        if (Function *NewCallee = CS.getCalledFunction())
-          if (!NewCallee->isDeclaration())
-            Calls.push_back(CS);
+      if (!IFI.InlinedCallSites.empty()) {
+        int NewHistoryID = InlineHistory.size();
+        InlineHistory.push_back({&Callee, InlineHistoryID});
+        for (CallSite &CS : reverse(IFI.InlinedCallSites))
+          if (Function *NewCallee = CS.getCalledFunction())
+            if (!NewCallee->isDeclaration())
+              Calls.push_back({CS, NewHistoryID});
+      }
 
       // Merge the attributes based on the inlining.
       AttributeFuncs::mergeAttributesForInlining(F, Callee);

Modified: llvm/trunk/test/Transforms/Inline/noinline-recursive-fn.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Inline/noinline-recursive-fn.ll?rev=290590&r1=290589&r2=290590&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/Inline/noinline-recursive-fn.ll (original)
+++ llvm/trunk/test/Transforms/Inline/noinline-recursive-fn.ll Tue Dec 27 00:46:20 2016
@@ -3,6 +3,7 @@
 ; inliner heuristics are not set up for this.
 
 ; RUN: opt -inline -S < %s | FileCheck %s
+; RUN: opt -passes='cgscc(inline)' -S < %s | FileCheck %s
 
 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
 target triple = "x86_64-apple-darwin10.3"




More information about the llvm-commits mailing list