LLVM: lib/Transforms/Instrumentation/MemProfUse.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

36#include

37#include

38

39using namespace llvm;

41

42#define DEBUG_TYPE "memprof"

43

44namespace llvm {

48}

49

50

51

52

54 "memprof-match-hot-cold-new",

56 "Match allocation profiles onto existing hot/cold operator new calls"),

58

61 cl::desc("Print matching stats for each allocation "

62 "context in this module's profiles"),

64

67 cl::desc("Print function GUIDs computed for matching"),

69

72 cl::desc("Salvage stale MemProf profile"),

74

76 "memprof-attach-calleeguids",

78 "Attach calleeguids as value profile metadata for indirect calls."),

80

83 cl::desc("Min percent of cold bytes matched to hint allocation cold"));

84

87 cl::desc("If true, annotate the static data section prefix"));

88

89

90STATISTIC(NumOfMemProfMissing, "Number of functions without memory profile.");

92 "Number of functions having mismatched memory profile hash.");

93STATISTIC(NumOfMemProfFunc, "Number of functions having valid memory profile.");

94STATISTIC(NumOfMemProfAllocContextProfiles,

95 "Number of alloc contexts in memory profile.");

97 "Number of callsites in memory profile.");

98STATISTIC(NumOfMemProfMatchedAllocContexts,

99 "Number of matched memory profile alloc contexts.");

101 "Number of matched memory profile allocs.");

103 "Number of matched memory profile callsites.");

105 "Number of global vars annotated with 'hot' section prefix.");

107 "Number of global vars annotated with 'unlikely' section prefix.");

109 "Number of global vars with unknown hotness (no section prefix).");

110STATISTIC(NumOfMemProfExplicitSectionGlobalVars,

111 "Number of global vars with user-specified section (not annotated).");

112

116 I.setMetadata(LLVMContext::MD_callsite,

118}

119

127 std::memcpy(&Id, Hash.data(), sizeof(Hash));

128 return Id;

129}

130

134

138 AllocInfo->Info.getTotalLifetime());

139}

140

145 for (const auto &StackFrame : AllocInfo->CallStack)

148 std::vector ContextSizeInfo;

150 auto TotalSize = AllocInfo->Info.getTotalSize();

152 assert(FullStackId != 0);

153 ContextSizeInfo.push_back({FullStackId, TotalSize});

154 }

157}

158

159

160

161

162static bool

165 return ProfileCallStack.size() >= InlinedCallStack.size() &&

167 InlinedCallStack, [](const Frame &F, uint64_t StackId) {

168 return computeStackId(F) == StackId;

169 });

170}

171

174 if (!Callee)

175 return false;

176 LibFunc Func;

178 return false;

179 switch (Func) {

180 case LibFunc_Znwm:

181 case LibFunc_ZnwmRKSt9nothrow_t:

182 case LibFunc_ZnwmSt11align_val_t:

183 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t:

184 case LibFunc_Znam:

185 case LibFunc_ZnamRKSt9nothrow_t:

186 case LibFunc_ZnamSt11align_val_t:

187 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t:

188 case LibFunc_size_returning_new:

189 case LibFunc_size_returning_new_aligned:

190 return true;

191 case LibFunc_Znwm12__hot_cold_t:

192 case LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t:

193 case LibFunc_ZnwmSt11align_val_t12__hot_cold_t:

194 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t:

195 case LibFunc_Znam12__hot_cold_t:

196 case LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t:

197 case LibFunc_ZnamSt11align_val_t12__hot_cold_t:

198 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t:

199 case LibFunc_size_returning_new_hot_cold:

200 case LibFunc_size_returning_new_aligned_hot_cold:

202 default:

203 return false;

204 }

205}

206

210 "Should not handle AnnotationOK here");

212 switch (Kind) {

214 ++NumOfMemProfExplicitSectionGlobalVars;

215 Reason.append("explicit section name");

216 break;

218 Reason.append("linker declaration");

219 break;

221 Reason.append("name starts with `llvm.`");

222 break;

223 default:

225 }

227 << Reason << ".\n");

228}

229

234

239

