]> granicus.if.org Git - llvm/commitdiff
Fix the samplepgo indirect call promotion bug: we should not promote a direct call.
authorDehao Chen <dehao@google.com>
Mon, 6 Feb 2017 23:33:15 +0000 (23:33 +0000)
committerDehao Chen <dehao@google.com>
Mon, 6 Feb 2017 23:33:15 +0000 (23:33 +0000)
Summary: Checking CS.getCalledFunction() == nullptr does not necessary indicate indirect call. We also need to check if CS.getCalledValue() is not a constant.

Reviewers: davidxl

Reviewed By: davidxl

Subscribers: llvm-commits

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

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

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

index 71a8cb886321676b9e2919ca59cdaa8f05b1a4d0..3c40cc0235cc0b28a62952c5ccc342615eb3ff21 100644 (file)
@@ -21,16 +21,8 @@ struct PGOIndirectCallSiteVisitor
   PGOIndirectCallSiteVisitor() {}
 
   void visitCallSite(CallSite CS) {
-    if (CS.getCalledFunction() || !CS.getCalledValue())
-      return;
-    Instruction *I = CS.getInstruction();
-    if (CallInst *CI = dyn_cast<CallInst>(I)) {
-      if (CI->isInlineAsm())
-        return;
-    }
-    if (isa<Constant>(CS.getCalledValue()))
-      return;
-    IndirectCallInsts.push_back(I);
+    if (CS.isIndirectCall())
+      IndirectCallInsts.push_back(CS.getInstruction());
   }
 };
 
index b02c89474146fe049e7a19227315edf9dcada94e..18601706f51185c2d23f33ad0a3053301b65f317 100644 (file)
@@ -111,6 +111,20 @@ public:
     return dyn_cast<FunTy>(getCalledValue());
   }
 
+  /// Returns true if the callsite is an indirect call
+  bool isIndirectCall() 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 (CI->isInlineAsm())
+        return false;
+    }
+    return true;
+  }
+
   /// setCalledFunction - Set the callee to the specified value.
   ///
   void setCalledFunction(Value *V) {
index 87015272b96a8a34d053657aae986879f7445905..d667827935513e6d5d901dbf1262be7932a2d790 100644 (file)
@@ -634,7 +634,8 @@ bool SampleProfileLoader::inlineHotFunctions(Function &F) {
       InlineFunctionInfo IFI(nullptr, ACT ? &GetAssumptionCache : nullptr);
       Function *CalledFunction = CallSite(I).getCalledFunction();
       Instruction *DI = I;
-      if (!CalledFunction && !PromotedInsns.count(I)) {
+      if (!CalledFunction && !PromotedInsns.count(I) &&
+          CallSite(I).isIndirectCall()) {
         auto CalleeFunctionName = findCalleeFunctionSamples(*I)->getName();
         const char *Reason = "Callee function not available";
         CalledFunction = F.getParent()->getFunction(CalleeFunctionName);
index 9ebfd77147d008f4b00790c2e802c8fca4c93855..ac32967bd546a7dd9b8bb20a0c641e5bcebf59bd 100644 (file)
@@ -6,3 +6,6 @@ test_inline:3000:0
 test_noinline:3000:0
  5: foo_noinline:3000
   1: 3000
+test_direct:3000:0
+ 5: foo_direct:3000
+  1: 3000
index c868d0b83a27d6f58f2fd287545edbd16f3a3a5d..e6e294fd6bfdf7c6f7767b35d5dd0881ae34bd2d 100644 (file)
@@ -47,6 +47,21 @@ define i32 @foo_noinline(i32 %x) !dbg !3 {
   ret i32 %x
 }
 
+define void @foo_direct() !dbg !3 {
+  ret void
+}
+
+; CHECK-LABEL: @test_direct
+; We should not promote a direct call.
+define void @test_direct() !dbg !3 {
+; CHECK-NOT: icmp
+; CHECK: call
+  call void @foo_alias(), !dbg !5
+  ret void
+}
+
+@foo_alias = alias void (), void ()* @foo_direct
+
 !llvm.dbg.cu = !{!0}
 !llvm.module.flags = !{!2}