[llvm-commits] [llvm] r102146 - in /llvm/trunk: include/llvm/Transforms/Utils/Cloning.h lib/Transforms/IPO/Inliner.cpp lib/Transforms/Utils/InlineFunction.cpp test/Transforms/Inline/indirect_resolve.ll
Chris Lattner
sabre at nondot.org
Thu Apr 22 16:37:36 PDT 2010
Author: lattner
Date: Thu Apr 22 18:37:35 2010
New Revision: 102146
URL: http://llvm.org/viewvc/llvm-project?rev=102146&view=rev
Log:
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.
Modified:
llvm/trunk/include/llvm/Transforms/Utils/Cloning.h
llvm/trunk/lib/Transforms/IPO/Inliner.cpp
llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp
llvm/trunk/test/Transforms/Inline/indirect_resolve.ll
Modified: llvm/trunk/include/llvm/Transforms/Utils/Cloning.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/Cloning.h?rev=102146&r1=102145&r2=102146&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Utils/Cloning.h (original)
+++ llvm/trunk/include/llvm/Transforms/Utils/Cloning.h Thu Apr 22 18:37:35 2010
@@ -174,10 +174,15 @@
/// 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();
}
};
Modified: llvm/trunk/lib/Transforms/IPO/Inliner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/Inliner.cpp?rev=102146&r1=102145&r2=102146&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/Inliner.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/Inliner.cpp Thu Apr 22 18:37:35 2010
@@ -383,11 +383,17 @@
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);
}
Modified: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp?rev=102146&r1=102145&r2=102146&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp Thu Apr 22 18:37:35 2010
@@ -170,7 +170,8 @@
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 @@
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 @@
// 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
Modified: llvm/trunk/test/Transforms/Inline/indirect_resolve.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Inline/indirect_resolve.ll?rev=102146&r1=102145&r2=102146&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/Inline/indirect_resolve.ll (original)
+++ llvm/trunk/test/Transforms/Inline/indirect_resolve.ll Thu Apr 22 18:37:35 2010
@@ -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 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
\ No newline at end of file
More information about the llvm-commits
mailing list