240 auto GetOffset = [](const DILocation *DIL) {

241 return (DIL->getLine() - DIL->getScope()->getSubprogram()->getLine()) &

242 0xffff;

243 };

244

246 if (F.isDeclaration())

247 continue;

248

249 for (auto &BB : F) {

250 for (auto &I : BB) {

252 continue;

253

255 auto *CalledFunction = CB->getCalledFunction();

256

257 if (!CalledFunction || CalledFunction->isIntrinsic())

258 continue;

259

260 StringRef CalleeName = CalledFunction->getName();

261

262

264

265

266 bool IsLeaf = true;

267 for (const DILocation *DIL = I.getDebugLoc(); DIL;

268 DIL = DIL->getInlinedAt()) {

269 StringRef CallerName = DIL->getSubprogramLinkageName();

271 "Be sure to enable -fdebug-info-for-profiling");

274

275

276 if (IsAlloc) {

277 if (IsLeaf) {

278

279

280 CalleeGUID = 0;

281 } else if (!IsPresentInProfile(CalleeGUID)) {

282

283

284 CalleeGUID = 0;

285 } else {

286

287

288 IsAlloc = false;

289 }

290 }

291

293 Calls[CallerGUID].emplace_back(Loc, CalleeGUID);

294 CalleeName = CallerName;

295 IsLeaf = false;

296 }

297 }

298 }

299 }

300

301

302 for (auto &[CallerGUID, CallList] : Calls) {

304 CallList.erase(llvm::unique(CallList), CallList.end());

305 }

306

307 return Calls;

308}

309

314

319 return CallsFromProfile.contains(GUID);

320 });

321

322

323 for (const auto &[CallerGUID, IRAnchors] : CallsFromIR) {

324 auto It = CallsFromProfile.find(CallerGUID);

325 if (It == CallsFromProfile.end())

326 continue;

327 const auto &ProfileAnchors = It->second;

328

331 ProfileAnchors, IRAnchors, std::equal_toGlobalValue::GUID(),

333 [[maybe_unused]] bool Inserted =

334 UndriftMaps.try_emplace(CallerGUID, std::move(Matchings)).second;

335

336

338 }

339

340 return UndriftMaps;

341}

342

343

344

345static void

348

349 auto UndriftCallStack = [&](std::vector &CallStack) {

351 auto I = UndriftMaps.find(F.Function);

352 if (I == UndriftMaps.end())

353 continue;

354 auto J = I->second.find(LineLocation(F.LineOffset, F.Column));

355 if (J == I->second.end())

356 continue;

357 auto &NewLoc = J->second;

358 F.LineOffset = NewLoc.LineOffset;

359 F.Column = NewLoc.Column;

360 }

361 };

362

363 for (auto &AS : MemProfRec.AllocSites)

364 UndriftCallStack(AS.CallStack);

365

366 for (auto &CS : MemProfRec.CallSites)

367 UndriftCallStack(CS.Frames);

368}

369

370

374 return;

375

376 if (I.getMetadata(LLVMContext::MD_prof)) {

378

379

380

382 1, Unused);

383

384 if (!ExistingVD.empty()) {

385 return;

386 }

387 }

388

391

393 InstrProfValueData VD;

394 VD.Value = CalleeGUID;

395

396

397

398

399 VD.Count = 1;

401 TotalCount += VD.Count;

402 }

403

404 if (!VDs.empty()) {

407 }

408}

409

410static void

414 const std::set<const AllocationInfo *> &AllocInfoSet,

415 std::map<std::pair<uint64_t, unsigned>, AllocMatchInfo>

