diff options
author | Rong Xu <xur@google.com> | 2016-01-21 18:11:44 +0000 |
---|---|---|
committer | Rong Xu <xur@google.com> | 2016-01-21 18:11:44 +0000 |
commit | ed9fec736502adf3a8f35a488243c212d640223d (patch) | |
tree | fccb332cbe1253ca305180a11309d1897148d3c1 /llvm/lib/Transforms | |
parent | 4e971da2723972b589f617301b7c838f00c8e2c7 (diff) | |
download | bcm5719-llvm-ed9fec736502adf3a8f35a488243c212d640223d.tar.gz bcm5719-llvm-ed9fec736502adf3a8f35a488243c212d640223d.zip |
[PGO] IR level instrumentation of indirect call value profiling
This patch adds the instrumentation for indirect call value profiling. It finds all the indirect call-sites and generates instrprof_value_profile intrinsic calls. A new opt level option -disable-vp is introduced to disable this instrumentation.
Reviewers: davidxl, betulb, vsk
Differential Revision: http://reviews.llvm.org/D16016
llvm-svn: 258417
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp | 56 |
1 files changed, 52 insertions, 4 deletions
diff --git a/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp b/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp index 4b59b93b325..64aa94fc60c 100644 --- a/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp +++ b/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp @@ -45,7 +45,6 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Transforms/Instrumentation.h" #include "CFGMST.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/STLExtras.h" @@ -53,9 +52,11 @@ #include "llvm/Analysis/BlockFrequencyInfo.h" #include "llvm/Analysis/BranchProbabilityInfo.h" #include "llvm/Analysis/CFG.h" +#include "llvm/IR/CallSite.h" #include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/InstIterator.h" +#include "llvm/IR/InstVisitor.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/MDBuilder.h" @@ -65,6 +66,7 @@ #include "llvm/Support/BranchProbability.h" #include "llvm/Support/Debug.h" #include "llvm/Support/JamCRC.h" +#include "llvm/Transforms/Instrumentation.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include <string> #include <utility> @@ -81,6 +83,7 @@ STATISTIC(NumOfPGOSplit, "Number of critical edge splits."); STATISTIC(NumOfPGOFunc, "Number of functions having valid profile counts."); STATISTIC(NumOfPGOMismatch, "Number of functions having mismatch profile."); STATISTIC(NumOfPGOMissing, "Number of functions without profile."); +STATISTIC(NumOfPGOICall, "Number of indirect call value instrumentation."); // Command line option to specify the file to read profile from. This is // mainly used for testing. @@ -90,6 +93,13 @@ static cl::opt<std::string> cl::desc("Specify the path of profile data file. This is" "mainly for test purpose.")); +// Command line options to disable value profiling. The default is false: +// i.e. vaule profiling is enabled by default. This is for debug purpose. +static cl::opt<bool> +DisableValueProfiling("disable-vp", cl::init(false), + cl::Hidden, + cl::desc("Disable Value Profiling")); + namespace { class PGOInstrumentationGen : public ModulePass { public: @@ -225,7 +235,7 @@ public: // Dump edges and BB information. void dumpInfo(std::string Str = "") const { MST.dumpEdges(dbgs(), Twine("Dump Function ") + FuncName + " Hash: " + - Twine(FunctionHash) + "\t" + Str); + Twine(FunctionHash) + "\t" + Str); } FuncPGOInstrumentation(Function &Func, bool CreateGlobalVar = false, @@ -305,7 +315,21 @@ BasicBlock *FuncPGOInstrumentation<Edge, BBInfo>::getInstrBB(Edge *E) { return InstrBB; } -// Visit all edge and instrument the edges not in MST. +// Visitor class that finds all indirect call sites. +struct PGOIndirectCallSiteVisitor + : public InstVisitor<PGOIndirectCallSiteVisitor> { + std::vector<CallInst *> IndirectCallInsts; + PGOIndirectCallSiteVisitor() {} + + void visitCallInst(CallInst &I) { + CallSite CS(&I); + if (CS.getCalledFunction() || !CS.getCalledValue()) + return; + IndirectCallInsts.push_back(&I); + } +}; + +// Visit all edge and instrument the edges not in MST, and do value profiling. // Critical edges will be split. static void instrumentOneFunc(Function &F, Module *M, BranchProbabilityInfo *BPI, @@ -318,6 +342,7 @@ static void instrumentOneFunc(Function &F, Module *M, } uint32_t I = 0; + Type *I8PtrTy = Type::getInt8PtrTy(M->getContext()); for (auto &E : FuncInfo.MST.AllEdges) { BasicBlock *InstrBB = FuncInfo.getInstrBB(E.get()); if (!InstrBB) @@ -326,13 +351,36 @@ static void instrumentOneFunc(Function &F, Module *M, IRBuilder<> Builder(InstrBB, InstrBB->getFirstInsertionPt()); assert(Builder.GetInsertPoint() != InstrBB->end() && "Cannot get the Instrumentation point"); - Type *I8PtrTy = Type::getInt8PtrTy(M->getContext()); Builder.CreateCall( Intrinsic::getDeclaration(M, Intrinsic::instrprof_increment), {llvm::ConstantExpr::getBitCast(FuncInfo.FuncNameVar, I8PtrTy), Builder.getInt64(FuncInfo.FunctionHash), Builder.getInt32(NumCounters), Builder.getInt32(I++)}); } + + if (DisableValueProfiling) + return; + + unsigned NumIndirectCallSites = 0; + PGOIndirectCallSiteVisitor ICV; + ICV.visit(F); + for (auto &I : ICV.IndirectCallInsts) { + CallSite CS(I); + Value *Callee = CS.getCalledValue(); + DEBUG(dbgs() << "Instrument one indirect call: CallSite Index = " + << NumIndirectCallSites << "\n"); + IRBuilder<> Builder(I); + assert(Builder.GetInsertPoint() != I->getParent()->end() && + "Cannot get the Instrumentation point"); + Builder.CreateCall( + Intrinsic::getDeclaration(M, Intrinsic::instrprof_value_profile), + {llvm::ConstantExpr::getBitCast(FuncInfo.FuncNameVar, I8PtrTy), + Builder.getInt64(FuncInfo.FunctionHash), + Builder.CreatePtrToInt(Callee, Builder.getInt64Ty()), + Builder.getInt32(llvm::InstrProfValueKind::IPVK_IndirectCallTarget), + Builder.getInt32(NumIndirectCallSites++)}); + } + NumOfPGOICall += NumIndirectCallSites; } // This class represents a CFG edge in profile use compilation. |