mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-23 20:22:09 +00:00
The inliner was choosing to not consider call sites
that appear in the SCC as a result of inlining as candidates for inlining. Change this so that it *does* consider call sites that change from being indirect to being direct as a result of inlining. This allows it to completely "devirtualize" the testcase. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@102146 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
3a1287b470
commit
fe9af3b1f7
@ -175,9 +175,14 @@ public:
|
|||||||
/// get copied into the caller.
|
/// get copied into the caller.
|
||||||
SmallVector<AllocaInst*, 4> StaticAllocas;
|
SmallVector<AllocaInst*, 4> StaticAllocas;
|
||||||
|
|
||||||
|
/// DevirtualizedCalls - InlineFunction fills this in with callsites that were
|
||||||
|
/// inlined from the callee that went from being indirect calls to direct
|
||||||
|
/// calls due to inlining. This is only filled in if CG is non-null.
|
||||||
|
SmallVector<Instruction*, 2> DevirtualizedCalls;
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
StaticAllocas.clear();
|
StaticAllocas.clear();
|
||||||
|
DevirtualizedCalls.clear();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -383,11 +383,17 @@ bool Inliner::runOnSCC(CallGraphSCC &SCC) {
|
|||||||
if (!shouldInline(CS))
|
if (!shouldInline(CS))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Attempt to inline the function...
|
// Attempt to inline the function.
|
||||||
if (!InlineCallIfPossible(CS, InlineInfo, InlinedArrayAllocas))
|
if (!InlineCallIfPossible(CS, InlineInfo, InlinedArrayAllocas))
|
||||||
continue;
|
continue;
|
||||||
++NumInlined;
|
++NumInlined;
|
||||||
|
|
||||||
|
// If inlining this function devirtualized any call sites, throw them
|
||||||
|
// onto our worklist to process. They are useful inline candidates.
|
||||||
|
for (unsigned i = 0, e = InlineInfo.DevirtualizedCalls.size();
|
||||||
|
i != e; ++i)
|
||||||
|
CallSites.push_back(CallSite(InlineInfo.DevirtualizedCalls[i]));
|
||||||
|
|
||||||
// Update the cached cost info with the inlined call.
|
// Update the cached cost info with the inlined call.
|
||||||
growCachedCostInfo(Caller, Callee);
|
growCachedCostInfo(Caller, Callee);
|
||||||
}
|
}
|
||||||
|
@ -170,7 +170,8 @@ static void HandleInlinedInvoke(InvokeInst *II, BasicBlock *FirstNewBlock,
|
|||||||
static void UpdateCallGraphAfterInlining(CallSite CS,
|
static void UpdateCallGraphAfterInlining(CallSite CS,
|
||||||
Function::iterator FirstNewBlock,
|
Function::iterator FirstNewBlock,
|
||||||
DenseMap<const Value*, Value*> &ValueMap,
|
DenseMap<const Value*, Value*> &ValueMap,
|
||||||
CallGraph &CG) {
|
InlineFunctionInfo &IFI) {
|
||||||
|
CallGraph &CG = *IFI.CG;
|
||||||
const Function *Caller = CS.getInstruction()->getParent()->getParent();
|
const Function *Caller = CS.getInstruction()->getParent()->getParent();
|
||||||
const Function *Callee = CS.getCalledFunction();
|
const Function *Callee = CS.getCalledFunction();
|
||||||
CallGraphNode *CalleeNode = CG[Callee];
|
CallGraphNode *CalleeNode = CG[Callee];
|
||||||
@ -210,6 +211,10 @@ static void UpdateCallGraphAfterInlining(CallSite CS,
|
|||||||
if (Function *F = CallSite(NewCall).getCalledFunction()) {
|
if (Function *F = CallSite(NewCall).getCalledFunction()) {
|
||||||
// Indirect call site resolved to direct call.
|
// Indirect call site resolved to direct call.
|
||||||
CallerNode->addCalledFunction(CallSite::get(NewCall), CG[F]);
|
CallerNode->addCalledFunction(CallSite::get(NewCall), CG[F]);
|
||||||
|
|
||||||
|
// Remember that this callsite got devirtualized for the client of
|
||||||
|
// InlineFunction.
|
||||||
|
IFI.DevirtualizedCalls.push_back(NewCall);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -362,7 +367,7 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI) {
|
|||||||
|
|
||||||
// Update the callgraph if requested.
|
// Update the callgraph if requested.
|
||||||
if (IFI.CG)
|
if (IFI.CG)
|
||||||
UpdateCallGraphAfterInlining(CS, FirstNewBlock, ValueMap, *IFI.CG);
|
UpdateCallGraphAfterInlining(CS, FirstNewBlock, ValueMap, IFI);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there are any alloca instructions in the block that used to be the entry
|
// If there are any alloca instructions in the block that used to be the entry
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
; RUN: opt < %s -inline | llvm-dis
|
; RUN: opt < %s -inline -S | FileCheck %s
|
||||||
; PR4834
|
; PR4834
|
||||||
|
|
||||||
define i32 @main() {
|
define i32 @test1() {
|
||||||
%funcall1_ = call fastcc i32 ()* ()* @f1()
|
%funcall1_ = call fastcc i32 ()* ()* @f1()
|
||||||
%executecommandptr1_ = call i32 %funcall1_()
|
%executecommandptr1_ = call i32 %funcall1_()
|
||||||
ret i32 %executecommandptr1_
|
ret i32 %executecommandptr1_
|
||||||
@ -14,3 +14,31 @@ define internal fastcc i32 ()* @f1() nounwind readnone {
|
|||||||
define internal i32 @f2() nounwind readnone {
|
define internal i32 @f2() nounwind readnone {
|
||||||
ret i32 1
|
ret i32 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; CHECK: @test1()
|
||||||
|
; CHECK-NEXT: ret i32 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
declare i8* @f1a(i8*) ssp align 2
|
||||||
|
|
||||||
|
define internal i32 @f2a(i8* %t) inlinehint ssp {
|
||||||
|
entry:
|
||||||
|
ret i32 41
|
||||||
|
}
|
||||||
|
|
||||||
|
define internal i32 @f3a(i32 (i8*)* %__f) ssp {
|
||||||
|
entry:
|
||||||
|
%A = call i32 %__f(i8* undef)
|
||||||
|
ret i32 %A
|
||||||
|
}
|
||||||
|
|
||||||
|
define i32 @test2(i8* %this) ssp align 2 {
|
||||||
|
%X = call i32 @f3a(i32 (i8*)* @f2a) ssp
|
||||||
|
ret i32 %X
|
||||||
|
}
|
||||||
|
|
||||||
|
; CHECK: @test2
|
||||||
|
; CHECK-NEXT: ret i32 41
|
Loading…
x
Reference in New Issue
Block a user