416 &FullStackIdToAllocMatchInfo) {

417

418

419

421 for (auto *AllocInfo : AllocInfoSet) {

423 auto [It, Inserted] =

424 UniqueFullContextIdAllocInfo.insert({FullStackId, AllocInfo});

425

426 if (Inserted)

427 continue;

428

429 auto CurSize = It->second->Info.getTotalSize();

430 auto NewSize = AllocInfo->Info.getTotalSize();

431 if ((CurSize > NewSize) ||

432 (CurSize == NewSize &&

434 continue;

436 }

437

438

439

443 for (auto &[FullStackId, AllocInfo] : UniqueFullContextIdAllocInfo) {

444

445

446

448 InlinedCallStack)) {

449 NumOfMemProfMatchedAllocContexts++;

451 TotalSize += AllocInfo->Info.getTotalSize();

453 TotalColdSize += AllocInfo->Info.getTotalSize();

454

455

457 assert(FullStackId != 0);

458 FullStackIdToAllocMatchInfo[std::make_pair(FullStackId,

459 InlinedCallStack.size())] = {

461 }

464 << ore::NV("AllocationCall", CI) << " in function "

466 << " matched alloc context with alloc type "

468 << " total size " << ore::NV("Size", AllocInfo->Info.getTotalSize())

469 << " full context id " << ore::NV("Context", FullStackId)

470 << " frame count " << ore::NV("Frames", InlinedCallStack.size()));

471 }

472 }

473

474

475

479 return;

480 }

481

482

483

484

485 if (!AllocTrie.empty()) {

486 NumOfMemProfMatchedAllocs++;

487

488

490 assert(MemprofMDAttached == I.hasMetadata(LLVMContext::MD_memprof));

491 if (MemprofMDAttached) {

492

493

494

495

496

497

498

500 }

501 }

502}

503

504

505

506

508

510

512

513

514

515

516

518 return Frames.data() == Other.Frames.data() &&

520 }

521};

522

528

532 const std::unordered_set<CallSiteEntry, CallSiteEntryHash> &CallSiteEntries,

533 Module &M, std::set<std::vector<uint64_t>> &MatchedCallSites,

535 auto &Ctx = M.getContext();

536 for (const auto &CallSiteEntry : CallSiteEntries) {

537

538

540 InlinedCallStack)) {

541 NumOfMemProfMatchedCallSites++;

543

544

545 if (!CalledFunction)

547

548

549

550

551

555 MatchedCallSites.insert(std::move(CallStack));

556 }

558 << ore::NV("CallSite", &I) << " in function "

559 << ore::NV("Caller", I.getFunction())

560 << " matched callsite with frame count "

561 << ore::NV("Frames", InlinedCallStack.size()));

562 break;

563 }

564 }

565}

566

570 std::map<std::pair<uint64_t, unsigned>, AllocMatchInfo>

571 &FullStackIdToAllocMatchInfo,

572 std::set<std::vector<uint64_t>> &MatchedCallSites,

575 auto &Ctx = M.getContext();

576

577

578

579

580

581

582

583 auto FuncName = F.getName();

586 errs() << "MemProf: Function GUID " << FuncGUID << " is " << FuncName

587 << "\n";

588 std::optionalmemprof::MemProfRecord MemProfRec;

589 auto Err = MemProfReader->getMemProfRecord(FuncGUID).moveInto(MemProfRec);

590 if (Err) {

592 auto Err = IPE.get();

593 bool SkipWarning = false;

594 LLVM_DEBUG(dbgs() << "Error in reading profile for Func " << FuncName

595 << ": ");

597 NumOfMemProfMissing++;

601 NumOfMemProfMismatch++;

602 SkipWarning =

605 (F.hasComdat() ||

607 LLVM_DEBUG(dbgs() << "hash mismatch (skip=" << SkipWarning << ")");

608 }

609

610 if (SkipWarning)

611 return;

612

613 std::string Msg = (IPE.message() + Twine(" ") + F.getName().str() +

614 Twine(" Hash = ") + std::to_string(FuncGUID))

615 .str();

616

617 Ctx.diagnose(

619 });

620 return;

621 }

622

623 NumOfMemProfFunc++;

624

625

626

629

630

631

632

633

634 bool ProfileHasColumns = false;

635

636

637

638 std::map<uint64_t, std::set<const AllocationInfo *>> LocHashToAllocInfo;

639

640

641

642 std::map<uint64_t, std::unordered_set<CallSiteEntry, CallSiteEntryHash>>

643 LocHashToCallSites;

644 for (auto &AI : MemProfRec->AllocSites) {

645 NumOfMemProfAllocContextProfiles++;

646

647

648

650 LocHashToAllocInfo[StackId].insert(&AI);

651 ProfileHasColumns |= AI.CallStack[0].Column;

652 }

