mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-23 02:29:18 +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
@ -174,10 +174,15 @@ public:
|
||||
/// StaticAllocas - InlineFunction fills this in with all static allocas that
|
||||
/// get copied into the caller.
|
||||
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() {
|
||||
StaticAllocas.clear();
|
||||
DevirtualizedCalls.clear();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -383,11 +383,17 @@ bool Inliner::runOnSCC(CallGraphSCC &SCC) {
|
||||
if (!shouldInline(CS))
|
||||
continue;
|
||||
|
||||
// Attempt to inline the function...
|
||||
// Attempt to inline the function.
|
||||
if (!InlineCallIfPossible(CS, InlineInfo, InlinedArrayAllocas))
|
||||
continue;
|
||||
++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.
|
||||
growCachedCostInfo(Caller, Callee);
|
||||
}
|
||||
|
@ -170,7 +170,8 @@ static void HandleInlinedInvoke(InvokeInst *II, BasicBlock *FirstNewBlock,
|
||||
static void UpdateCallGraphAfterInlining(CallSite CS,
|
||||
Function::iterator FirstNewBlock,
|
||||
DenseMap<const Value*, Value*> &ValueMap,
|
||||
CallGraph &CG) {
|
||||
InlineFunctionInfo &IFI) {
|
||||
CallGraph &CG = *IFI.CG;
|
||||
const Function *Caller = CS.getInstruction()->getParent()->getParent();
|
||||
const Function *Callee = CS.getCalledFunction();
|
||||
CallGraphNode *CalleeNode = CG[Callee];
|
||||
@ -210,6 +211,10 @@ static void UpdateCallGraphAfterInlining(CallSite CS,
|
||||
if (Function *F = CallSite(NewCall).getCalledFunction()) {
|
||||
// Indirect call site resolved to direct call.
|
||||
CallerNode->addCalledFunction(CallSite::get(NewCall), CG[F]);
|
||||
|
||||
// Remember that this callsite got devirtualized for the client of
|
||||
// InlineFunction.
|
||||
IFI.DevirtualizedCalls.push_back(NewCall);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -362,7 +367,7 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI) {
|
||||
|
||||
// Update the callgraph if requested.
|
||||
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
|
||||
|
@ -1,7 +1,7 @@
|
||||
; RUN: opt < %s -inline | llvm-dis
|
||||
; RUN: opt < %s -inline -S | FileCheck %s
|
||||
; PR4834
|
||||
|
||||
define i32 @main() {
|
||||
define i32 @test1() {
|
||||
%funcall1_ = call fastcc i32 ()* ()* @f1()
|
||||
%executecommandptr1_ = call i32 %funcall1_()
|
||||
ret i32 %executecommandptr1_
|
||||
@ -14,3 +14,31 @@ define internal fastcc i32 ()* @f1() nounwind readnone {
|
||||
define internal i32 @f2() nounwind readnone {
|
||||
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…
Reference in New Issue
Block a user