53#define DEBUG_TYPE "memprof"
78 "__memprof_version_mismatch_check_v";
81 "__memprof_shadow_memory_dynamic_address";
90 "memprof-guard-against-version-mismatch",
96 cl::desc(
"instrument read instructions"),
105 "memprof-instrument-atomics",
110 "memprof-use-callbacks",
111 cl::desc(
"Use callbacks instead of inline instrumentation sequences."),
116 cl::desc(
"Prefix for memory access callbacks"),
124 cl::desc(
"scale of memprof shadow mapping"),
129 cl::desc(
"granularity of memprof shadow mapping"),
133 cl::desc(
"Instrument scalar stack variables"),
154 "memprof-match-hot-cold-new",
156 "Match allocation profiles onto existing hot/cold operator new calls"),
160 cl::desc(
"Collect access count histograms"),
165 cl::desc(
"Print matching stats for each allocation "
166 "context in this module's profiles"),
171 cl::desc(
"The default memprof options"),
176 cl::desc(
"Salvage stale MemProf profile"),
181 cl::desc(
"Min percent of cold bytes to hint alloc cold during cloning"));
187 cl::desc(
"Min percent of cold bytes matched to hint allocation cold"));
190STATISTIC(NumInstrumentedReads,
"Number of instrumented reads");
191STATISTIC(NumInstrumentedWrites,
"Number of instrumented writes");
192STATISTIC(NumSkippedStackReads,
"Number of non-instrumented stack reads");
193STATISTIC(NumSkippedStackWrites,
"Number of non-instrumented stack writes");
196STATISTIC(NumOfMemProfMissing,
"Number of functions without memory profile.");
198 "Number of functions having mismatched memory profile hash.");
199STATISTIC(NumOfMemProfFunc,
"Number of functions having valid memory profile.");
201 "Number of alloc contexts in memory profile.");
203 "Number of callsites in memory profile.");
205 "Number of matched memory profile alloc contexts.");
207 "Number of matched memory profile allocs.");
209 "Number of matched memory profile callsites.");
215struct ShadowMapping {
219 Mask = ~(Granularity - 1);
232struct InterestingMemoryAccess {
236 Value *MaybeMask =
nullptr;
243 C = &(
M.getContext());
244 LongSize =
M.getDataLayout().getPointerSizeInBits();
246 PtrTy = PointerType::getUnqual(*C);
252 std::optional<InterestingMemoryAccess>
256 InterestingMemoryAccess &
Access);
265 bool maybeInsertMemProfInitAtFunctionEntry(
Function &
F);
266 bool insertDynamicShadowAtFunctionEntry(
Function &
F);
269 void initializeCallbacks(
Module &M);
275 ShadowMapping Mapping;
281 Value *DynamicShadowOffset =
nullptr;
284class ModuleMemProfiler {
286 ModuleMemProfiler(
Module &M) { TargetTriple =
Triple(
M.getTargetTriple()); }
288 bool instrumentModule(
Module &);
292 ShadowMapping Mapping;
293 Function *MemProfCtorFunction =
nullptr;
303 "Memprof with histogram only supports default mapping granularity");
305 MemProfiler Profiler(M);
306 if (Profiler.instrumentFunction(
F))
316 ModuleMemProfiler Profiler(M);
317 if (Profiler.instrumentModule(M))
324 Shadow = IRB.
CreateAnd(Shadow, Mapping.Mask);
325 Shadow = IRB.
CreateLShr(Shadow, Mapping.Scale);
327 assert(DynamicShadowOffset);
328 return IRB.
CreateAdd(Shadow, DynamicShadowOffset);
334 if (isa<MemTransferInst>(
MI)) {
335 IRB.
CreateCall(isa<MemMoveInst>(
MI) ? MemProfMemmove : MemProfMemcpy,
336 {
MI->getOperand(0),
MI->getOperand(1),
338 }
else if (isa<MemSetInst>(
MI)) {
345 MI->eraseFromParent();
348std::optional<InterestingMemoryAccess>
349MemProfiler::isInterestingMemoryAccess(
Instruction *
I)
const {
351 if (DynamicShadowOffset ==
I)
354 InterestingMemoryAccess
Access;
356 if (
LoadInst *LI = dyn_cast<LoadInst>(
I)) {
360 Access.AccessTy = LI->getType();
361 Access.Addr = LI->getPointerOperand();
362 }
else if (
StoreInst *SI = dyn_cast<StoreInst>(
I)) {
366 Access.AccessTy =
SI->getValueOperand()->getType();
367 Access.Addr =
SI->getPointerOperand();
372 Access.AccessTy = RMW->getValOperand()->getType();
373 Access.Addr = RMW->getPointerOperand();
378 Access.AccessTy = XCHG->getCompareOperand()->getType();
379 Access.Addr = XCHG->getPointerOperand();
380 }
else if (
auto *CI = dyn_cast<CallInst>(
I)) {
381 auto *
F = CI->getCalledFunction();
382 if (
F && (
F->getIntrinsicID() == Intrinsic::masked_load ||
383 F->getIntrinsicID() == Intrinsic::masked_store)) {
384 unsigned OpOffset = 0;
385 if (
F->getIntrinsicID() == Intrinsic::masked_store) {
390 Access.AccessTy = CI->getArgOperand(0)->getType();
395 Access.AccessTy = CI->getType();
399 auto *
BasePtr = CI->getOperand(0 + OpOffset);
400 Access.MaybeMask = CI->getOperand(2 + OpOffset);
410 Type *PtrTy = cast<PointerType>(
Access.Addr->getType()->getScalarType());
418 if (
Access.Addr->isSwiftError())
422 auto *
Addr =
Access.Addr->stripInBoundsOffsets();
426 if (GV->hasSection()) {
436 if (GV->getName().starts_with(
"__llvm"))
445 Type *AccessTy,
bool IsWrite) {
446 auto *VTy = cast<FixedVectorType>(AccessTy);
447 unsigned Num = VTy->getNumElements();
448 auto *
Zero = ConstantInt::get(IntptrTy, 0);
449 for (
unsigned Idx = 0;
Idx < Num; ++
Idx) {
450 Value *InstrumentedAddress =
nullptr;
452 if (
auto *
Vector = dyn_cast<ConstantVector>(Mask)) {
465 InsertBefore = ThenTerm;
469 InstrumentedAddress =
476 InterestingMemoryAccess &
Access) {
480 ++NumSkippedStackWrites;
482 ++NumSkippedStackReads;
487 NumInstrumentedWrites++;
489 NumInstrumentedReads++;
502void MemProfiler::instrumentAddress(
Instruction *OrigIns,
509 IRB.
CreateCall(MemProfMemoryAccessCallback[IsWrite], AddrLong);
516 Value *ShadowPtr = memToShadow(AddrLong, IRB);
527 Value *Inc = ConstantInt::get(ShadowTy, 1);
528 ShadowValue = IRB.
CreateAdd(ShadowValue, Inc);
535 dyn_cast_or_null<MDString>(M.getModuleFlag(
"MemProfProfileFilename"));
536 if (!MemProfFilename)
539 "Unexpected MemProfProfileFilename metadata with empty string");
541 M.getContext(), MemProfFilename->
getString(),
true);
543 M, ProfileNameConst->
getType(),
true,
545 Triple TT(M.getTargetTriple());
546 if (TT.supportsCOMDAT()) {
560 Triple TT(M.getTargetTriple());
561 if (TT.supportsCOMDAT()) {
563 MemprofHistogramFlag->setComdat(M.getOrInsertComdat(VarName));
574 "__memprof_default_options_str");
575 Triple TT(M.getTargetTriple());
576 if (TT.supportsCOMDAT()) {
582bool ModuleMemProfiler::instrumentModule(
Module &M) {
586 std::string VersionCheckName =
589 std::tie(MemProfCtorFunction, std::ignore) =
592 {}, VersionCheckName);
594 const uint64_t Priority = getCtorAndDtorPriority(TargetTriple);
606void MemProfiler::initializeCallbacks(
Module &M) {
609 for (
size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) {
610 const std::string TypeStr = AccessIsWrite ?
"store" :
"load";
611 const std::string HistPrefix =
ClHistogram ?
"hist_" :
"";
614 MemProfMemoryAccessCallback[AccessIsWrite] =
M.getOrInsertFunction(
618 MemProfMemmove =
M.getOrInsertFunction(
621 PtrTy, PtrTy, PtrTy, IntptrTy);
627bool MemProfiler::maybeInsertMemProfInitAtFunctionEntry(
Function &
F) {
635 if (
F.getName().contains(
" load]")) {
645bool MemProfiler::insertDynamicShadowAtFunctionEntry(
Function &
F) {
647 Value *GlobalDynamicAddress =
F.getParent()->getOrInsertGlobal(
650 cast<GlobalVariable>(GlobalDynamicAddress)->setDSOLocal(
true);
651 DynamicShadowOffset = IRB.
CreateLoad(IntptrTy, GlobalDynamicAddress);
655bool MemProfiler::instrumentFunction(
Function &
F) {
660 if (
F.getName().starts_with(
"__memprof_"))
663 bool FunctionModified =
false;
668 if (maybeInsertMemProfInitAtFunctionEntry(
F))
669 FunctionModified =
true;
673 initializeCallbacks(*
F.getParent());
679 for (
auto &Inst : BB) {
680 if (isInterestingMemoryAccess(&Inst) || isa<MemIntrinsic>(Inst))
685 if (ToInstrument.
empty()) {
686 LLVM_DEBUG(
dbgs() <<
"MEMPROF done instrumenting: " << FunctionModified
687 <<
" " <<
F <<
"\n");
689 return FunctionModified;
692 FunctionModified |= insertDynamicShadowAtFunctionEntry(
F);
694 int NumInstrumented = 0;
695 for (
auto *Inst : ToInstrument) {
698 std::optional<InterestingMemoryAccess>
Access =
699 isInterestingMemoryAccess(Inst);
701 instrumentMop(Inst,
F.getDataLayout(), *
Access);
703 instrumentMemIntrinsic(cast<MemIntrinsic>(Inst));
708 if (NumInstrumented > 0)
709 FunctionModified =
true;
711 LLVM_DEBUG(
dbgs() <<
"MEMPROF done instrumenting: " << FunctionModified <<
" "
714 return FunctionModified;
720 I.setMetadata(LLVMContext::MD_callsite,
731 std::memcpy(&Id, Hash.data(),
sizeof(Hash));
748 std::memcpy(&Id, Hash.data(),
sizeof(Hash));
756 for (
const auto &StackFrame :
AllocInfo->CallStack)
761 std::vector<ContextTotalSize> ContextSizeInfo;
763 auto TotalSize =
AllocInfo->Info.getTotalSize();
766 ContextSizeInfo.push_back({FullStackId, TotalSize});
779 auto StackFrame = ProfileCallStack.
begin();
780 auto InlCallStackIter = InlinedCallStack.
begin();
781 for (; StackFrame != ProfileCallStack.
end() &&
782 InlCallStackIter != InlinedCallStack.
end();
783 ++StackFrame, ++InlCallStackIter) {
785 if (StackId != *InlCallStackIter)
790 return InlCallStackIter == InlinedCallStack.
end();
802 case LibFunc_ZnwmRKSt9nothrow_t:
803 case LibFunc_ZnwmSt11align_val_t:
804 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t:
806 case LibFunc_ZnamRKSt9nothrow_t:
807 case LibFunc_ZnamSt11align_val_t:
808 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t:
809 case LibFunc_size_returning_new:
810 case LibFunc_size_returning_new_aligned:
812 case LibFunc_Znwm12__hot_cold_t:
813 case LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t:
814 case LibFunc_ZnwmSt11align_val_t12__hot_cold_t:
815 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
816 case LibFunc_Znam12__hot_cold_t:
817 case LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t:
818 case LibFunc_ZnamSt11align_val_t12__hot_cold_t:
819 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
820 case LibFunc_size_returning_new_hot_cold:
821 case LibFunc_size_returning_new_aligned_hot_cold:
831 bool Matched =
false;
840 return (DIL->getLine() - DIL->getScope()->getSubprogram()->getLine()) &
845 if (
F.isDeclaration())
850 if (!isa<CallBase>(&
I) || isa<IntrinsicInst>(&
I))
853 auto *CB = dyn_cast<CallBase>(&
I);
854 auto *CalledFunction = CB->getCalledFunction();
856 if (!CalledFunction || CalledFunction->isIntrinsic())
859 StringRef CalleeName = CalledFunction->getName();
867 DIL = DIL->getInlinedAt()) {
868 StringRef CallerName = DIL->getSubprogramLinkageName();
870 "Be sure to enable -fdebug-info-for-profiling");
880 }
else if (!IsPresentInProfile(CalleeGUID)) {
892 Calls[CallerGUID].emplace_back(Loc, CalleeGUID);
893 CalleeName = CallerName;
901 for (
auto &[CallerGUID, CallList] : Calls) {
918 return CallsFromProfile.
contains(GUID);
922 for (
const auto &[CallerGUID, IRAnchors] : CallsFromIR) {
923 auto It = CallsFromProfile.
find(CallerGUID);
924 if (It == CallsFromProfile.
end())
926 const auto &ProfileAnchors = It->second;
929 longestCommonSequence<LineLocation, GlobalValue::GUID>(
930 ProfileAnchors, IRAnchors, std::equal_to<GlobalValue::GUID>(),
932 bool Inserted = UndriftMaps.
try_emplace(CallerGUID, Matchings).second;
948 auto UndriftCallStack = [&](std::vector<Frame> &
CallStack) {
950 auto I = UndriftMaps.
find(
F.Function);
951 if (
I == UndriftMaps.
end())
954 if (J ==
I->second.end())
956 auto &NewLoc = J->second;
957 F.LineOffset = NewLoc.LineOffset;
958 F.Column = NewLoc.Column;
963 UndriftCallStack(AS.CallStack);
966 UndriftCallStack(CS);
972 std::map<uint64_t, AllocMatchInfo> &FullStackIdToAllocMatchInfo,
974 auto &Ctx = M.getContext();
982 auto FuncName =
F.getName();
984 std::optional<memprof::MemProfRecord> MemProfRec;
985 auto Err =
MemProfReader->getMemProfRecord(FuncGUID).moveInto(MemProfRec);
988 auto Err = IPE.
get();
989 bool SkipWarning =
false;
990 LLVM_DEBUG(
dbgs() <<
"Error in reading profile for Func " << FuncName
993 NumOfMemProfMissing++;
997 NumOfMemProfMismatch++;
1003 LLVM_DEBUG(
dbgs() <<
"hash mismatch (skip=" << SkipWarning <<
")");
1009 std::string Msg = (IPE.
message() +
Twine(
" ") +
F.getName().str() +
1010 Twine(
" Hash = ") + std::to_string(FuncGUID))
1030 bool ProfileHasColumns =
false;
1034 std::map<uint64_t, std::set<const AllocationInfo *>> LocHashToAllocInfo;
1036 struct CallStackHash {
1043 std::map<uint64_t, std::unordered_set<ArrayRef<Frame>, CallStackHash>>
1045 for (
auto &AI : MemProfRec->AllocSites) {
1046 NumOfMemProfAllocContextProfiles++;
1051 LocHashToAllocInfo[StackId].insert(&AI);
1052 ProfileHasColumns |= AI.CallStack[0].Column;
1054 for (
auto &CS : MemProfRec->CallSites) {
1055 NumOfMemProfCallSiteProfiles++;
1059 for (
auto &StackFrame : CS) {
1062 ProfileHasColumns |= StackFrame.Column;
1064 if (StackFrame.Function == FuncGUID)
1067 assert(
Idx <= CS.size() && CS[
Idx - 1].Function == FuncGUID);
1071 return (DIL->getLine() - DIL->getScope()->getSubprogram()->getLine()) &
1077 for (
auto &BB :
F) {
1078 for (
auto &
I : BB) {
1079 if (
I.isDebugOrPseudoInst())
1083 auto *CI = dyn_cast<CallBase>(&
I);
1086 auto *CalledFunction = CI->getCalledFunction();
1087 if (CalledFunction && CalledFunction->isIntrinsic())
1093 bool LeafFound =
false;
1099 std::map<uint64_t, std::set<const AllocationInfo *>>::iterator
1101 decltype(LocHashToCallSites)::iterator CallSitesIter;
1102 for (
const DILocation *DIL =
I.getDebugLoc(); DIL !=
nullptr;
1103 DIL = DIL->getInlinedAt()) {
1106 StringRef Name = DIL->getScope()->getSubprogram()->getLinkageName();
1108 Name = DIL->getScope()->getSubprogram()->getName();
1111 ProfileHasColumns ? DIL->getColumn() : 0);
1117 AllocInfoIter = LocHashToAllocInfo.find(StackId);
1118 CallSitesIter = LocHashToCallSites.find(StackId);
1119 if (AllocInfoIter != LocHashToAllocInfo.end() ||
1120 CallSitesIter != LocHashToCallSites.end())
1134 if (AllocInfoIter != LocHashToAllocInfo.end()) {
1144 for (
auto *
AllocInfo : AllocInfoIter->second) {
1149 InlinedCallStack)) {
1150 NumOfMemProfMatchedAllocContexts++;
1156 TotalSize +=
AllocInfo->Info.getTotalSize();
1158 TotalColdSize +=
AllocInfo->Info.getTotalSize();
1162 assert(FullStackId != 0);
1163 FullStackIdToAllocMatchInfo[FullStackId] = {
1181 if (!AllocTrie.
empty()) {
1182 NumOfMemProfMatchedAllocs++;
1186 assert(MemprofMDAttached ==
I.hasMetadata(LLVMContext::MD_memprof));
1187 if (MemprofMDAttached) {
1204 assert(CallSitesIter != LocHashToCallSites.end());
1205 for (
auto CallStackIdx : CallSitesIter->second) {
1209 InlinedCallStack)) {
1210 NumOfMemProfMatchedCallSites++;
1223 : MemoryProfileFileName(MemoryProfileFile), FS(FS) {
1234 auto &Ctx = M.getContext();
1236 if (
Error E = ReaderOrErr.takeError()) {
1245 std::move(ReaderOrErr.get());
1248 MemoryProfileFileName.data(),
StringRef(
"Cannot get MemProfReader")));
1254 "Not a memory profile"));
1268 std::map<uint64_t, AllocMatchInfo> FullStackIdToAllocMatchInfo;
1271 if (
F.isDeclaration())
1280 for (
const auto &[Id,
Info] : FullStackIdToAllocMatchInfo)
1282 <<
" context with id " << Id <<
" has total profiled size "
1283 <<
Info.TotalSize << (
Info.Matched ?
" is" :
" not")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static cl::opt< int > ClDebugMin("asan-debug-min", cl::desc("Debug min inst"), cl::Hidden, cl::init(-1))
static cl::opt< std::string > ClMemoryAccessCallbackPrefix("asan-memory-access-callback-prefix", cl::desc("Prefix for memory access callbacks"), cl::Hidden, cl::init("__asan_"))
static cl::opt< bool > ClInsertVersionCheck("asan-guard-against-version-mismatch", cl::desc("Guard against compiler/runtime version mismatch."), cl::Hidden, cl::init(true))
static cl::opt< bool > ClInstrumentWrites("asan-instrument-writes", cl::desc("instrument write instructions"), cl::Hidden, cl::init(true))
static cl::opt< int > ClDebugMax("asan-debug-max", cl::desc("Debug max inst"), cl::Hidden, cl::init(-1))
static cl::opt< bool > ClStack("asan-stack", cl::desc("Handle stack memory"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClInstrumentAtomics("asan-instrument-atomics", cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden, cl::init(true))
static cl::opt< int > ClMappingScale("asan-mapping-scale", cl::desc("scale of asan shadow mapping"), cl::Hidden, cl::init(0))
static cl::opt< std::string > ClDebugFunc("asan-debug-func", cl::Hidden, cl::desc("Debug func"))
static cl::opt< bool > ClInstrumentReads("asan-instrument-reads", cl::desc("instrument read instructions"), cl::Hidden, cl::init(true))
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Analysis containing CSE Info
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
Module.h This file contains the declarations for the Module class.
static cl::opt< int > ClMappingGranularity("memprof-mapping-granularity", cl::desc("granularity of memprof shadow mapping"), cl::Hidden, cl::init(DefaultMemGranularity))
constexpr char MemProfVersionCheckNamePrefix[]
static cl::opt< int > ClDebugMin("memprof-debug-min", cl::desc("Debug min inst"), cl::Hidden, cl::init(-1))
void createMemprofHistogramFlagVar(Module &M)
constexpr uint64_t MemProfEmscriptenCtorAndDtorPriority
static uint64_t computeFullStackId(ArrayRef< Frame > CallStack)
static cl::opt< std::string > MemprofRuntimeDefaultOptions("memprof-runtime-default-options", cl::desc("The default memprof options"), cl::Hidden, cl::init(""))
static cl::opt< std::string > ClDebugFunc("memprof-debug-func", cl::Hidden, cl::desc("Debug func"))
constexpr char MemProfShadowMemoryDynamicAddress[]
static void addCallsiteMetadata(Instruction &I, ArrayRef< uint64_t > InlinedCallStack, LLVMContext &Ctx)
static bool isAllocationWithHotColdVariant(const Function *Callee, const TargetLibraryInfo &TLI)
constexpr uint64_t MemProfCtorAndDtorPriority
constexpr int LLVM_MEM_PROFILER_VERSION
static cl::opt< bool > ClUseCalls("memprof-use-callbacks", cl::desc("Use callbacks instead of inline instrumentation sequences."), cl::Hidden, cl::init(false))
static cl::opt< bool > ClInstrumentAtomics("memprof-instrument-atomics", cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClInsertVersionCheck("memprof-guard-against-version-mismatch", cl::desc("Guard against compiler/runtime version mismatch."), cl::Hidden, cl::init(true))
constexpr char MemProfInitName[]
constexpr char MemProfFilenameVar[]
static void undriftMemProfRecord(const DenseMap< uint64_t, LocToLocMap > &UndriftMaps, memprof::MemProfRecord &MemProfRec)
static uint64_t computeStackId(GlobalValue::GUID Function, uint32_t LineOffset, uint32_t Column)
static cl::opt< bool > ClStack("memprof-instrument-stack", cl::desc("Instrument scalar stack variables"), cl::Hidden, cl::init(false))
static cl::opt< bool > ClHistogram("memprof-histogram", cl::desc("Collect access count histograms"), cl::Hidden, cl::init(false))
constexpr uint64_t DefaultMemGranularity
void createMemprofDefaultOptionsVar(Module &M)
static cl::opt< bool > ClPrintMemProfMatchInfo("memprof-print-match-info", cl::desc("Print matching stats for each allocation " "context in this module's profiles"), cl::Hidden, cl::init(false))
constexpr uint64_t HistogramGranularity
constexpr uint64_t DefaultShadowScale
cl::opt< bool > MemProfReportHintedSizes
static cl::opt< std::string > ClMemoryAccessCallbackPrefix("memprof-memory-access-callback-prefix", cl::desc("Prefix for memory access callbacks"), cl::Hidden, cl::init("__memprof_"))
constexpr char MemProfModuleCtorName[]
static cl::opt< bool > SalvageStaleProfile("memprof-salvage-stale-profile", cl::desc("Salvage stale MemProf profile"), cl::init(false), cl::Hidden)
static cl::opt< unsigned > MinMatchedColdBytePercent("memprof-matching-cold-threshold", cl::init(100), cl::Hidden, cl::desc("Min percent of cold bytes matched to hint allocation cold"))
static cl::opt< bool > ClInstrumentReads("memprof-instrument-reads", cl::desc("instrument read instructions"), cl::Hidden, cl::init(true))
static cl::opt< int > ClDebugMax("memprof-debug-max", cl::desc("Debug max inst"), cl::Hidden, cl::init(-1))
static cl::opt< bool > ClInstrumentWrites("memprof-instrument-writes", cl::desc("instrument write instructions"), cl::Hidden, cl::init(true))
static cl::opt< int > ClDebug("memprof-debug", cl::desc("debug"), cl::Hidden, cl::init(0))
static cl::opt< int > ClMappingScale("memprof-mapping-scale", cl::desc("scale of memprof shadow mapping"), cl::Hidden, cl::init(DefaultShadowScale))
static void readMemprof(Module &M, Function &F, IndexedInstrProfReader *MemProfReader, const TargetLibraryInfo &TLI, std::map< uint64_t, AllocMatchInfo > &FullStackIdToAllocMatchInfo, DenseMap< uint64_t, LocToLocMap > &UndriftMaps)
static cl::opt< bool > ClMemProfMatchHotColdNew("memprof-match-hot-cold-new", cl::desc("Match allocation profiles onto existing hot/cold operator new calls"), cl::Hidden, cl::init(false))
static AllocationType addCallStack(CallStackTrie &AllocTrie, const AllocationInfo *AllocInfo, uint64_t FullStackId)
constexpr char MemProfHistogramFlagVar[]
cl::opt< unsigned > MinClonedColdBytePercent("memprof-cloning-cold-threshold", cl::init(100), cl::Hidden, cl::desc("Min percent of cold bytes to hint alloc cold during cloning"))
static bool stackFrameIncludesInlinedCallStack(ArrayRef< Frame > ProfileCallStack, ArrayRef< uint64_t > InlinedCallStack)
cl::opt< bool > MemProfReportHintedSizes("memprof-report-hinted-sizes", cl::init(false), cl::Hidden, cl::desc("Report total allocation sizes of hinted allocations"))
FunctionAnalysisManager FAM
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Defines the virtual file system interface vfs::FileSystem.
Class for arbitrary precision integers.
A container for analyses that lazily runs them and caches their results.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
An instruction that atomically checks whether a specified value is in a memory location,...
an instruction that atomically reads a memory location, combines it with another value,...
static Constant * getString(LLVMContext &Context, StringRef Initializer, bool AddNull=true)
This method constructs a CDS and initializes it with a text string.
This is an important base class in LLVM.
static Constant * getIntegerValue(Type *Ty, const APInt &V)
Return the value for an integer or pointer constant, or a vector thereof, with the given scalar value...
A parsed version of the target data layout string in and methods for querying it.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
Diagnostic information for the PGO profiler.
Base class for error info classes.
virtual std::string message() const
Return the error message as a string.
Lightweight error class with error context and mandatory checking.
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
void setComdat(Comdat *C)
void setLinkage(LinkageTypes LT)
GUID getGUID() const
Return a 64-bit global unique ID constructed from global value name (i.e.
@ ExternalLinkage
Externally visible function.
@ WeakAnyLinkage
Keep one copy of named function when linking (weak)
@ AvailableExternallyLinkage
Available for inspection, not emission.
HashResultTy< HasherT_ > final()
Forward to HasherT::final() if available.
Interface to help hash various types through a hasher type.
std::enable_if_t< hashbuilder_detail::IsHashableData< T >::value, HashBuilder & > add(T Value)
Implement hashing for hashable data types, e.g. integral or enum values.
Value * CreateICmpULT(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Type * getVoidTy()
Fetch the type representing void.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Reader for the indexed binary instrprof format.
static Expected< std::unique_ptr< IndexedInstrProfReader > > create(const Twine &Path, vfs::FileSystem &FS, const Twine &RemappingPath="")
Factory method to create an indexed reader.
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...
instrprof_error get() const
std::string message() const override
Return the error message as a string.
A smart pointer to a reference-counted object that inherits from RefCountedBase or ThreadSafeRefCount...
This is an important class for using LLVM in a threaded context.
An instruction for reading from memory.
StringRef getString() const
This is the common base class for memset/memcpy/memmove.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
MemProfUsePass(std::string MemoryProfileFile, IntrusiveRefCntPtr< vfs::FileSystem > FS=nullptr)
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
A Module instance is used to store all the information related to an LLVM module.
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
bool getLibFunc(StringRef funcName, LibFunc &F) const
Searches for a particular function name.
Triple - Helper class for working with autoconf configuration names.
ObjectFormatType getObjectFormat() const
Get the object format for this triple.
bool isOSEmscripten() const
Tests whether the OS is Emscripten.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
static IntegerType * getInt1Ty(LLVMContext &C)
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
static IntegerType * getIntNTy(LLVMContext &C, unsigned N)
static IntegerType * getInt8Ty(LLVMContext &C)
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
StringRef getName() const
Return a constant reference to the value's name.
An efficient, type-erasing, non-owning reference to a callable.
Class to build a trie of call stack contexts for a particular profiled allocation call,...
void addCallStack(AllocationType AllocType, ArrayRef< uint64_t > StackIds, std::vector< ContextTotalSize > ContextSizeInfo={})
Add a call stack context with the given allocation type to the Trie.
void addSingleAllocTypeAttribute(CallBase *CI, AllocationType AT, StringRef Descriptor)
Add an attribute for the given allocation type to the call instruction.
bool buildAndAttachMIBMetadata(CallBase *CI)
Build and attach the minimal necessary MIB metadata.
Helper class to iterate through stack ids in both metadata (memprof MIB and callsite) and the corresp...
void instrumentAddress(Module &M, IRBuilder<> &IRB, Instruction *OrigIns, Instruction *InsertBefore, Value *Addr, Align Alignment, TypeSize TypeStoreSize, bool IsWrite, Value *SizeArgument, bool UseCalls, bool Recover, int AsanScale, int AsanOffset)
Instrument the memory operand Addr.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ C
The default llvm calling convention, compatible with C.
initializer< Ty > init(const Ty &Val)
DenseMap< uint64_t, LocToLocMap > computeUndriftMap(Module &M, IndexedInstrProfReader *MemProfReader, const TargetLibraryInfo &TLI)
MDNode * buildCallstackMetadata(ArrayRef< uint64_t > CallStack, LLVMContext &Ctx)
Build callstack metadata from the provided list of call stack ids.
AllocationType getAllocType(uint64_t TotalLifetimeAccessDensity, uint64_t AllocCount, uint64_t TotalLifetime)
Return the allocation type for a given set of memory profile values.
DenseMap< uint64_t, SmallVector< CallEdgeTy, 0 > > extractCallsFromIR(Module &M, const TargetLibraryInfo &TLI, function_ref< bool(uint64_t)> IsPresentInProfile=[](uint64_t) { return true;})
std::unordered_map< LineLocation, LineLocation, LineLocationHash > LocToLocMap
std::string getAllocTypeAttributeString(AllocationType Type)
Returns the string to use in attributes with the given type.
IntrusiveRefCntPtr< FileSystem > getRealFileSystem()
Gets an vfs::FileSystem for the 'real' file system, as seen by the operating system.
This is an optimization pass for GlobalISel generic memory operations.
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=6)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
cl::opt< bool > PGOWarnMissing
auto unique(Range &&R, Predicate P)
std::string getInstrProfSectionName(InstrProfSectKind IPSK, Triple::ObjectFormatType OF, bool AddSegmentInfo=true)
Return the name of the profile section corresponding to IPSK.
std::array< uint8_t, NumBytes > BLAKE3Result
The constant LLVM_BLAKE3_OUT_LEN provides the default output length, 32 bytes, which is recommended f...
FunctionCallee declareSanitizerInitFunction(Module &M, StringRef InitName, ArrayRef< Type * > InitArgTypes, bool Weak=false)
std::pair< Function *, FunctionCallee > createSanitizerCtorAndInitFunctions(Module &M, StringRef CtorName, StringRef InitName, ArrayRef< Type * > InitArgTypes, ArrayRef< Value * > InitArgs, StringRef VersionCheckName=StringRef(), bool Weak=false)
Creates sanitizer constructor function, and calls sanitizer's init function from it.
void sort(IteratorTy Start, IteratorTy End)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
cl::opt< bool > NoPGOWarnMismatch
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.compiler.used list.
void createProfileFileNameVar(Module &M, StringRef InstrProfileOutput)
void appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Append F to the list of global ctors of module M with the given Priority.
Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
cl::opt< bool > NoPGOWarnMismatchComdatWeak
Summary of memprof metadata on allocations.
GlobalValue::GUID Function
static GlobalValue::GUID getGUID(const StringRef FunctionName)
llvm::SmallVector< std::vector< Frame > > CallSites
llvm::SmallVector< AllocationInfo > AllocSites