653 for (auto &CS : MemProfRec->CallSites) {

654 NumOfMemProfCallSiteProfiles++;

655

656

657 unsigned Idx = 0;

658 for (auto &StackFrame : CS.Frames) {

662 LocHashToCallSites[StackId].insert({FrameSlice, CalleeGuids});

663

664 ProfileHasColumns |= StackFrame.Column;

665

666 if (StackFrame.Function == FuncGUID)

667 break;

668 }

669 assert(Idx <= CS.Frames.size() && CS.Frames[Idx - 1].Function == FuncGUID);

670 }

671

672 auto GetOffset = [](const DILocation *DIL) {

673 return (DIL->getLine() - DIL->getScope()->getSubprogram()->getLine()) &

674 0xffff;

675 };

676

677

678

679 for (auto &BB : F) {

680 for (auto &I : BB) {

681 if (I.isDebugOrPseudoInst())

682 continue;

683

684

686 if (!CI)

687 continue;

688 auto *CalledFunction = CI->getCalledFunction();

689 if (CalledFunction && CalledFunction->isIntrinsic())

690 continue;

691

692

694

695 bool LeafFound = false;

696

697

698

699

700

701 auto AllocInfoIter = LocHashToAllocInfo.end();

702 auto CallSitesIter = LocHashToCallSites.end();

703 for (const DILocation *DIL = I.getDebugLoc(); DIL != nullptr;

704 DIL = DIL->getInlinedAt()) {

705

706

707 StringRef Name = DIL->getScope()->getSubprogram()->getLinkageName();

708 if (Name.empty())

709 Name = DIL->getScope()->getSubprogram()->getName();

711 auto StackId = computeStackId(CalleeGUID, GetOffset(DIL),

712 ProfileHasColumns ? DIL->getColumn() : 0);

713

714

715

716

717 if (!LeafFound) {

718 AllocInfoIter = LocHashToAllocInfo.find(StackId);

719 CallSitesIter = LocHashToCallSites.find(StackId);

720 if (AllocInfoIter != LocHashToAllocInfo.end() ||

721 CallSitesIter != LocHashToCallSites.end())

722 LeafFound = true;

723 }

724 if (LeafFound)

725 InlinedCallStack.push_back(StackId);

726 }

727

728 if (!LeafFound)

729 continue;

730

731

732

733

734

735 if (AllocInfoIter != LocHashToAllocInfo.end() &&

736

738 handleAllocSite(I, CI, InlinedCallStack, Ctx, ORE, MaxColdSize,

739 AllocInfoIter->second, FullStackIdToAllocMatchInfo);

740 else if (CallSitesIter != LocHashToCallSites.end())

741

742

743

745 CallSitesIter->second, M, MatchedCallSites, ORE);

746 }

747 }

748}

749

752 : MemoryProfileFileName(MemoryProfileFile), FS(FS) {

753 if (!FS)

755}

756

758

759

760 if (M.empty() && M.globals().empty())

762

764 auto &Ctx = M.getContext();

766 if (Error E = ReaderOrErr.takeError()) {

768 Ctx.diagnose(

770 });

772 }

773

774 std::unique_ptr MemProfReader =

775 std::move(ReaderOrErr.get());

778 MemoryProfileFileName.data(), StringRef("Cannot get MemProfReader")));

780 }

781

784 "Not a memory profile"));

786 }

787

789 annotateGlobalVariables(M, MemProfReader->getDataAccessProfileData());

790

791

792

793 if (M.empty())

795

797

802

803

804

805

806 std::map<std::pair<uint64_t, unsigned>, AllocMatchInfo>

807 FullStackIdToAllocMatchInfo;

808

809

810

811 std::set<std::vector<uint64_t>> MatchedCallSites;

812

814 if (auto *MemProfSum = MemProfReader->getMemProfSummary())

815 MaxColdSize = MemProfSum->getMaxColdTotalSize();

816

817 for (auto &F : M) {

818 if (F.isDeclaration())

819 continue;

820

824 MatchedCallSites, UndriftMaps, ORE, MaxColdSize);

