]> granicus.if.org Git - llvm/commitdiff
Annotate VP prof on indirect call if it is ICPed in the profiled binary.
authorDehao Chen <dehao@google.com>
Thu, 5 Oct 2017 20:15:29 +0000 (20:15 +0000)
committerDehao Chen <dehao@google.com>
Thu, 5 Oct 2017 20:15:29 +0000 (20:15 +0000)
Summary: In SamplePGO, when an indirect call is promoted in the profiled binary, before profile annotation, it will be promoted and inlined. For the original indirect call, the current implementation will not mark VP profile on it. This is an issue when profile becomes stale. This patch annotates VP prof on indirect calls during annotation.

Reviewers: tejohnson

Reviewed By: tejohnson

Subscribers: sanjoy, llvm-commits

Differential Revision: https://reviews.llvm.org/D38477

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@315016 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/IR/CallSite.h
lib/Transforms/IPO/SampleProfile.cpp
test/Transforms/SampleProfile/Inputs/indirect-call.prof
test/Transforms/SampleProfile/indirect-call.ll

index 42c25e25c1cf211284181cec3c16d0db3932f3f2..01aa03e59ff5cfcc2cbe4ce1959303140251e249 100644 (file)
@@ -110,12 +110,12 @@ public:
 
   /// Return true if the callsite is an indirect call.
   bool isIndirectCall() const {
-    Value *V = getCalledValue();
+    const Value *V = getCalledValue();
     if (!V)
       return false;
     if (isa<FunTy>(V) || isa<Constant>(V))
       return false;
-    if (CallInst *CI = dyn_cast<CallInst>(getInstruction())) {
+    if (const CallInst *CI = dyn_cast<CallInst>(getInstruction())) {
       if (CI->isInlineAsm())
         return false;
     }
index 7dce904ff157a032e1fbadd2a2895f716a0f527a..fb7397c3d8e570ae5ec51b6f9bf1f840250f55d9 100644 (file)
@@ -511,10 +511,12 @@ ErrorOr<uint64_t> SampleProfileLoader::getInstWeight(const Instruction &Inst) {
   if (isa<BranchInst>(Inst) || isa<IntrinsicInst>(Inst))
     return std::error_code();
 
-  // If a call/invoke instruction is inlined in profile, but not inlined here,
+  // If a direct call/invoke instruction is inlined in profile
+  // (findCalleeFunctionSamples returns non-empty result), but not inlined here,
   // it means that the inlined callsite has no sample, thus the call
   // instruction should have 0 count.
   if ((isa<CallInst>(Inst) || isa<InvokeInst>(Inst)) &&
+      !ImmutableCallSite(&Inst).isIndirectCall() &&
       findCalleeFunctionSamples(Inst))
     return 0;
 
index f35b4b13c71c71bac435bac620192aa0b0d36e8c..dda7d0585e3bf56ce4f73321583297ae6c1668c6 100644 (file)
@@ -1,6 +1,7 @@
 test:63067:0
  1: 3345 _Z3barv:1398 _Z3foov:2059
 test_inline:3000:0
+ 1: 1000 foo_inline3:1000
  1: foo_inline1:3000
   11: 3000
  1: foo_inline2:4000
index 28d61ed2426157b0eade7e00897f19c85c9253ab..02fcb11060a4a4607cf64ef883eb18a36a18f638 100644 (file)
@@ -24,7 +24,7 @@ define void @test_inline(i64* (i32*)*, i32* %x) !dbg !6 {
 ; CHECK: if.true.direct_targ1:
 ; CHECK-NOT: call
 ; CHECK: if.false.orig_indirect2:
-; CHECK: call
+; CHECK: call {{.*}} !prof ![[VP:[0-9]+]]
   call i64* %3(i32* %x), !dbg !7
   ret void
 }
@@ -152,6 +152,7 @@ define void @test_direct() !dbg !22 {
 !4 = !DILocation(line: 4, scope: !3)
 !5 = !DILocation(line: 6, scope: !3)
 ; CHECK: ![[PROF]] = !{!"VP", i32 0, i64 3457, i64 9191153033785521275, i64 2059, i64 -1069303473483922844, i64 1398}
+; CHECK: ![[VP]] = !{!"VP", i32 0, i64 1000, i64 -6391416044382067764, i64 1000}
 !6 = distinct !DISubprogram(name: "test_inline", scope: !1, file: !1, line: 6, unit: !0)
 !7 = !DILocation(line: 7, scope: !6)
 !8 = distinct !DISubprogram(name: "test_inline_strip", scope: !1, file: !1, line: 8, unit: !0)