OSDN Git Service

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 42c25e2..01aa03e 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 7dce904..fb7397c 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 f35b4b1..dda7d05 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 28d61ed..02fcb11 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)