Index: llvm/include/llvm/Analysis/IndirectCallSiteVisitor.h =================================================================== --- llvm/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: llvm/include/llvm/Analysis/IndirectCallVisitor.h =================================================================== --- /dev/null +++ llvm/include/llvm/Analysis/IndirectCallVisitor.h @@ -0,0 +1,39 @@ +//===-- IndirectCallVisitor.h - indirect call 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_INDIRECTCALLVISITOR_H +#define LLVM_ANALYSIS_INDIRECTCALLVISITOR_H + +#include "llvm/IR/InstVisitor.h" +#include + +namespace llvm { +// Visitor class that finds all indirect call. +struct PGOIndirectCallVisitor : public InstVisitor { + std::vector IndirectCalls; + PGOIndirectCallVisitor() {} + + void visitCallBase(CallBase &Call) { + if (Call.isIndirectCall()) + IndirectCalls.push_back(&Call); + } +}; + +// Helper function that finds all indirect call sites. +inline std::vector findIndirectCalls(Function &F) { + PGOIndirectCallVisitor ICV; + ICV.visit(F); + return ICV.IndirectCalls; +} +} // namespace llvm + +#endif Index: llvm/include/llvm/IR/InstrTypes.h =================================================================== --- llvm/include/llvm/IR/InstrTypes.h +++ llvm/include/llvm/IR/InstrTypes.h @@ -1182,6 +1182,9 @@ return dyn_cast_or_null(getCalledOperand()); } + /// Return true if the callsite is an indirect call. + bool isIndirectCall() const; + /// Helper to get the caller (the parent function). Function *getCaller(); const Function *getCaller() const { Index: llvm/lib/Analysis/IndirectCallPromotionAnalysis.cpp =================================================================== --- llvm/lib/Analysis/IndirectCallPromotionAnalysis.cpp +++ llvm/lib/Analysis/IndirectCallPromotionAnalysis.cpp @@ -15,7 +15,7 @@ #include "llvm/Analysis/IndirectCallPromotionAnalysis.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/Analysis/IndirectCallSiteVisitor.h" +#include "llvm/Analysis/IndirectCallVisitor.h" #include "llvm/IR/CallSite.h" #include "llvm/IR/InstIterator.h" #include "llvm/IR/InstVisitor.h" Index: llvm/lib/IR/Instructions.cpp =================================================================== --- llvm/lib/IR/Instructions.cpp +++ llvm/lib/IR/Instructions.cpp @@ -257,6 +257,17 @@ Function *CallBase::getCaller() { return getParent()->getParent(); } +bool CallBase::isIndirectCall() const { + const Value *V = getCalledValue(); + if (isa(V) || isa(V)) + return false; + if (const CallInst *CI = dyn_cast(this)) { + if (CI->isInlineAsm()) + return false; + } + return true; +} + Intrinsic::ID CallBase::getIntrinsicID() const { if (auto *F = getCalledFunction()) return F->getIntrinsicID(); Index: llvm/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp =================================================================== --- llvm/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp +++ llvm/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/IndirectCallVisitor.h" #include "llvm/Analysis/OptimizationRemarkEmitter.h" #include "llvm/Analysis/ProfileSummaryInfo.h" #include "llvm/IR/Attributes.h" @@ -41,8 +41,8 @@ #include "llvm/ProfileData/InstrProf.h" #include "llvm/Support/Casting.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Support/Error.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/Error.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Instrumentation.h" #include "llvm/Transforms/Instrumentation/PGOInstrumentation.h" @@ -352,7 +352,7 @@ bool ICallPromotionFunc::processFunction(ProfileSummaryInfo *PSI) { bool Changed = false; ICallPromotionAnalysis ICallAnalysis; - for (auto &I : findIndirectCallSites(F)) { + for (auto &I : findIndirectCalls(F)) { uint32_t NumVals, NumCandidates; uint64_t TotalCount; auto ICallProfDataRef = ICallAnalysis.getPromotionCandidatesForInstruction( Index: llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp =================================================================== --- llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp +++ llvm/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/IndirectCallVisitor.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] = findIndirectCalls(Func); ValueSites[IPVK_MemOPSize] = MIVisitor.findMemIntrinsics(Func); FuncName = getPGOFuncName(F); @@ -754,12 +754,12 @@ if (DisableValueProfiling) return; - unsigned NumIndirectCallSites = 0; + unsigned NumIndirectCalls = 0; for (auto &I : FuncInfo.ValueSites[IPVK_IndirectCallTarget]) { CallSite CS(I); Value *Callee = CS.getCalledValue(); LLVM_DEBUG(dbgs() << "Instrument one indirect call: CallSite Index = " - << NumIndirectCallSites << "\n"); + << NumIndirectCalls << "\n"); IRBuilder<> Builder(I); assert(Builder.GetInsertPoint() != I->getParent()->end() && "Cannot get the Instrumentation point"); @@ -769,9 +769,9 @@ Builder.getInt64(FuncInfo.FunctionHash), Builder.CreatePtrToInt(Callee, Builder.getInt64Ty()), Builder.getInt32(IPVK_IndirectCallTarget), - Builder.getInt32(NumIndirectCallSites++)}); + Builder.getInt32(NumIndirectCalls++)}); } - NumOfPGOICall += NumIndirectCallSites; + NumOfPGOICall += NumIndirectCalls; // Now instrument memop intrinsic calls. FuncInfo.MIVisitor.instrumentMemIntrinsics(