llvm.org GIT mirror llvm / fe9af3b
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 Chris Lattner 10 years ago
4 changed file(s) with 50 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
173173 /// StaticAllocas - InlineFunction fills this in with all static allocas that
174174 /// get copied into the caller.
175175 SmallVector StaticAllocas;
176
176
177 /// DevirtualizedCalls - InlineFunction fills this in with callsites that were
178 /// inlined from the callee that went from being indirect calls to direct
179 /// calls due to inlining. This is only filled in if CG is non-null.
180 SmallVector DevirtualizedCalls;
177181
178182 void reset() {
179183 StaticAllocas.clear();
184 DevirtualizedCalls.clear();
180185 }
181186 };
182187
382382 if (!shouldInline(CS))
383383 continue;
384384
385 // Attempt to inline the function...
385 // Attempt to inline the function.
386386 if (!InlineCallIfPossible(CS, InlineInfo, InlinedArrayAllocas))
387387 continue;
388388 ++NumInlined;
389389
390 // If inlining this function devirtualized any call sites, throw them
391 // onto our worklist to process. They are useful inline candidates.
392 for (unsigned i = 0, e = InlineInfo.DevirtualizedCalls.size();
393 i != e; ++i)
394 CallSites.push_back(CallSite(InlineInfo.DevirtualizedCalls[i]));
395
390396 // Update the cached cost info with the inlined call.
391397 growCachedCostInfo(Caller, Callee);
392398 }
169169 static void UpdateCallGraphAfterInlining(CallSite CS,
170170 Function::iterator FirstNewBlock,
171171 DenseMap &ValueMap,
172 CallGraph &CG) {
172 InlineFunctionInfo &IFI) {
173 CallGraph &CG = *IFI.CG;
173174 const Function *Caller = CS.getInstruction()->getParent()->getParent();
174175 const Function *Callee = CS.getCalledFunction();
175176 CallGraphNode *CalleeNode = CG[Callee];
209210 if (Function *F = CallSite(NewCall).getCalledFunction()) {
210211 // Indirect call site resolved to direct call.
211212 CallerNode->addCalledFunction(CallSite::get(NewCall), CG[F]);
213
214 // Remember that this callsite got devirtualized for the client of
215 // InlineFunction.
216 IFI.DevirtualizedCalls.push_back(NewCall);
212217 continue;
213218 }
214219
361366
362367 // Update the callgraph if requested.
363368 if (IFI.CG)
364 UpdateCallGraphAfterInlining(CS, FirstNewBlock, ValueMap, *IFI.CG);
369 UpdateCallGraphAfterInlining(CS, FirstNewBlock, ValueMap, IFI);
365370 }
366371
367372 // If there are any alloca instructions in the block that used to be the entry
None ; RUN: opt < %s -inline | llvm-dis
0 ; RUN: opt < %s -inline -S | FileCheck %s
11 ; PR4834
22
3 define i32 @main() {
3 define i32 @test1() {
44 %funcall1_ = call fastcc i32 ()* ()* @f1()
55 %executecommandptr1_ = call i32 %funcall1_()
66 ret i32 %executecommandptr1_
1313 define internal i32 @f2() nounwind readnone {
1414 ret i32 1
1515 }
16
17 ; CHECK: @test1()
18 ; CHECK-NEXT: ret i32 1
19
20
21
22
23
24 declare i8* @f1a(i8*) ssp align 2
25
26 define internal i32 @f2a(i8* %t) inlinehint ssp {
27 entry:
28 ret i32 41
29 }
30
31 define internal i32 @f3a(i32 (i8*)* %__f) ssp {
32 entry:
33 %A = call i32 %__f(i8* undef)
34 ret i32 %A
35 }
36
37 define i32 @test2(i8* %this) ssp align 2 {
38 %X = call i32 @f3a(i32 (i8*)* @f2a) ssp
39 ret i32 %X
40 }
41
42 ; CHECK: @test2
43 ; CHECK-NEXT: ret i32 41