825 }

826

828 for (const auto &[IdLengthPair, Info] : FullStackIdToAllocMatchInfo) {

829 auto [Id, Length] = IdLengthPair;

831 << " context with id " << Id << " has total profiled size "

832 << Info.TotalSize << " is matched with " << Length << " frames\n";

833 }

834

835 for (const auto &CallStack : MatchedCallSites) {

836 errs() << "MemProf callsite match for inline call stack";

838 errs() << " " << StackId;

839 errs() << "\n";

840 }

841 }

842

844}

845

846bool MemProfUsePass::annotateGlobalVariables(

849 return false;

850

851 if (!DataAccessProf) {

852 M.addModuleFlag(Module::Warning, "EnableDataAccessProf", 0U);

854 MemoryProfileFileName.data(),

855 StringRef("Data access profiles not found in memprof. Ignore "

856 "-memprof-annotate-static-data-prefix."),

858 return false;

859 }

860 M.addModuleFlag(Module::Warning, "EnableDataAccessProf", 1U);

861

863

864

865

866

867

869 assert(!GVar.getSectionPrefix().has_value() &&

870 "GVar shouldn't have section prefix yet");

874 continue;

875 }

876

877 StringRef Name = GVar.getName();

878

879

880

881

882 if (Name.starts_with(".str")) {

883 LLVM_DEBUG(dbgs() << "Skip annotating string literal " << Name << "\n");

884 continue;

885 }

886

887

888

889 std::optional Record =

891

892

893

894

895

896

897 if (Record && Record->AccessCount > 0) {

898 ++NumOfMemProfHotGlobalVars;

899 Changed |= GVar.setSectionPrefix("hot");

901 << " is annotated as hot\n");

903 ++NumOfMemProfColdGlobalVars;

904 Changed |= GVar.setSectionPrefix("unlikely");

907 << " is annotated as unlikely\n");

908 } else {

909 ++NumOfMemProfUnknownGlobalVars;

910 LLVM_DEBUG(dbgs() << "Global variable " << Name << " is not annotated\n");

911 }

912 }

913

915}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

Module.h This file contains the declarations for the Module class.

static void addCallsiteMetadata(Instruction &I, ArrayRef< uint64_t > InlinedCallStack, LLVMContext &Ctx)

Definition MemProfUse.cpp:113

static bool isAllocationWithHotColdVariant(const Function *Callee, const TargetLibraryInfo &TLI)

Definition MemProfUse.cpp:172

static cl::opt< bool > ClMemProfAttachCalleeGuids("memprof-attach-calleeguids", cl::desc("Attach calleeguids as value profile metadata for indirect calls."), cl::init(true), cl::Hidden)

static void HandleUnsupportedAnnotationKinds(GlobalVariable &GVar, AnnotationKind Kind)

Definition MemProfUse.cpp:207

static void undriftMemProfRecord(const DenseMap< uint64_t, LocToLocMap > &UndriftMaps, memprof::MemProfRecord &MemProfRec)

Definition MemProfUse.cpp:346

static uint64_t computeStackId(GlobalValue::GUID Function, uint32_t LineOffset, uint32_t Column)

Definition MemProfUse.cpp:120

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))

static void addVPMetadata(Module &M, Instruction &I, ArrayRef< GlobalValue::GUID > CalleeGuids)

Definition MemProfUse.cpp:371

static cl::opt< bool > PrintFunctionGuids("memprof-print-function-guids", cl::desc("Print function GUIDs computed for matching"), cl::Hidden, cl::init(false))

static cl::opt< bool > AnnotateStaticDataSectionPrefix("memprof-annotate-static-data-prefix", cl::init(false), cl::Hidden, cl::desc("If true, annotate the static data section prefix"))

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 void handleCallSite(Instruction &I, const Function *CalledFunction, ArrayRef< uint64_t > InlinedCallStack, const std::unordered_set< CallSiteEntry, CallSiteEntryHash > &CallSiteEntries, Module &M, std::set< std::vector< uint64_t > > &MatchedCallSites, OptimizationRemarkEmitter &ORE)

