LLVM 23.0.0git
InstrProfCorrelator.cpp
Go to the documentation of this file.
1//===-- InstrProfCorrelator.cpp -------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
17#include "llvm/Object/MachO.h"
18#include "llvm/Support/Debug.h"
19#include "llvm/Support/Format.h"
21#include <optional>
22
23#define DEBUG_TYPE "correlator"
24
25using namespace llvm;
26
27/// Get profile section.
30 // On COFF, the getInstrProfSectionName returns the section names may followed
31 // by "$M". The linker removes the dollar and everything after it in the final
32 // binary. Do the same to match.
33 Triple::ObjectFormatType ObjFormat = Obj.getTripleObjectFormat();
34 auto StripSuffix = [ObjFormat](StringRef N) {
35 return ObjFormat == Triple::COFF ? N.split('$').first : N;
36 };
37 std::string ExpectedSectionName =
38 getInstrProfSectionName(IPSK, ObjFormat,
39 /*AddSegmentInfo=*/false);
40 ExpectedSectionName = StripSuffix(ExpectedSectionName);
41 for (auto &Section : Obj.sections()) {
42 if (auto SectionName = Section.getName())
43 if (*SectionName == ExpectedSectionName)
44 return Section;
45 }
48 "could not find section (" + Twine(ExpectedSectionName) + ")");
49}
50
51const char *InstrProfCorrelator::FunctionNameAttributeName = "Function Name";
52const char *InstrProfCorrelator::CFGHashAttributeName = "CFG Hash";
53const char *InstrProfCorrelator::NumCountersAttributeName = "Num Counters";
54
56InstrProfCorrelator::Context::get(std::unique_ptr<MemoryBuffer> Buffer,
58 ProfCorrelatorKind FileKind) {
59 auto C = std::make_unique<Context>();
60 auto CountersSection = getInstrProfSection(Obj, IPSK_cnts);
61 if (auto Err = CountersSection.takeError())
62 return std::move(Err);
63 Triple::ObjectFormatType ObjFormat = Obj.getTripleObjectFormat();
64 if (FileKind == InstrProfCorrelator::BINARY) {
65 auto DataSection = getInstrProfSection(Obj, IPSK_covdata);
66 if (auto Err = DataSection.takeError())
67 return std::move(Err);
68 auto DataOrErr = DataSection->getContents();
69 if (!DataOrErr)
70 return DataOrErr.takeError();
71 auto NameSection = getInstrProfSection(Obj, IPSK_covname);
72 if (auto Err = NameSection.takeError())
73 return std::move(Err);
74 auto NameOrErr = NameSection->getContents();
75 if (!NameOrErr)
76 return NameOrErr.takeError();
77 C->DataStart = DataOrErr->data();
78 C->DataEnd = DataOrErr->data() + DataOrErr->size();
79 C->NameStart = NameOrErr->data();
80 C->NameSize = NameOrErr->size();
81
82 if (ObjFormat == Triple::MachO) {
83 std::string FullSectionName =
84 getInstrProfSectionName(IPSK_covdata, ObjFormat);
85 SmallVector<StringRef, 3> SegmentAndSection;
86 StringRef(FullSectionName).split(SegmentAndSection, ',', 2);
87 auto *MachO = static_cast<object::MachOObjectFile *>(&Obj);
88 Error Err = Error::success();
89 for (const object::MachOChainedFixupEntry &Entry :
90 MachO->fixupTable(Err)) {
91 if (Entry.isRebase() && Entry.segmentName() == SegmentAndSection[0] &&
92 Entry.sectionName() == SegmentAndSection[1]) {
93 C->MachOFixups[Entry.address() - DataSection->getAddress()] =
94 Entry.pointerValue();
95 }
96 }
97 if (Err)
98 return std::move(Err);
99 }
100 }
101 C->Buffer = std::move(Buffer);
102 C->CountersSectionStart = CountersSection->getAddress();
103 C->CountersSectionEnd = C->CountersSectionStart + CountersSection->getSize();
104 // In COFF object file, there's a null byte at the beginning of the counter
105 // section which doesn't exist in raw profile.
106 if (ObjFormat == Triple::COFF)
107 ++C->CountersSectionStart;
108
109 C->ShouldSwapBytes = Obj.isLittleEndian() != sys::IsLittleEndianHost;
110 return Expected<std::unique_ptr<Context>>(std::move(C));
111}
112
115 const object::BuildIDFetcher *BIDFetcher,
116 const ArrayRef<object::BuildID> BIs) {
117 std::optional<std::string> Path;
118 if (BIDFetcher) {
119 if (BIs.empty())
122 "unsupported profile binary correlation when there is no build ID "
123 "in a profile");
124 if (BIs.size() > 1)
127 "unsupported profile binary correlation when there are multiple "
128 "build IDs in a profile");
129
130 Path = BIDFetcher->fetch(BIs.front());
131 if (!Path)
134 "Missing build ID: " + llvm::toHex(BIs.front(),
135 /*LowerCase=*/true));
136 Filename = *Path;
137 }
138
139 if (FileKind == DEBUG_INFO) {
140 auto DsymObjectsOrErr =
142 if (auto Err = DsymObjectsOrErr.takeError())
143 return std::move(Err);
144 if (!DsymObjectsOrErr->empty()) {
145 // TODO: Enable profile correlation when there are multiple objects in a
146 // dSYM bundle.
147 if (DsymObjectsOrErr->size() > 1)
150 "using multiple objects is not yet supported");
151 Filename = *DsymObjectsOrErr->begin();
152 }
154 if (auto Err = BufferOrErr.takeError())
155 return std::move(Err);
156
157 return get(std::move(*BufferOrErr), FileKind);
158 }
159 if (FileKind == BINARY) {
161 if (auto Err = BufferOrErr.takeError())
162 return std::move(Err);
163
164 return get(std::move(*BufferOrErr), FileKind);
165 }
168 "unsupported correlation kind (only DWARF debug info and Binary format "
169 "(ELF/COFF) are supported)");
170}
171
173InstrProfCorrelator::get(std::unique_ptr<MemoryBuffer> Buffer,
174 ProfCorrelatorKind FileKind) {
175 auto BinOrErr = object::createBinary(*Buffer);
176 if (auto Err = BinOrErr.takeError())
177 return std::move(Err);
178
179 if (auto *Obj = dyn_cast<object::ObjectFile>(BinOrErr->get())) {
180 auto CtxOrErr = Context::get(std::move(Buffer), *Obj, FileKind);
181 if (auto Err = CtxOrErr.takeError())
182 return std::move(Err);
183 auto T = Obj->makeTriple();
184 if (T.isArch64Bit())
185 return InstrProfCorrelatorImpl<uint64_t>::get(std::move(*CtxOrErr), *Obj,
186 FileKind);
187 if (T.isArch32Bit())
188 return InstrProfCorrelatorImpl<uint32_t>::get(std::move(*CtxOrErr), *Obj,
189 FileKind);
190 }
193}
194
195std::optional<size_t> InstrProfCorrelator::getDataSize() const {
197 return C->getDataSize();
199 return C->getDataSize();
200 return {};
201}
202
203namespace llvm {
204
205template <>
210template <>
215template <>
219template <>
223
224} // end namespace llvm
225
226template <class IntPtrT>
229 std::unique_ptr<InstrProfCorrelator::Context> Ctx,
230 const object::ObjectFile &Obj, ProfCorrelatorKind FileKind) {
231 if (FileKind == DEBUG_INFO) {
232 if (Obj.isELF() || Obj.isMachO()) {
233 auto DICtx = DWARFContext::create(Obj);
234 return std::make_unique<DwarfInstrProfCorrelator<IntPtrT>>(
235 std::move(DICtx), std::move(Ctx));
236 }
239 "unsupported debug info format (only DWARF is supported)");
240 }
241 if (Obj.isELF() || Obj.isCOFF() || Obj.isMachO())
242 return std::make_unique<BinaryInstrProfCorrelator<IntPtrT>>(std::move(Ctx));
245 "unsupported binary format (only ELF, COFF, and Mach-O are supported)");
246}
247
248template <class IntPtrT>
250 assert(Data.empty() && Names.empty() && NamesVec.empty());
251 correlateProfileDataImpl(MaxWarnings);
252 if (this->Data.empty())
255 "could not find any profile data metadata in correlated file");
257 this->CounterOffsets.clear();
258 this->NamesVec.clear();
259 return Result;
260}
261
262template <> struct yaml::MappingTraits<InstrProfCorrelator::CorrelationData> {
263 static void mapping(yaml::IO &io,
265 io.mapRequired("Probes", Data.Probes);
266 }
267};
268
269template <> struct yaml::MappingTraits<InstrProfCorrelator::Probe> {
271 io.mapRequired("Function Name", P.FunctionName);
272 io.mapOptional("Linkage Name", P.LinkageName);
273 io.mapRequired("CFG Hash", P.CFGHash);
274 io.mapRequired("Counter Offset", P.CounterOffset);
275 io.mapRequired("Num Counters", P.NumCounters);
276 io.mapOptional("File", P.FilePath);
277 io.mapOptional("Line", P.LineNumber);
278 }
279};
280
282 static const bool flow = false;
283};
284
285template <class IntPtrT>
287 raw_ostream &OS) {
289 correlateProfileDataImpl(MaxWarnings, &Data);
290 if (Data.Probes.empty())
293 "could not find any profile data metadata in debug info");
294 yaml::Output YamlOS(OS);
295 YamlOS << Data;
296 return Error::success();
297}
298
299template <class IntPtrT>
301 uint64_t CFGHash,
302 IntPtrT CounterOffset,
303 IntPtrT FunctionPtr,
305 // Check if a probe was already added for this counter offset.
306 if (!CounterOffsets.insert(CounterOffset).second)
307 return;
308 Data.push_back({
309 maybeSwap<uint64_t>(NameRef),
310 maybeSwap<uint64_t>(CFGHash),
311 // In this mode, CounterPtr actually stores the section relative address
312 // of the counter.
313 maybeSwap<IntPtrT>(CounterOffset),
314 // TODO: MC/DC is not yet supported.
315 /*BitmapOffset=*/maybeSwap<IntPtrT>(0),
316 maybeSwap<IntPtrT>(FunctionPtr),
317 // TODO: Value profiling is not yet supported.
318 /*ValuesPtr=*/maybeSwap<IntPtrT>(0),
320 /*NumValueSites=*/{maybeSwap<uint16_t>(0), maybeSwap<uint16_t>(0)},
321 // TODO: MC/DC is not yet supported.
322 /*NumBitmapBytes=*/maybeSwap<uint32_t>(0),
323 });
324}
325
326template <class IntPtrT>
327std::optional<uint64_t>
328DwarfInstrProfCorrelator<IntPtrT>::getLocation(const DWARFDie &Die) const {
329 auto Locations = Die.getLocations(dwarf::DW_AT_location);
330 if (!Locations) {
331 consumeError(Locations.takeError());
332 return {};
333 }
334 auto &DU = *Die.getDwarfUnit();
335 auto AddressSize = DU.getAddressByteSize();
336 for (auto &Location : *Locations) {
337 DataExtractor Data(Location.Expr, DICtx->isLittleEndian(), AddressSize);
338 DWARFExpression Expr(Data, AddressSize);
339 for (auto &Op : Expr) {
340 if (Op.getCode() == dwarf::DW_OP_addr)
341 return Op.getRawOperand(0);
342 if (Op.getCode() == dwarf::DW_OP_addrx) {
343 uint64_t Index = Op.getRawOperand(0);
344 if (auto SA = DU.getAddrOffsetSectionItem(Index))
345 return SA->Address;
346 }
347 }
348 }
349 return {};
350}
351
352template <class IntPtrT>
353bool DwarfInstrProfCorrelator<IntPtrT>::isDIEOfProbe(const DWARFDie &Die) {
354 const auto &ParentDie = Die.getParent();
355 if (!Die.isValid() || !ParentDie.isValid() || Die.isNULL())
356 return false;
357 if (Die.getTag() != dwarf::DW_TAG_variable)
358 return false;
359 if (!ParentDie.isSubprogramDIE())
360 return false;
361 if (!Die.hasChildren())
362 return false;
363 if (const char *Name = Die.getName(DINameKind::ShortName))
365 return false;
366}
367
368template <class IntPtrT>
369void DwarfInstrProfCorrelator<IntPtrT>::correlateProfileDataImpl(
370 int MaxWarnings, InstrProfCorrelator::CorrelationData *Data) {
371 bool UnlimitedWarnings = (MaxWarnings == 0);
372 // -N suppressed warnings means we can emit up to N (unsuppressed) warnings
373 int NumSuppressedWarnings = -MaxWarnings;
374 auto MaybeAddProbe = [&](DWARFDie Die) {
375 if (!isDIEOfProbe(Die))
376 return;
377 std::optional<const char *> FunctionName;
378 std::optional<uint64_t> CFGHash;
379 std::optional<uint64_t> CounterPtr = getLocation(Die);
380 auto FnDie = Die.getParent();
381 auto FunctionPtr = dwarf::toAddress(FnDie.find(dwarf::DW_AT_low_pc));
382 std::optional<uint64_t> NumCounters;
383 for (const DWARFDie &Child : Die.children()) {
384 if (Child.getTag() != dwarf::DW_TAG_LLVM_annotation)
385 continue;
386 auto AnnotationFormName = Child.find(dwarf::DW_AT_name);
387 auto AnnotationFormValue = Child.find(dwarf::DW_AT_const_value);
388 if (!AnnotationFormName || !AnnotationFormValue)
389 continue;
390 auto AnnotationNameOrErr = AnnotationFormName->getAsCString();
391 if (auto Err = AnnotationNameOrErr.takeError()) {
392 consumeError(std::move(Err));
393 continue;
394 }
395 StringRef AnnotationName = *AnnotationNameOrErr;
397 if (auto EC =
398 AnnotationFormValue->getAsCString().moveInto(FunctionName))
399 consumeError(std::move(EC));
400 } else if (AnnotationName == InstrProfCorrelator::CFGHashAttributeName) {
401 CFGHash = AnnotationFormValue->getAsUnsignedConstant();
402 } else if (AnnotationName ==
404 NumCounters = AnnotationFormValue->getAsUnsignedConstant();
405 }
406 }
407 // If there is no function and no counter, assume it was dead-stripped
408 if (!FunctionPtr && !CounterPtr)
409 return;
410 if (!FunctionName || !CFGHash || !CounterPtr || !NumCounters) {
411 if (UnlimitedWarnings || ++NumSuppressedWarnings < 1) {
413 << "Incomplete DIE for function " << FunctionName
414 << ": CFGHash=" << CFGHash << " CounterPtr=" << CounterPtr
415 << " NumCounters=" << NumCounters << "\n";
416 LLVM_DEBUG(Die.dump(dbgs()));
417 }
418 return;
419 }
420 uint64_t CountersStart = this->Ctx->CountersSectionStart;
421 uint64_t CountersEnd = this->Ctx->CountersSectionEnd;
422 if (*CounterPtr < CountersStart || *CounterPtr >= CountersEnd) {
423 if (UnlimitedWarnings || ++NumSuppressedWarnings < 1) {
425 << format("CounterPtr out of range for function %s: Actual=0x%x "
426 "Expected=[0x%x, 0x%x)\n",
427 *FunctionName, *CounterPtr, CountersStart, CountersEnd);
428 LLVM_DEBUG(Die.dump(dbgs()));
429 }
430 return;
431 }
432 if (!FunctionPtr && (UnlimitedWarnings || ++NumSuppressedWarnings < 1)) {
433 WithColor::warning() << format("Could not find address of function %s\n",
434 *FunctionName);
435 LLVM_DEBUG(Die.dump(dbgs()));
436 }
437 // In debug info correlation mode, the CounterPtr is an absolute address of
438 // the counter, but it's expected to be relative later when iterating Data.
439 IntPtrT CounterOffset = *CounterPtr - CountersStart;
440 if (Data) {
442 P.FunctionName = *FunctionName;
443 if (const char *Name = FnDie.getName(DINameKind::LinkageName))
444 P.LinkageName = Name;
445 P.CFGHash = *CFGHash;
446 P.CounterOffset = CounterOffset;
447 P.NumCounters = *NumCounters;
448 auto FilePath = FnDie.getDeclFile(
450 if (!FilePath.empty())
451 P.FilePath = FilePath;
452 if (auto LineNumber = FnDie.getDeclLine())
453 P.LineNumber = LineNumber;
454 Data->Probes.push_back(P);
455 } else {
456 this->addDataProbe(IndexedInstrProf::ComputeHash(*FunctionName), *CFGHash,
457 CounterOffset, FunctionPtr.value_or(0), *NumCounters);
458 this->NamesVec.push_back(*FunctionName);
459 }
460 };
461 for (auto &CU : DICtx->normal_units())
462 for (const auto &Entry : CU->dies())
463 MaybeAddProbe(DWARFDie(CU.get(), &Entry));
464 for (auto &CU : DICtx->dwo_units())
465 for (const auto &Entry : CU->dies())
466 MaybeAddProbe(DWARFDie(CU.get(), &Entry));
467
468 if (!UnlimitedWarnings && NumSuppressedWarnings > 0)
469 WithColor::warning() << format("Suppressed %d additional warnings\n",
470 NumSuppressedWarnings);
471}
472
473template <class IntPtrT>
474Error DwarfInstrProfCorrelator<IntPtrT>::correlateProfileNameImpl() {
475 if (this->NamesVec.empty()) {
478 "could not find any profile name metadata in debug info");
479 }
480 auto Result =
481 collectGlobalObjectNameStrings(this->NamesVec,
482 /*doCompression=*/false, this->Names);
483 return Result;
484}
485
486template <class IntPtrT>
487void BinaryInstrProfCorrelator<IntPtrT>::correlateProfileDataImpl(
488 int MaxWarnings, InstrProfCorrelator::CorrelationData *CorrelateData) {
489 using RawProfData = RawInstrProf::ProfileData<IntPtrT>;
490 bool UnlimitedWarnings = (MaxWarnings == 0);
491 // -N suppressed warnings means we can emit up to N (unsuppressed) warnings
492 int NumSuppressedWarnings = -MaxWarnings;
493
494 const RawProfData *DataStart = (const RawProfData *)this->Ctx->DataStart;
495 const RawProfData *DataEnd = (const RawProfData *)this->Ctx->DataEnd;
496 // We need to use < here because the last data record may have no padding.
497 for (const RawProfData *I = DataStart; I < DataEnd; ++I) {
498 uint64_t CounterPtr = this->template maybeSwap<IntPtrT>(I->CounterPtr);
499 uint64_t CountersStart = this->Ctx->CountersSectionStart;
500 uint64_t CountersEnd = this->Ctx->CountersSectionEnd;
501 if (!this->Ctx->MachOFixups.empty()) {
502 uint64_t Offset = (uint64_t)&I->CounterPtr - (uint64_t)DataStart;
503 auto It = this->Ctx->MachOFixups.find(Offset);
504 if (It != this->Ctx->MachOFixups.end()) {
505 CounterPtr = It->second;
506 } else if (UnlimitedWarnings || ++NumSuppressedWarnings < 1) {
508 "Mach-O fixup not found for covdata offset 0x%llx\n", Offset);
509 }
510 }
511 if (CounterPtr < CountersStart || CounterPtr >= CountersEnd) {
512 if (UnlimitedWarnings || ++NumSuppressedWarnings < 1) {
514 << format("CounterPtr out of range for function: Actual=0x%x "
515 "Expected=[0x%x, 0x%x) at data offset=0x%x\n",
516 CounterPtr, CountersStart, CountersEnd,
517 (I - DataStart) * sizeof(RawProfData));
518 }
519 }
520 // In binary correlation mode, the CounterPtr is an absolute address of the
521 // counter, but it's expected to be relative later when iterating Data.
522 IntPtrT CounterOffset = CounterPtr - CountersStart;
523 this->addDataProbe(I->NameRef, I->FuncHash, CounterOffset,
524 I->FunctionPointer, I->NumCounters);
525 }
526}
527
528template <class IntPtrT>
529Error BinaryInstrProfCorrelator<IntPtrT>::correlateProfileNameImpl() {
530 if (this->Ctx->NameSize == 0) {
533 "could not find any profile data metadata in object file");
534 }
535 this->Names.append(this->Ctx->NameStart, this->Ctx->NameSize);
536 return Error::success();
537}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static Expected< object::SectionRef > getInstrProfSection(const object::ObjectFile &Obj, InstrProfSectKind IPSK)
Get profile section.
#define I(x, y, z)
Definition MD5.cpp:57
#define T
static constexpr StringLiteral Filename
#define P(N)
static MemoryLocation getLocation(Instruction *I)
#define LLVM_DEBUG(...)
Definition Debug.h:114
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
const T & front() const
front - Get the first element.
Definition ArrayRef.h:145
size_t size() const
size - Get the array size.
Definition ArrayRef.h:142
bool empty() const
empty - Check if the array is empty.
Definition ArrayRef.h:137
static std::unique_ptr< DWARFContext > create(const object::ObjectFile &Obj, ProcessDebugRelocations RelocAction=ProcessDebugRelocations::Process, const LoadedObjectInfo *L=nullptr, std::string DWPName="", std::function< void(Error)> RecoverableErrorHandler=WithColor::defaultErrorHandler, std::function< void(Error)> WarningHandler=WithColor::defaultWarningHandler, bool ThreadSafe=false)
Utility class that carries the DWARF compile/type unit and the debug info entry in an object.
Definition DWARFDie.h:43
iterator_range< iterator > children() const
Definition DWARFDie.h:406
LLVM_ABI DWARFDie getParent() const
Get the parent of this DIE object.
Definition DWARFDie.cpp:725
DWARFUnit * getDwarfUnit() const
Definition DWARFDie.h:55
bool hasChildren() const
Definition DWARFDie.h:80
LLVM_ABI const char * getName(DINameKind Kind) const
Return the DIE name resolving DW_AT_specification or DW_AT_abstract_origin references if necessary.
Definition DWARFDie.cpp:531
dwarf::Tag getTag() const
Definition DWARFDie.h:73
LLVM_ABI Expected< DWARFLocationExpressionsVector > getLocations(dwarf::Attribute Attr) const
Definition DWARFDie.cpp:495
bool isNULL() const
Returns true for a valid DIE that terminates a sibling chain.
Definition DWARFDie.h:86
bool isValid() const
Definition DWARFDie.h:52
LLVM_ABI void dump(raw_ostream &OS, unsigned indent=0, DIDumpOptions DumpOpts=DIDumpOptions()) const
Dump the DIE and all of its attributes to the supplied stream.
Definition DWARFDie.cpp:663
uint8_t getAddressByteSize() const
Definition DWARFUnit.h:333
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Tagged union holding either a T or a Error.
Definition Error.h:485
InstrProfCorrelatorImpl - A child of InstrProfCorrelator with a template pointer type so that the Pro...
static llvm::Expected< std::unique_ptr< InstrProfCorrelatorImpl< IntPtrT > > > get(std::unique_ptr< InstrProfCorrelator::Context > Ctx, const object::ObjectFile &Obj, ProfCorrelatorKind FileKind)
virtual Error correlateProfileNameImpl()=0
virtual void correlateProfileDataImpl(int MaxWarnings, InstrProfCorrelator::CorrelationData *Data=nullptr)=0
std::vector< RawInstrProf::ProfileData< IntPtrT > > Data
Error correlateProfileData(int MaxWarnings) override
Construct a ProfileData vector used to correlate raw instrumentation data to their functions.
static bool classof(const InstrProfCorrelator *C)
InstrProfCorrelatorImpl(std::unique_ptr< InstrProfCorrelator::Context > Ctx)
void addDataProbe(uint64_t FunctionName, uint64_t CFGHash, IntPtrT CounterOffset, IntPtrT FunctionPtr, uint32_t NumCounters)
Error dumpYaml(int MaxWarnings, raw_ostream &OS) override
Process debug info and dump the correlation data.
InstrProfCorrelator - A base class used to create raw instrumentation data to their functions.
static LLVM_ABI const char * FunctionNameAttributeName
static LLVM_ABI const char * CFGHashAttributeName
InstrProfCorrelator(InstrProfCorrelatorKind K, std::unique_ptr< Context > Ctx)
std::vector< std::string > NamesVec
static LLVM_ABI const char * NumCountersAttributeName
ProfCorrelatorKind
Indicate if we should use the debug info or profile metadata sections to correlate.
const std::unique_ptr< Context > Ctx
LLVM_ABI std::optional< size_t > getDataSize() const
Return the number of ProfileData elements.
static LLVM_ABI llvm::Expected< std::unique_ptr< InstrProfCorrelator > > get(StringRef Filename, ProfCorrelatorKind FileKind, const object::BuildIDFetcher *BIDFetcher=nullptr, const ArrayRef< llvm::object::BuildID > BIs={})
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
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.
Definition StringRef.h:55
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition StringRef.h:730
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition StringRef.h:258
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
static LLVM_ABI raw_ostream & warning()
Convenience method for printing "warning: " to stderr.
Definition WithColor.cpp:85
BuildIDFetcher searches local cache directories for debug info.
Definition BuildID.h:40
virtual std::optional< std::string > fetch(BuildIDRef BuildID) const
Returns the path to the debug file with the given build ID.
Definition BuildID.cpp:82
static Expected< std::vector< std::string > > findDsymObjectMembers(StringRef Path)
If the input path is a .dSYM bundle (as created by the dsymutil tool), return the paths to the object...
This class is the base class for all object file types.
Definition ObjectFile.h:231
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
void mapOptional(StringRef Key, T &Val)
Definition YAMLTraits.h:799
void mapRequired(StringRef Key, T &Val)
Definition YAMLTraits.h:789
The Output class is used to generate a yaml document from in-memory structs and vectors.
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
uint64_t ComputeHash(StringRef K)
Definition InstrProf.h:1187
std::optional< uint64_t > toAddress(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an address.
LLVM_ABI Expected< std::unique_ptr< Binary > > createBinary(MemoryBufferRef Source, LLVMContext *Context=nullptr, bool InitContent=true)
Create a Binary from Source, autodetecting the file type.
Definition Binary.cpp:45
constexpr bool IsLittleEndianHost
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
@ Offset
Definition DWP.cpp:532
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
FunctionAddr NumCounters
Definition InstrProf.h:91
LLVM_ABI std::string getInstrProfSectionName(InstrProfSectKind IPSK, Triple::ObjectFormatType OF, bool AddSegmentInfo=true)
Return the name of the profile section corresponding to IPSK.
InstrProfSectKind
Definition InstrProf.h:91
StringRef getInstrProfCountersVarPrefix()
Return the name prefix of profile counter variables.
Definition InstrProf.h:132
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition Format.h:129
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
Definition Error.h:340
FunctionAddr VTableAddr uintptr_t uintptr_t Data
Definition InstrProf.h:189
DWARFExpression::Operation Op
Expected< T > errorOrToExpected(ErrorOr< T > &&EO)
Convert an ErrorOr<T> to an Expected<T>.
Definition Error.h:1245
LLVM_ABI Error collectGlobalObjectNameStrings(ArrayRef< std::string > NameStrs, bool doCompression, std::string &Result)
Given a vector of strings (names of global objects like functions or, virtual tables) NameStrs,...
void toHex(ArrayRef< uint8_t > Input, bool LowerCase, SmallVectorImpl< char > &Output)
Convert buffer Input to its hexadecimal representation. The returned string is double the size of Inp...
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1917
void consumeError(Error Err)
Consume a Error without doing anything.
Definition Error.h:1083
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:870
#define N
std::unique_ptr< MemoryBuffer > Buffer
static LLVM_ABI llvm::Expected< std::unique_ptr< Context > > get(std::unique_ptr< MemoryBuffer > Buffer, object::ObjectFile &Obj, ProfCorrelatorKind FileKind)
This class should be specialized by any type that needs to be converted to/from a YAML mapping.
Definition YAMLTraits.h:62
This class should be specialized by any type for which vectors of that type need to be converted to/f...
Definition YAMLTraits.h:257
static void mapping(yaml::IO &io, InstrProfCorrelator::CorrelationData &Data)
static void mapping(yaml::IO &io, InstrProfCorrelator::Probe &P)