LLVM 22.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,
57 const object::ObjectFile &Obj,
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 if (FileKind == InstrProfCorrelator::BINARY) {
64 auto DataSection = getInstrProfSection(Obj, IPSK_covdata);
65 if (auto Err = DataSection.takeError())
66 return std::move(Err);
67 auto DataOrErr = DataSection->getContents();
68 if (!DataOrErr)
69 return DataOrErr.takeError();
70 auto NameSection = getInstrProfSection(Obj, IPSK_covname);
71 if (auto Err = NameSection.takeError())
72 return std::move(Err);
73 auto NameOrErr = NameSection->getContents();
74 if (!NameOrErr)
75 return NameOrErr.takeError();
76 C->DataStart = DataOrErr->data();
77 C->DataEnd = DataOrErr->data() + DataOrErr->size();
78 C->NameStart = NameOrErr->data();
79 C->NameSize = NameOrErr->size();
80 }
81 C->Buffer = std::move(Buffer);
82 C->CountersSectionStart = CountersSection->getAddress();
83 C->CountersSectionEnd = C->CountersSectionStart + CountersSection->getSize();
84 // In COFF object file, there's a null byte at the beginning of the counter
85 // section which doesn't exist in raw profile.
86 if (Obj.getTripleObjectFormat() == Triple::COFF)
87 ++C->CountersSectionStart;
88
89 C->ShouldSwapBytes = Obj.isLittleEndian() != sys::IsLittleEndianHost;
90 return Expected<std::unique_ptr<Context>>(std::move(C));
91}
92
95 const object::BuildIDFetcher *BIDFetcher,
96 const ArrayRef<object::BuildID> BIs) {
97 std::optional<std::string> Path;
98 if (BIDFetcher) {
99 if (BIs.empty())
102 "unsupported profile binary correlation when there is no build ID "
103 "in a profile");
104 if (BIs.size() > 1)
107 "unsupported profile binary correlation when there are multiple "
108 "build IDs in a profile");
109
110 Path = BIDFetcher->fetch(BIs.front());
111 if (!Path)
114 "Missing build ID: " + llvm::toHex(BIs.front(),
115 /*LowerCase=*/true));
116 Filename = *Path;
117 }
118
119 if (FileKind == DEBUG_INFO) {
120 auto DsymObjectsOrErr =
122 if (auto Err = DsymObjectsOrErr.takeError())
123 return std::move(Err);
124 if (!DsymObjectsOrErr->empty()) {
125 // TODO: Enable profile correlation when there are multiple objects in a
126 // dSYM bundle.
127 if (DsymObjectsOrErr->size() > 1)
130 "using multiple objects is not yet supported");
131 Filename = *DsymObjectsOrErr->begin();
132 }
133 auto BufferOrErr = errorOrToExpected(MemoryBuffer::getFile(Filename));
134 if (auto Err = BufferOrErr.takeError())
135 return std::move(Err);
136
137 return get(std::move(*BufferOrErr), FileKind);
138 }
139 if (FileKind == BINARY) {
140 auto BufferOrErr = errorOrToExpected(MemoryBuffer::getFile(Filename));
141 if (auto Err = BufferOrErr.takeError())
142 return std::move(Err);
143
144 return get(std::move(*BufferOrErr), FileKind);
145 }
148 "unsupported correlation kind (only DWARF debug info and Binary format "
149 "(ELF/COFF) are supported)");
150}
151
153InstrProfCorrelator::get(std::unique_ptr<MemoryBuffer> Buffer,
154 ProfCorrelatorKind FileKind) {
155 auto BinOrErr = object::createBinary(*Buffer);
156 if (auto Err = BinOrErr.takeError())
157 return std::move(Err);
158
159 if (auto *Obj = dyn_cast<object::ObjectFile>(BinOrErr->get())) {
160 auto CtxOrErr = Context::get(std::move(Buffer), *Obj, FileKind);
161 if (auto Err = CtxOrErr.takeError())
162 return std::move(Err);
163 auto T = Obj->makeTriple();
164 if (T.isArch64Bit())
165 return InstrProfCorrelatorImpl<uint64_t>::get(std::move(*CtxOrErr), *Obj,
166 FileKind);
167 if (T.isArch32Bit())
168 return InstrProfCorrelatorImpl<uint32_t>::get(std::move(*CtxOrErr), *Obj,
169 FileKind);
170 }
173}
174
175std::optional<size_t> InstrProfCorrelator::getDataSize() const {
177 return C->getDataSize();
179 return C->getDataSize();
180 return {};
181}
182
183namespace llvm {
184
185template <>
190template <>
195template <>
199template <>
203
204} // end namespace llvm
205
206template <class IntPtrT>
209 std::unique_ptr<InstrProfCorrelator::Context> Ctx,
210 const object::ObjectFile &Obj, ProfCorrelatorKind FileKind) {
211 if (FileKind == DEBUG_INFO) {
212 if (Obj.isELF() || Obj.isMachO()) {
213 auto DICtx = DWARFContext::create(Obj);
214 return std::make_unique<DwarfInstrProfCorrelator<IntPtrT>>(
215 std::move(DICtx), std::move(Ctx));
216 }
219 "unsupported debug info format (only DWARF is supported)");
220 }
221 if (Obj.isELF() || Obj.isCOFF())
222 return std::make_unique<BinaryInstrProfCorrelator<IntPtrT>>(std::move(Ctx));
225 "unsupported binary format (only ELF and COFF are supported)");
226}
227
228template <class IntPtrT>
230 assert(Data.empty() && Names.empty() && NamesVec.empty());
231 correlateProfileDataImpl(MaxWarnings);
232 if (this->Data.empty())
235 "could not find any profile data metadata in correlated file");
237 this->CounterOffsets.clear();
238 this->NamesVec.clear();
239 return Result;
240}
241
242template <> struct yaml::MappingTraits<InstrProfCorrelator::CorrelationData> {
243 static void mapping(yaml::IO &io,
245 io.mapRequired("Probes", Data.Probes);
246 }
247};
248
249template <> struct yaml::MappingTraits<InstrProfCorrelator::Probe> {
251 io.mapRequired("Function Name", P.FunctionName);
252 io.mapOptional("Linkage Name", P.LinkageName);
253 io.mapRequired("CFG Hash", P.CFGHash);
254 io.mapRequired("Counter Offset", P.CounterOffset);
255 io.mapRequired("Num Counters", P.NumCounters);
256 io.mapOptional("File", P.FilePath);
257 io.mapOptional("Line", P.LineNumber);
258 }
259};
260
262 static const bool flow = false;
263};
264
265template <class IntPtrT>
267 raw_ostream &OS) {
269 correlateProfileDataImpl(MaxWarnings, &Data);
270 if (Data.Probes.empty())
273 "could not find any profile data metadata in debug info");
274 yaml::Output YamlOS(OS);
275 YamlOS << Data;
276 return Error::success();
277}
278
279template <class IntPtrT>
281 uint64_t CFGHash,
282 IntPtrT CounterOffset,
283 IntPtrT FunctionPtr,
285 // Check if a probe was already added for this counter offset.
286 if (!CounterOffsets.insert(CounterOffset).second)
287 return;
288 Data.push_back({
289 maybeSwap<uint64_t>(NameRef),
290 maybeSwap<uint64_t>(CFGHash),
291 // In this mode, CounterPtr actually stores the section relative address
292 // of the counter.
293 maybeSwap<IntPtrT>(CounterOffset),
294 // TODO: MC/DC is not yet supported.
295 /*BitmapOffset=*/maybeSwap<IntPtrT>(0),
296 maybeSwap<IntPtrT>(FunctionPtr),
297 // TODO: Value profiling is not yet supported.
298 /*ValuesPtr=*/maybeSwap<IntPtrT>(0),
300 /*NumValueSites=*/{maybeSwap<uint16_t>(0), maybeSwap<uint16_t>(0)},
301 // TODO: MC/DC is not yet supported.
302 /*NumBitmapBytes=*/maybeSwap<uint32_t>(0),
303 });
304}
305
306template <class IntPtrT>
307std::optional<uint64_t>
308DwarfInstrProfCorrelator<IntPtrT>::getLocation(const DWARFDie &Die) const {
309 auto Locations = Die.getLocations(dwarf::DW_AT_location);
310 if (!Locations) {
311 consumeError(Locations.takeError());
312 return {};
313 }
314 auto &DU = *Die.getDwarfUnit();
315 auto AddressSize = DU.getAddressByteSize();
316 for (auto &Location : *Locations) {
317 DataExtractor Data(Location.Expr, DICtx->isLittleEndian(), AddressSize);
318 DWARFExpression Expr(Data, AddressSize);
319 for (auto &Op : Expr) {
320 if (Op.getCode() == dwarf::DW_OP_addr)
321 return Op.getRawOperand(0);
322 if (Op.getCode() == dwarf::DW_OP_addrx) {
323 uint64_t Index = Op.getRawOperand(0);
324 if (auto SA = DU.getAddrOffsetSectionItem(Index))
325 return SA->Address;
326 }
327 }
328 }
329 return {};
330}
331
332template <class IntPtrT>
333bool DwarfInstrProfCorrelator<IntPtrT>::isDIEOfProbe(const DWARFDie &Die) {
334 const auto &ParentDie = Die.getParent();
335 if (!Die.isValid() || !ParentDie.isValid() || Die.isNULL())
336 return false;
337 if (Die.getTag() != dwarf::DW_TAG_variable)
338 return false;
339 if (!ParentDie.isSubprogramDIE())
340 return false;
341 if (!Die.hasChildren())
342 return false;
343 if (const char *Name = Die.getName(DINameKind::ShortName))
345 return false;
346}
347
348template <class IntPtrT>
349void DwarfInstrProfCorrelator<IntPtrT>::correlateProfileDataImpl(
350 int MaxWarnings, InstrProfCorrelator::CorrelationData *Data) {
351 bool UnlimitedWarnings = (MaxWarnings == 0);
352 // -N suppressed warnings means we can emit up to N (unsuppressed) warnings
353 int NumSuppressedWarnings = -MaxWarnings;
354 auto MaybeAddProbe = [&](DWARFDie Die) {
355 if (!isDIEOfProbe(Die))
356 return;
357 std::optional<const char *> FunctionName;
358 std::optional<uint64_t> CFGHash;
359 std::optional<uint64_t> CounterPtr = getLocation(Die);
360 auto FnDie = Die.getParent();
361 auto FunctionPtr = dwarf::toAddress(FnDie.find(dwarf::DW_AT_low_pc));
362 std::optional<uint64_t> NumCounters;
363 for (const DWARFDie &Child : Die.children()) {
364 if (Child.getTag() != dwarf::DW_TAG_LLVM_annotation)
365 continue;
366 auto AnnotationFormName = Child.find(dwarf::DW_AT_name);
367 auto AnnotationFormValue = Child.find(dwarf::DW_AT_const_value);
368 if (!AnnotationFormName || !AnnotationFormValue)
369 continue;
370 auto AnnotationNameOrErr = AnnotationFormName->getAsCString();
371 if (auto Err = AnnotationNameOrErr.takeError()) {
372 consumeError(std::move(Err));
373 continue;
374 }
375 StringRef AnnotationName = *AnnotationNameOrErr;
377 if (auto EC =
378 AnnotationFormValue->getAsCString().moveInto(FunctionName))
379 consumeError(std::move(EC));
380 } else if (AnnotationName == InstrProfCorrelator::CFGHashAttributeName) {
381 CFGHash = AnnotationFormValue->getAsUnsignedConstant();
382 } else if (AnnotationName ==
384 NumCounters = AnnotationFormValue->getAsUnsignedConstant();
385 }
386 }
387 // If there is no function and no counter, assume it was dead-stripped
388 if (!FunctionPtr && !CounterPtr)
389 return;
390 if (!FunctionName || !CFGHash || !CounterPtr || !NumCounters) {
391 if (UnlimitedWarnings || ++NumSuppressedWarnings < 1) {
393 << "Incomplete DIE for function " << FunctionName
394 << ": CFGHash=" << CFGHash << " CounterPtr=" << CounterPtr
395 << " NumCounters=" << NumCounters << "\n";
396 LLVM_DEBUG(Die.dump(dbgs()));
397 }
398 return;
399 }
400 uint64_t CountersStart = this->Ctx->CountersSectionStart;
401 uint64_t CountersEnd = this->Ctx->CountersSectionEnd;
402 if (*CounterPtr < CountersStart || *CounterPtr >= CountersEnd) {
403 if (UnlimitedWarnings || ++NumSuppressedWarnings < 1) {
405 << format("CounterPtr out of range for function %s: Actual=0x%x "
406 "Expected=[0x%x, 0x%x)\n",
407 *FunctionName, *CounterPtr, CountersStart, CountersEnd);
408 LLVM_DEBUG(Die.dump(dbgs()));
409 }
410 return;
411 }
412 if (!FunctionPtr && (UnlimitedWarnings || ++NumSuppressedWarnings < 1)) {
413 WithColor::warning() << format("Could not find address of function %s\n",
414 *FunctionName);
415 LLVM_DEBUG(Die.dump(dbgs()));
416 }
417 // In debug info correlation mode, the CounterPtr is an absolute address of
418 // the counter, but it's expected to be relative later when iterating Data.
419 IntPtrT CounterOffset = *CounterPtr - CountersStart;
420 if (Data) {
422 P.FunctionName = *FunctionName;
423 if (const char *Name = FnDie.getName(DINameKind::LinkageName))
424 P.LinkageName = Name;
425 P.CFGHash = *CFGHash;
426 P.CounterOffset = CounterOffset;
427 P.NumCounters = *NumCounters;
428 auto FilePath = FnDie.getDeclFile(
430 if (!FilePath.empty())
431 P.FilePath = FilePath;
432 if (auto LineNumber = FnDie.getDeclLine())
433 P.LineNumber = LineNumber;
434 Data->Probes.push_back(P);
435 } else {
436 this->addDataProbe(IndexedInstrProf::ComputeHash(*FunctionName), *CFGHash,
437 CounterOffset, FunctionPtr.value_or(0), *NumCounters);
438 this->NamesVec.push_back(*FunctionName);
439 }
440 };
441 for (auto &CU : DICtx->normal_units())
442 for (const auto &Entry : CU->dies())
443 MaybeAddProbe(DWARFDie(CU.get(), &Entry));
444 for (auto &CU : DICtx->dwo_units())
445 for (const auto &Entry : CU->dies())
446 MaybeAddProbe(DWARFDie(CU.get(), &Entry));
447
448 if (!UnlimitedWarnings && NumSuppressedWarnings > 0)
449 WithColor::warning() << format("Suppressed %d additional warnings\n",
450 NumSuppressedWarnings);
451}
452
453template <class IntPtrT>
454Error DwarfInstrProfCorrelator<IntPtrT>::correlateProfileNameImpl() {
455 if (this->NamesVec.empty()) {
458 "could not find any profile name metadata in debug info");
459 }
460 auto Result =
461 collectGlobalObjectNameStrings(this->NamesVec,
462 /*doCompression=*/false, this->Names);
463 return Result;
464}
465
466template <class IntPtrT>
467void BinaryInstrProfCorrelator<IntPtrT>::correlateProfileDataImpl(
468 int MaxWarnings, InstrProfCorrelator::CorrelationData *CorrelateData) {
469 using RawProfData = RawInstrProf::ProfileData<IntPtrT>;
470 bool UnlimitedWarnings = (MaxWarnings == 0);
471 // -N suppressed warnings means we can emit up to N (unsuppressed) warnings
472 int NumSuppressedWarnings = -MaxWarnings;
473
474 const RawProfData *DataStart = (const RawProfData *)this->Ctx->DataStart;
475 const RawProfData *DataEnd = (const RawProfData *)this->Ctx->DataEnd;
476 // We need to use < here because the last data record may have no padding.
477 for (const RawProfData *I = DataStart; I < DataEnd; ++I) {
478 uint64_t CounterPtr = this->template maybeSwap<IntPtrT>(I->CounterPtr);
479 uint64_t CountersStart = this->Ctx->CountersSectionStart;
480 uint64_t CountersEnd = this->Ctx->CountersSectionEnd;
481 if (CounterPtr < CountersStart || CounterPtr >= CountersEnd) {
482 if (UnlimitedWarnings || ++NumSuppressedWarnings < 1) {
484 << format("CounterPtr out of range for function: Actual=0x%x "
485 "Expected=[0x%x, 0x%x) at data offset=0x%x\n",
486 CounterPtr, CountersStart, CountersEnd,
487 (I - DataStart) * sizeof(RawProfData));
488 }
489 }
490 // In binary correlation mode, the CounterPtr is an absolute address of the
491 // counter, but it's expected to be relative later when iterating Data.
492 IntPtrT CounterOffset = CounterPtr - CountersStart;
493 this->addDataProbe(I->NameRef, I->FuncHash, CounterOffset,
494 I->FunctionPointer, I->NumCounters);
495 }
496}
497
498template <class IntPtrT>
499Error BinaryInstrProfCorrelator<IntPtrT>::correlateProfileNameImpl() {
500 if (this->Ctx->NameSize == 0) {
503 "could not find any profile data metadata in object file");
504 }
505 this->Names.append(this->Ctx->NameStart, this->Ctx->NameSize);
506 return Error::success();
507}
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
#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:724
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:530
dwarf::Tag getTag() const
Definition DWARFDie.h:73
LLVM_ABI Expected< DWARFLocationExpressionsVector > getLocations(dwarf::Attribute Attr) const
Definition DWARFDie.cpp:494
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:662
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,...
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition StringRef.h:261
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.
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:1867
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:867
#define N
std::unique_ptr< MemoryBuffer > Buffer
static LLVM_ABI llvm::Expected< std::unique_ptr< Context > > get(std::unique_ptr< MemoryBuffer > Buffer, const 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)