Definition MemProfUse.cpp:529

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)

Definition MemProfUse.cpp:141

static void readMemprof(Module &M, Function &F, IndexedInstrProfReader *MemProfReader, const TargetLibraryInfo &TLI, std::map< std::pair< uint64_t, unsigned >, AllocMatchInfo > &FullStackIdToAllocMatchInfo, std::set< std::vector< uint64_t > > &MatchedCallSites, DenseMap< uint64_t, LocToLocMap > &UndriftMaps, OptimizationRemarkEmitter &ORE, uint64_t MaxColdSize)

Definition MemProfUse.cpp:567

static void handleAllocSite(Instruction &I, CallBase *CI, ArrayRef< uint64_t > InlinedCallStack, LLVMContext &Ctx, OptimizationRemarkEmitter &ORE, uint64_t MaxColdSize, const std::set< const AllocationInfo * > &AllocInfoSet, std::map< std::pair< uint64_t, unsigned >, AllocMatchInfo > &FullStackIdToAllocMatchInfo)

Definition MemProfUse.cpp:411

static bool stackFrameIncludesInlinedCallStack(ArrayRef< Frame > ProfileCallStack, ArrayRef< uint64_t > InlinedCallStack)

Definition MemProfUse.cpp:163

FunctionAnalysisManager FAM

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.

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),...

ArrayRef< T > take_front(size_t N=1) const

Return a copy of *this with only the first N elements.

ArrayRef< T > drop_front(size_t N=1) const

Drop the first N elements of the array.

size_t size() const

size - Get the array size.

bool empty() const

empty - Check if the array is empty.

Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...

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.

std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)

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.

static LLVM_ABI GUID getGUIDAssumingExternalLinkage(StringRef GlobalName)

Return a 64-bit global unique ID constructed from the name of a global symbol.

uint64_t GUID

Declare a type to represent a global unique identifier for a global value.

@ 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.

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.

instrprof_error get() const

std::string message() const override

Return the error message as a string.

LLVM_ABI const Function * getFunction() const

Return the function this instruction belongs to.

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.

LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)

Definition MemProfUse.cpp:757

LLVM_ABI MemProfUsePass(std::string MemoryProfileFile, IntrusiveRefCntPtr< vfs::FileSystem > FS=nullptr)

Definition MemProfUse.cpp:750

A Module instance is used to store all the information related to an LLVM module.

@ Warning

Emits a warning if two values disagree.

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.

SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...

void append(StringRef RHS)

Append from a StringRef.

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

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.

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

LLVM_ABI 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,...

LLVM_ABI 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.

LLVM_ABI void addSingleAllocTypeAttribute(CallBase *CI, AllocationType AT, StringRef Descriptor)

Add an attribute for the given allocation type to the call instruction.

LLVM_ABI 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...

Encapsulates the data access profile data and the methods to operate on it.

LLVM_ABI std::optional< DataAccessProfRecord > getProfileRecord(const SymbolHandleRef SymID) const

Returns a profile record for SymbolID, or std::nullopt if there isn't a record.

LLVM_ABI bool isKnownColdSymbol(const SymbolHandleRef SymID) const

Returns true if SymID is seen in profiled binaries and cold.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

initializer< Ty > init(const Ty &Val)

LLVM_ABI DenseMap< uint64_t, LocToLocMap > computeUndriftMap(Module &M, IndexedInstrProfReader *MemProfReader, const TargetLibraryInfo &TLI)

Definition MemProfUse.cpp:311

LLVM_ABI MDNode * buildCallstackMetadata(ArrayRef< uint64_t > CallStack, LLVMContext &Ctx)

Build callstack metadata from the provided list of call stack ids.

LLVM_ABI AllocationType getAllocType(uint64_t TotalLifetimeAccessDensity, uint64_t AllocCount, uint64_t TotalLifetime)

Return the allocation type for a given set of memory profile values.

LLVM_ABI bool recordContextSizeInfoForAnalysis()

Whether we need to record the context size info in the alloc trie used to build metadata.

std::unordered_map< LineLocation, LineLocation, LineLocationHash > LocToLocMap

