diff --git a/include/llvm/Analysis/IndirectCallSiteVisitor.h b/include/llvm/Analysis/IndirectCallSiteVisitor.h index 71a8cb88632..3c40cc0235c 100644 --- a/include/llvm/Analysis/IndirectCallSiteVisitor.h +++ b/include/llvm/Analysis/IndirectCallSiteVisitor.h @@ -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(I)) { - if (CI->isInlineAsm()) - return; - } - if (isa(CS.getCalledValue())) - return; - IndirectCallInsts.push_back(I); + if (CS.isIndirectCall()) + IndirectCallInsts.push_back(CS.getInstruction()); } }; diff --git a/include/llvm/IR/CallSite.h b/include/llvm/IR/CallSite.h index b02c8947414..18601706f51 100644 --- a/include/llvm/IR/CallSite.h +++ b/include/llvm/IR/CallSite.h @@ -111,6 +111,20 @@ public: return dyn_cast(getCalledValue()); } + /// Returns true if the callsite is an indirect call + bool isIndirectCall() const { + Value *V = getCalledValue(); + if (!V) + return false; + if (isa(V) || isa(V)) + return false; + if (CallInst *CI = dyn_cast(getInstruction())) { + if (CI->isInlineAsm()) + return false; + } + return true; + } + /// setCalledFunction - Set the callee to the specified value. /// void setCalledFunction(Value *V) { diff --git a/lib/Transforms/IPO/SampleProfile.cpp b/lib/Transforms/IPO/SampleProfile.cpp index 87015272b96..d6678279355 100644 --- a/lib/Transforms/IPO/SampleProfile.cpp +++ b/lib/Transforms/IPO/SampleProfile.cpp @@ -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); diff --git a/test/Transforms/SampleProfile/Inputs/indirect-call.prof b/test/Transforms/SampleProfile/Inputs/indirect-call.prof index 9ebfd77147d..ac32967bd54 100644 --- a/test/Transforms/SampleProfile/Inputs/indirect-call.prof +++ b/test/Transforms/SampleProfile/Inputs/indirect-call.prof @@ -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 diff --git a/test/Transforms/SampleProfile/indirect-call.ll b/test/Transforms/SampleProfile/indirect-call.ll index c868d0b83a2..e6e294fd6bf 100644 --- a/test/Transforms/SampleProfile/indirect-call.ll +++ b/test/Transforms/SampleProfile/indirect-call.ll @@ -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}