Index: include/llvm/Analysis/IndirectCallSiteVisitor.h =================================================================== --- include/llvm/Analysis/IndirectCallSiteVisitor.h +++ /dev/null @@ -1,40 +0,0 @@ -//===-- IndirectCallSiteVisitor.h - indirect call-sites visitor -----------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements defines a visitor class and a helper function that find -// all indirect call-sites in a function. - -#ifndef LLVM_ANALYSIS_INDIRECTCALLSITEVISITOR_H -#define LLVM_ANALYSIS_INDIRECTCALLSITEVISITOR_H - -#include "llvm/IR/InstVisitor.h" -#include - -namespace llvm { -// Visitor class that finds all indirect call sites. -struct PGOIndirectCallSiteVisitor - : public InstVisitor { - std::vector IndirectCallInsts; - PGOIndirectCallSiteVisitor() {} - - void visitCallSite(CallSite CS) { - if (CS.isIndirectCall()) - IndirectCallInsts.push_back(CS.getInstruction()); - } -}; - -// Helper function that finds all indirect call sites. -inline std::vector findIndirectCallSites(Function &F) { - PGOIndirectCallSiteVisitor ICV; - ICV.visit(F); - return ICV.IndirectCallInsts; -} -} - -#endif Index: include/llvm/Analysis/NonConstantCallSiteVisitor.h =================================================================== --- /dev/null +++ include/llvm/Analysis/NonConstantCallSiteVisitor.h @@ -0,0 +1,42 @@ +//===-- NonConstantCallSiteVisitor.h - non-constant call site visitor -----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines and implements a visitor class and a helper function that +// find all non-constant call sites in a function. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_NONCONSTANTCALLSITEVISITOR_H +#define LLVM_ANALYSIS_NONCONSTANTCALLSITEVISITOR_H + +#include "llvm/IR/InstVisitor.h" +#include + +namespace llvm { +// Visitor class that finds all non-constant call sites. +struct PGONonConstantCallSiteVisitor + : public InstVisitor { + std::vector NonConstantCallInsts; + PGONonConstantCallSiteVisitor() {} + + void visitCallSite(CallSite CS) { + if (!CS.isConstant()) + NonConstantCallInsts.push_back(CS.getInstruction()); + } +}; + +// Helper function that finds all non-constant call sites. +inline std::vector findNonConstantCallSites(Function &F) { + PGONonConstantCallSiteVisitor ICV; + ICV.visit(F); + return ICV.NonConstantCallInsts; +} +} + +#endif Index: include/llvm/IR/CallSite.h =================================================================== --- include/llvm/IR/CallSite.h +++ include/llvm/IR/CallSite.h @@ -96,7 +96,9 @@ /// Get the basic block containing the call site. BBTy* getParent() const { return getInstruction()->getParent(); } - /// Return the pointer to function that is being called. + /// Return the pointer to the value that is being called. + /// + /// getCalledValue never returns null. ValTy *getCalledValue() const { assert(getInstruction() && "Not a call or invoke instruction!"); return *getCallee(); @@ -104,22 +106,32 @@ /// Return the function being called if this is a direct call, otherwise /// return null (if it's an indirect call). + /// + /// A direct call is a call to a FunTy. An indirect call is a call to + /// anything which is not a FunTy (e.g. a bitcast of a FunTy). FunTy *getCalledFunction() const { return dyn_cast(getCalledValue()); } - /// Return true if the callsite is an indirect call. - bool isIndirectCall() const { + /// Return the function being called if this is either a direct call or an + /// indirect call to a cast of a FunTy, otherwise return null. + /// + /// See getCalledFunction for the definitions of direct and indirect calls. + FunTy *getCalledFunctionStripCasts() const { + return dyn_cast(getCalledValue()->stripPointerCasts()); + } + + /// Return true if the call site is "constant". A call site is constant if it + /// is to a function, constant, or inline assembly. + bool isConstant() const { const Value *V = getCalledValue(); - if (!V) - return false; if (isa(V) || isa(V)) - return false; + return true; if (const CallInst *CI = dyn_cast(getInstruction())) { if (CI->isInlineAsm()) - return false; + return true; } - return true; + return false; } /// Set the callee to the specified value. Index: lib/Analysis/IndirectCallPromotionAnalysis.cpp =================================================================== --- lib/Analysis/IndirectCallPromotionAnalysis.cpp +++ lib/Analysis/IndirectCallPromotionAnalysis.cpp @@ -15,7 +15,6 @@ #include "llvm/Analysis/IndirectCallPromotionAnalysis.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/Analysis/IndirectCallSiteVisitor.h" #include "llvm/IR/CallSite.h" #include "llvm/IR/InstIterator.h" #include "llvm/IR/InstVisitor.h" Index: lib/CodeGen/WinEHPrepare.cpp =================================================================== --- lib/CodeGen/WinEHPrepare.cpp +++ lib/CodeGen/WinEHPrepare.cpp @@ -953,8 +953,7 @@ continue; // Skip call sites which are nounwind intrinsics or inline asm. - auto *CalledFn = - dyn_cast(CS.getCalledValue()->stripPointerCasts()); + Function *CalledFn = CS.getCalledFunctionStripCasts(); if (CalledFn && ((CalledFn->isIntrinsic() && CS.doesNotThrow()) || CS.isInlineAsm())) continue; Index: lib/IR/Verifier.cpp =================================================================== --- lib/IR/Verifier.cpp +++ lib/IR/Verifier.cpp @@ -2744,8 +2744,7 @@ if (Attrs.hasAttribute(AttributeList::FunctionIndex, Attribute::Speculatable)) { // Don't allow speculatable on call sites, unless the underlying function // declaration is also speculatable. - Function *Callee - = dyn_cast(CS.getCalledValue()->stripPointerCasts()); + Function *Callee = CS.getCalledFunctionStripCasts(); Assert(Callee && Callee->isSpeculatable(), "speculatable attribute may not apply to call sites", I); } Index: lib/Target/AMDGPU/AMDGPUFixFunctionBitcasts.cpp =================================================================== --- lib/Target/AMDGPU/AMDGPUFixFunctionBitcasts.cpp +++ lib/Target/AMDGPU/AMDGPUFixFunctionBitcasts.cpp @@ -35,7 +35,7 @@ void visitCallSite(CallSite CS) { if (CS.getCalledFunction()) return; - auto Callee = dyn_cast(CS.getCalledValue()->stripPointerCasts()); + auto Callee = CS.getCalledFunctionStripCasts(); if (Callee && isLegalToPromote(CS, Callee)) { promoteCall(CS, Callee); Modified = true; Index: lib/Transforms/IPO/SampleProfile.cpp =================================================================== --- lib/Transforms/IPO/SampleProfile.cpp +++ lib/Transforms/IPO/SampleProfile.cpp @@ -549,7 +549,7 @@ // it means that the inlined callsite has no sample, thus the call // instruction should have 0 count. if ((isa(Inst) || isa(Inst)) && - !ImmutableCallSite(&Inst).isIndirectCall() && + ImmutableCallSite(&Inst).isConstant() && findCalleeFunctionSamples(Inst)) return 0; @@ -795,7 +795,7 @@ // Do not inline recursive calls. if (CalledFunction == &F) continue; - if (CallSite(I).isIndirectCall()) { + if (!CallSite(I).isConstant()) { if (PromotedInsns.count(I)) continue; uint64_t Sum; Index: lib/Transforms/InstCombine/InstCombineCalls.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCalls.cpp +++ lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -4239,7 +4239,7 @@ /// If the callee is a constexpr cast of a function, attempt to move the cast to /// the arguments of the call/invoke. bool InstCombiner::transformConstExprCastCall(CallSite CS) { - auto *Callee = dyn_cast(CS.getCalledValue()->stripPointerCasts()); + Function *Callee = CS.getCalledFunctionStripCasts(); if (!Callee) return false; Index: lib/Transforms/Instrumentation/CGProfile.cpp =================================================================== --- lib/Transforms/Instrumentation/CGProfile.cpp +++ lib/Transforms/Instrumentation/CGProfile.cpp @@ -53,7 +53,7 @@ CallSite CS(&I); if (!CS) continue; - if (CS.isIndirectCall()) { + if (!CS.isConstant()) { InstrProfValueData ValueData[8]; uint32_t ActualNumValueData; uint64_t TotalC; Index: lib/Transforms/Instrumentation/IndirectCallPromotion.cpp =================================================================== --- lib/Transforms/Instrumentation/IndirectCallPromotion.cpp +++ lib/Transforms/Instrumentation/IndirectCallPromotion.cpp @@ -19,7 +19,7 @@ #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringRef.h" #include "llvm/Analysis/IndirectCallPromotionAnalysis.h" -#include "llvm/Analysis/IndirectCallSiteVisitor.h" +#include "llvm/Analysis/NonConstantCallSiteVisitor.h" #include "llvm/Analysis/OptimizationRemarkEmitter.h" #include "llvm/Analysis/ProfileSummaryInfo.h" #include "llvm/IR/Attributes.h" @@ -352,7 +352,7 @@ bool ICallPromotionFunc::processFunction(ProfileSummaryInfo *PSI) { bool Changed = false; ICallPromotionAnalysis ICallAnalysis; - for (auto &I : findIndirectCallSites(F)) { + for (auto &I : findNonConstantCallSites(F)) { uint32_t NumVals, NumCandidates; uint64_t TotalCount; auto ICallProfDataRef = ICallAnalysis.getPromotionCandidatesForInstruction( Index: lib/Transforms/Instrumentation/PGOInstrumentation.cpp =================================================================== --- lib/Transforms/Instrumentation/PGOInstrumentation.cpp +++ lib/Transforms/Instrumentation/PGOInstrumentation.cpp @@ -63,7 +63,7 @@ #include "llvm/Analysis/BlockFrequencyInfo.h" #include "llvm/Analysis/BranchProbabilityInfo.h" #include "llvm/Analysis/CFG.h" -#include "llvm/Analysis/IndirectCallSiteVisitor.h" +#include "llvm/Analysis/NonConstantCallSiteVisitor.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/OptimizationRemarkEmitter.h" #include "llvm/IR/Attributes.h" @@ -544,7 +544,7 @@ MIVisitor.countMemIntrinsics(Func); NumOfPGOSelectInsts += SIVisitor.getNumOfSelectInsts(); NumOfPGOMemIntrinsics += MIVisitor.getNumOfMemIntrinsics(); - ValueSites[IPVK_IndirectCallTarget] = findIndirectCallSites(Func); + ValueSites[IPVK_IndirectCallTarget] = findNonConstantCallSites(Func); ValueSites[IPVK_MemOPSize] = MIVisitor.findMemIntrinsics(Func); FuncName = getPGOFuncName(F); Index: lib/Transforms/Utils/InlineFunction.cpp =================================================================== --- lib/Transforms/Utils/InlineFunction.cpp +++ lib/Transforms/Utils/InlineFunction.cpp @@ -2017,8 +2017,7 @@ continue; // Skip call sites which are nounwind intrinsics. - auto *CalledFn = - dyn_cast(CS.getCalledValue()->stripPointerCasts()); + Function *CalledFn = CS.getCalledFunctionStripCasts(); if (CalledFn && CalledFn->isIntrinsic() && CS.doesNotThrow()) continue;