LLVM_ABI uint64_t computeFullStackId(ArrayRef< Frame > CallStack)

Helper to generate a single hash id for a given callstack, used for emitting matching statistics and ...

LLVM_ABI DenseMap< uint64_t, SmallVector< CallEdgeTy, 0 > > extractCallsFromIR(Module &M, const TargetLibraryInfo &TLI, function_ref< bool(uint64_t)> IsPresentInProfile=[](uint64_t) { return true;})

Definition MemProfUse.cpp:236

AnnotationKind getAnnotationKind(const GlobalVariable &GV)

Returns the annotation kind of the global variable GV.

LLVM_ABI GlobalValue::GUID getGUID(const StringRef FunctionName)

LLVM_ABI std::string getAllocTypeAttributeString(AllocationType Type)

Returns the string to use in attributes with the given type.

DiagnosticInfoOptimizationBase::Argument NV

LLVM_ABI 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.

std::array< uint8_t, NumBytes > BLAKE3Result

The constant LLVM_BLAKE3_OUT_LEN provides the default output length, 32 bytes, which is recommended f...

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

void handleAllErrors(Error E, HandlerTs &&... Handlers)

Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...

void append_range(Container &C, Range &&R)

Wrapper function to append range R to container C.

InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy

Provide the FunctionAnalysisManager to Module proxy.

cl::opt< bool > PGOWarnMissing

auto unique(Range &&R, Predicate P)

LLVM_ABI void annotateValueSite(Module &M, Instruction &Inst, const InstrProfRecord &InstrProfR, InstrProfValueKind ValueKind, uint32_t SiteIndx, uint32_t MaxMDCount=3)

Get the value profile data for value site SiteIdx from InstrProfR and annotate the instruction Inst w...

void sort(IteratorTy Start, IteratorTy End)

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

LLVM_ABI SmallVector< InstrProfValueData, 4 > getValueProfDataFromInst(const Instruction &Inst, InstrProfValueKind ValueKind, uint32_t MaxNumValueData, uint64_t &TotalC, bool GetNoICPValue=false)

Extract the value profile data from Inst and returns them if Inst is annotated with value profile dat...

bool isa(const From &Val)

isa - Return true if the parameter to the template is an instance of one of the template type argu...

cl::opt< bool > NoPGOWarnMismatch

Definition MemProfUse.cpp:46

LLVM_ABI raw_fd_ostream & errs()

This returns a reference to a raw_ostream for standard error.

cl::opt< bool > SalvageStaleProfile("salvage-stale-profile", cl::Hidden, cl::init(false), cl::desc("Salvage stale profile by fuzzy matching and use the remapped " "location for sample profile query."))

void longestCommonSequence(AnchorList AnchorList1, AnchorList AnchorList2, llvm::function_ref< bool(const Function &, const Function &)> FunctionMatchesProfile, llvm::function_ref< void(Loc, Loc)> InsertMatching)

ArrayRef(const T &OneElt) -> ArrayRef< T >

bool equal(L &&LRange, R &&RRange)

Wrapper function around std::equal to detect if pair-wise elements between two ranges are the same.

AnalysisManager< Module > ModuleAnalysisManager

Convenience typedef for the Module analysis manager.

cl::opt< bool > NoPGOWarnMismatchComdatWeak

Definition MemProfUse.cpp:230

uint64_t TotalSize

Definition MemProfUse.cpp:231

AllocationType AllocType

Definition MemProfUse.cpp:232

Definition MemProfUse.cpp:523

size_t operator()(const CallSiteEntry &Entry) const

Definition MemProfUse.cpp:524

Definition MemProfUse.cpp:507

ArrayRef< GlobalValue::GUID > CalleeGuids

Definition MemProfUse.cpp:511

bool operator==(const CallSiteEntry &Other) const

Definition MemProfUse.cpp:517

ArrayRef< Frame > Frames

Definition MemProfUse.cpp:509

Summary of memprof metadata on allocations.

GlobalValue::GUID Function

llvm::SmallVector< CallSiteInfo > CallSites

llvm::SmallVector< AllocationInfo > AllocSites