Index: lib/Transforms/IPO/Inliner.cpp =================================================================== --- lib/Transforms/IPO/Inliner.cpp +++ lib/Transforms/IPO/Inliner.cpp @@ -830,6 +830,8 @@ // incrementally maknig a single function grow in a super linear fashion. SmallVector, 16> Calls; + SmallPtrSet SCCFunctions; + // Populate the initial list of calls in this SCC. for (auto &N : InitialC) { // We want to generally process call sites top-down in order for @@ -842,11 +844,20 @@ if (Function *Callee = CS.getCalledFunction()) if (!Callee->isDeclaration()) Calls.push_back({CS, -1}); + SCCFunctions.insert(&N.getFunction()); } if (Calls.empty()) return PreservedAnalyses::all(); - // Capture updatable variables for the current SCC and RefSCC. + // Now that we have all of the call sites, move the ones to functions in the + // current SCC to the end of the list. + unsigned FirstCallInSCC = Calls.size(); + for (unsigned i = 0; i < FirstCallInSCC; ++i) + if (Function *F = Calls[i].first.getCalledFunction()) + if (SCCFunctions.count(F)) + std::swap(Calls[i--], Calls[--FirstCallInSCC]); + + // Capture updatable variables for the current SC and RefSCC. auto *C = &InitialC; auto *RC = &C->getOuterRefSCC(); Index: test/Transforms/Inline/cgscc-order.ll =================================================================== --- /dev/null +++ test/Transforms/Inline/cgscc-order.ll @@ -0,0 +1,36 @@ +; RUN: opt < %s -passes='cgscc(inline)' -S -inline-threshold=30 | FileCheck %s + +@glbl = external global i32 + +define void @out() { + store i32 0, i32* @glbl + store i32 1, i32* @glbl + store i32 2, i32* @glbl + store i32 3, i32* @glbl + store i32 4, i32* @glbl + store i32 5, i32* @glbl + store i32 6, i32* @glbl + store i32 7, i32* @glbl + store i32 8, i32* @glbl + store i32 9, i32* @glbl + ret void +} + +define void @scc_a() { +entry: + call void @scc_b() + call void @out() + ret void +} + +define void @scc_b() { +; CHECK-LABEL: define void @scc_b( +; Make sure out is inlined into scc_a first so that scc_a is too big to be +; inined into scc_b +entry: +; CHECK: call +; CHECK-NEXT: ret + call void @scc_a() + ret void +} +