1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 11:13:28 +01:00

[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.

llvm-svn: 290590
This commit is contained in:
Chandler Carruth 2016-12-27 06:46:20 +00:00
parent 44c5a10c53
commit fba79f0538
2 changed files with 24 additions and 7 deletions

View File

@ -788,7 +788,13 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
// 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(LazyCallGraph::SCC &InitialC,
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(LazyCallGraph::SCC &InitialC,
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);

View File

@ -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"