diff options
Diffstat (limited to 'llvm/lib/Transforms/Instrumentation/MemProfiler.cpp')
| -rw-r--r-- | llvm/lib/Transforms/Instrumentation/MemProfiler.cpp | 45 |
1 files changed, 38 insertions, 7 deletions
diff --git a/llvm/lib/Transforms/Instrumentation/MemProfiler.cpp b/llvm/lib/Transforms/Instrumentation/MemProfiler.cpp index aac57231ba2e..1880928b0d52 100644 --- a/llvm/lib/Transforms/Instrumentation/MemProfiler.cpp +++ b/llvm/lib/Transforms/Instrumentation/MemProfiler.cpp @@ -77,6 +77,8 @@ constexpr char MemProfShadowMemoryDynamicAddress[] = constexpr char MemProfFilenameVar[] = "__memprof_profile_filename"; +constexpr char MemProfHistogramFlagVar[] = "__memprof_histogram"; + // Command-line flags. static cl::opt<bool> ClInsertVersionCheck( @@ -145,10 +147,14 @@ static cl::opt<int> ClDebugMax("memprof-debug-max", cl::desc("Debug max inst"), // override these hints anyway. static cl::opt<bool> ClMemProfMatchHotColdNew( "memprof-match-hot-cold-new", - cl::desc( + cl::desc( "Match allocation profiles onto existing hot/cold operator new calls"), cl::Hidden, cl::init(false)); +static cl::opt<bool> ClHistogram("memprof-histogram", + cl::desc("Collect access count histograms"), + cl::Hidden, cl::init(false)); + static cl::opt<bool> ClPrintMemProfMatchInfo("memprof-print-match-info", cl::desc("Print matching stats for each allocation " @@ -279,6 +285,11 @@ ModuleMemProfilerPass::ModuleMemProfilerPass() = default; PreservedAnalyses ModuleMemProfilerPass::run(Module &M, AnalysisManager<Module> &AM) { + + assert((!ClHistogram || (ClHistogram && ClUseCalls)) && + "Cannot use -memprof-histogram without Callbacks. Set " + "memprof-use-callbacks"); + ModuleMemProfiler Profiler(M); if (Profiler.instrumentModule(M)) return PreservedAnalyses::none(); @@ -508,7 +519,24 @@ void createProfileFileNameVar(Module &M) { } } +// Set MemprofHistogramFlag as a Global veriable in IR. This makes it accessible +// to the runtime, changing shadow count behavior. +void createMemprofHistogramFlagVar(Module &M) { + const StringRef VarName(MemProfHistogramFlagVar); + Type *IntTy1 = Type::getInt1Ty(M.getContext()); + auto MemprofHistogramFlag = new GlobalVariable( + M, IntTy1, true, GlobalValue::WeakAnyLinkage, + Constant::getIntegerValue(IntTy1, APInt(1, ClHistogram)), VarName); + Triple TT(M.getTargetTriple()); + if (TT.supportsCOMDAT()) { + MemprofHistogramFlag->setLinkage(GlobalValue::ExternalLinkage); + MemprofHistogramFlag->setComdat(M.getOrInsertComdat(VarName)); + } + appendToCompilerUsed(M, MemprofHistogramFlag); +} + bool ModuleMemProfiler::instrumentModule(Module &M) { + // Create a module constructor. std::string MemProfVersion = std::to_string(LLVM_MEM_PROFILER_VERSION); std::string VersionCheckName = @@ -524,6 +552,8 @@ bool ModuleMemProfiler::instrumentModule(Module &M) { createProfileFileNameVar(M); + createMemprofHistogramFlagVar(M); + return true; } @@ -532,11 +562,12 @@ void MemProfiler::initializeCallbacks(Module &M) { for (size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) { const std::string TypeStr = AccessIsWrite ? "store" : "load"; + const std::string HistPrefix = ClHistogram ? "hist_" : ""; SmallVector<Type *, 2> Args1{1, IntptrTy}; - MemProfMemoryAccessCallback[AccessIsWrite] = - M.getOrInsertFunction(ClMemoryAccessCallbackPrefix + TypeStr, - FunctionType::get(IRB.getVoidTy(), Args1, false)); + MemProfMemoryAccessCallback[AccessIsWrite] = M.getOrInsertFunction( + ClMemoryAccessCallbackPrefix + HistPrefix + TypeStr, + FunctionType::get(IRB.getVoidTy(), Args1, false)); } MemProfMemmove = M.getOrInsertFunction( ClMemoryAccessCallbackPrefix + "memmove", PtrTy, PtrTy, PtrTy, IntptrTy); @@ -839,7 +870,7 @@ readMemprof(Module &M, Function &F, IndexedInstrProfReader *MemProfReader, }; // Now walk the instructions, looking up the associated profile data using - // dbug locations. + // debug locations. for (auto &BB : F) { for (auto &I : BB) { if (I.isDebugOrPseudoInst()) @@ -937,7 +968,7 @@ readMemprof(Module &M, Function &F, IndexedInstrProfReader *MemProfReader, // Add callsite metadata for the instruction's location list so that // it simpler later on to identify which part of the MIB contexts // are from this particular instruction (including during inlining, - // when the callsite metdata will be updated appropriately). + // when the callsite metadata will be updated appropriately). // FIXME: can this be changed to strip out the matching stack // context ids from the MIB contexts and not add any callsite // metadata here to save space? @@ -1024,4 +1055,4 @@ PreservedAnalyses MemProfUsePass::run(Module &M, ModuleAnalysisManager &AM) { } return PreservedAnalyses::none(); -} +}
\ No newline at end of file |
