LLVM  14.0.0git
PerfJITEventListener.cpp
Go to the documentation of this file.
1 //===-- PerfJITEventListener.cpp - Tell Linux's perf about JITted code ----===//
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 //
9 // This file defines a JITEventListener object that tells perf about JITted
10 // functions, including source line information.
11 //
12 // Documentation for perf jit integration is available at:
13 // https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/tools/perf/Documentation/jitdump-specification.txt
14 // https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/tools/perf/Documentation/jit-interface.txt
15 //
16 //===----------------------------------------------------------------------===//
17 
18 #include "llvm/ADT/Twine.h"
19 #include "llvm/Config/config.h"
22 #include "llvm/Object/ObjectFile.h"
23 #include "llvm/Object/SymbolSize.h"
24 #include "llvm/Support/Debug.h"
25 #include "llvm/Support/Errno.h"
29 #include "llvm/Support/Mutex.h"
30 #include "llvm/Support/Path.h"
31 #include "llvm/Support/Process.h"
32 #include "llvm/Support/Threading.h"
34 #include <mutex>
35 
36 #include <sys/mman.h> // mmap()
37 #include <time.h> // clock_gettime(), time(), localtime_r() */
38 #include <unistd.h> // for read(), close()
39 
40 using namespace llvm;
41 using namespace llvm::object;
43 
44 namespace {
45 
46 // language identifier (XXX: should we generate something better from debug
47 // info?)
48 #define JIT_LANG "llvm-IR"
49 #define LLVM_PERF_JIT_MAGIC \
50  ((uint32_t)'J' << 24 | (uint32_t)'i' << 16 | (uint32_t)'T' << 8 | \
51  (uint32_t)'D')
52 #define LLVM_PERF_JIT_VERSION 1
53 
54 // bit 0: set if the jitdump file is using an architecture-specific timestamp
55 // clock source
56 #define JITDUMP_FLAGS_ARCH_TIMESTAMP (1ULL << 0)
57 
58 struct LLVMPerfJitHeader;
59 
60 class PerfJITEventListener : public JITEventListener {
61 public:
62  PerfJITEventListener();
63  ~PerfJITEventListener() {
64  if (MarkerAddr)
65  CloseMarker();
66  }
67 
68  void notifyObjectLoaded(ObjectKey K, const ObjectFile &Obj,
69  const RuntimeDyld::LoadedObjectInfo &L) override;
70  void notifyFreeingObject(ObjectKey K) override;
71 
72 private:
73  bool InitDebuggingDir();
74  bool OpenMarker();
75  void CloseMarker();
76  static bool FillMachine(LLVMPerfJitHeader &hdr);
77 
78  void NotifyCode(Expected<llvm::StringRef> &Symbol, uint64_t CodeAddr,
79  uint64_t CodeSize);
80  void NotifyDebug(uint64_t CodeAddr, DILineInfoTable Lines);
81 
82  // cache lookups
84 
85  // base directory for output data
86  std::string JitPath;
87 
88  // output data stream, closed via Dumpstream
89  int DumpFd = -1;
90 
91  // output data stream
92  std::unique_ptr<raw_fd_ostream> Dumpstream;
93 
94  // prevent concurrent dumps from messing up the output file
96 
97  // perf mmap marker
98  void *MarkerAddr = NULL;
99 
100  // perf support ready
101  bool SuccessfullyInitialized = false;
102 
103  // identifier for functions, primarily to identify when moving them around
104  uint64_t CodeGeneration = 1;
105 };
106 
107 // The following are POD struct definitions from the perf jit specification
108 
109 enum LLVMPerfJitRecordType {
110  JIT_CODE_LOAD = 0,
111  JIT_CODE_MOVE = 1, // not emitted, code isn't moved
112  JIT_CODE_DEBUG_INFO = 2,
113  JIT_CODE_CLOSE = 3, // not emitted, unnecessary
114  JIT_CODE_UNWINDING_INFO = 4, // not emitted
115 
116  JIT_CODE_MAX
117 };
118 
119 struct LLVMPerfJitHeader {
120  uint32_t Magic; // characters "JiTD"
121  uint32_t Version; // header version
122  uint32_t TotalSize; // total size of header
123  uint32_t ElfMach; // elf mach target
124  uint32_t Pad1; // reserved
125  uint32_t Pid;
126  uint64_t Timestamp; // timestamp
127  uint64_t Flags; // flags
128 };
129 
130 // record prefix (mandatory in each record)
131 struct LLVMPerfJitRecordPrefix {
132  uint32_t Id; // record type identifier
133  uint32_t TotalSize;
135 };
136 
137 struct LLVMPerfJitRecordCodeLoad {
138  LLVMPerfJitRecordPrefix Prefix;
139 
140  uint32_t Pid;
141  uint32_t Tid;
142  uint64_t Vma;
143  uint64_t CodeAddr;
144  uint64_t CodeSize;
145  uint64_t CodeIndex;
146 };
147 
148 struct LLVMPerfJitDebugEntry {
149  uint64_t Addr;
150  int Lineno; // source line number starting at 1
151  int Discrim; // column discriminator, 0 is default
152  // followed by null terminated filename, \xff\0 if same as previous entry
153 };
154 
155 struct LLVMPerfJitRecordDebugInfo {
156  LLVMPerfJitRecordPrefix Prefix;
157 
158  uint64_t CodeAddr;
159  uint64_t NrEntry;
160  // followed by NrEntry LLVMPerfJitDebugEntry records
161 };
162 
163 static inline uint64_t timespec_to_ns(const struct timespec *ts) {
164  const uint64_t NanoSecPerSec = 1000000000;
165  return ((uint64_t)ts->tv_sec * NanoSecPerSec) + ts->tv_nsec;
166 }
167 
168 static inline uint64_t perf_get_timestamp(void) {
169  struct timespec ts;
170  int ret;
171 
172  ret = clock_gettime(CLOCK_MONOTONIC, &ts);
173  if (ret)
174  return 0;
175 
176  return timespec_to_ns(&ts);
177 }
178 
179 PerfJITEventListener::PerfJITEventListener()
180  : Pid(sys::Process::getProcessId()) {
181  // check if clock-source is supported
182  if (!perf_get_timestamp()) {
183  errs() << "kernel does not support CLOCK_MONOTONIC\n";
184  return;
185  }
186 
187  if (!InitDebuggingDir()) {
188  errs() << "could not initialize debugging directory\n";
189  return;
190  }
191 
192  std::string Filename;
193  raw_string_ostream FilenameBuf(Filename);
194  FilenameBuf << JitPath << "/jit-" << Pid << ".dump";
195 
196  // Need to open ourselves, because we need to hand the FD to OpenMarker() and
197  // raw_fd_ostream doesn't expose the FD.
199  if (auto EC =
200  openFileForReadWrite(FilenameBuf.str(), DumpFd,
202  errs() << "could not open JIT dump file " << FilenameBuf.str() << ": "
203  << EC.message() << "\n";
204  return;
205  }
206 
207  Dumpstream = std::make_unique<raw_fd_ostream>(DumpFd, true);
208 
209  LLVMPerfJitHeader Header = {0};
210  if (!FillMachine(Header))
211  return;
212 
213  // signal this process emits JIT information
214  if (!OpenMarker())
215  return;
216 
217  // emit dumpstream header
218  Header.Magic = LLVM_PERF_JIT_MAGIC;
219  Header.Version = LLVM_PERF_JIT_VERSION;
220  Header.TotalSize = sizeof(Header);
221  Header.Pid = Pid;
222  Header.Timestamp = perf_get_timestamp();
223  Dumpstream->write(reinterpret_cast<const char *>(&Header), sizeof(Header));
224 
225  // Everything initialized, can do profiling now.
226  if (!Dumpstream->has_error())
227  SuccessfullyInitialized = true;
228 }
229 
230 void PerfJITEventListener::notifyObjectLoaded(
231  ObjectKey K, const ObjectFile &Obj,
233 
234  if (!SuccessfullyInitialized)
235  return;
236 
237  OwningBinary<ObjectFile> DebugObjOwner = L.getObjectForDebug(Obj);
238  const ObjectFile &DebugObj = *DebugObjOwner.getBinary();
239 
240  // Get the address of the object image for use as a unique identifier
241  std::unique_ptr<DIContext> Context = DWARFContext::create(DebugObj);
242 
243  // Use symbol info to iterate over functions in the object.
244  for (const std::pair<SymbolRef, uint64_t> &P : computeSymbolSizes(DebugObj)) {
245  SymbolRef Sym = P.first;
246  std::string SourceFileName;
247 
248  Expected<SymbolRef::Type> SymTypeOrErr = Sym.getType();
249  if (!SymTypeOrErr) {
250  // There's not much we can with errors here
251  consumeError(SymTypeOrErr.takeError());
252  continue;
253  }
254  SymbolRef::Type SymType = *SymTypeOrErr;
255  if (SymType != SymbolRef::ST_Function)
256  continue;
257 
259  if (!Name) {
260  consumeError(Name.takeError());
261  continue;
262  }
263 
264  Expected<uint64_t> AddrOrErr = Sym.getAddress();
265  if (!AddrOrErr) {
266  consumeError(AddrOrErr.takeError());
267  continue;
268  }
269  uint64_t Size = P.second;
271  Address.Address = *AddrOrErr;
272 
273  uint64_t SectionIndex = object::SectionedAddress::UndefSection;
274  if (auto SectOrErr = Sym.getSection())
275  if (*SectOrErr != Obj.section_end())
276  SectionIndex = SectOrErr.get()->getIndex();
277 
278  // According to spec debugging info has to come before loading the
279  // corresonding code load.
280  DILineInfoTable Lines = Context->getLineInfoForAddressRange(
281  {*AddrOrErr, SectionIndex}, Size, FileLineInfoKind::AbsoluteFilePath);
282 
283  NotifyDebug(*AddrOrErr, Lines);
284  NotifyCode(Name, *AddrOrErr, Size);
285  }
286 
287  // avoid races with writes
288  std::lock_guard<sys::Mutex> Guard(Mutex);
289 
290  Dumpstream->flush();
291 }
292 
293 void PerfJITEventListener::notifyFreeingObject(ObjectKey K) {
294  // perf currently doesn't have an interface for unloading. But munmap()ing the
295  // code section does, so that's ok.
296 }
297 
298 bool PerfJITEventListener::InitDebuggingDir() {
299  time_t Time;
300  struct tm LocalTime;
301  char TimeBuffer[sizeof("YYYYMMDD")];
302  SmallString<64> Path;
303 
304  // search for location to dump data to
305  if (const char *BaseDir = getenv("JITDUMPDIR"))
306  Path.append(BaseDir);
307  else if (!sys::path::home_directory(Path))
308  Path = ".";
309 
310  // create debug directory
311  Path += "/.debug/jit/";
312  if (auto EC = sys::fs::create_directories(Path)) {
313  errs() << "could not create jit cache directory " << Path << ": "
314  << EC.message() << "\n";
315  return false;
316  }
317 
318  // create unique directory for dump data related to this process
319  time(&Time);
320  localtime_r(&Time, &LocalTime);
321  strftime(TimeBuffer, sizeof(TimeBuffer), "%Y%m%d", &LocalTime);
322  Path += JIT_LANG "-jit-";
323  Path += TimeBuffer;
324 
325  SmallString<128> UniqueDebugDir;
326 
328  if (auto EC = createUniqueDirectory(Path, UniqueDebugDir)) {
329  errs() << "could not create unique jit cache directory " << UniqueDebugDir
330  << ": " << EC.message() << "\n";
331  return false;
332  }
333 
334  JitPath = std::string(UniqueDebugDir.str());
335 
336  return true;
337 }
338 
339 bool PerfJITEventListener::OpenMarker() {
340  // We mmap the jitdump to create an MMAP RECORD in perf.data file. The mmap
341  // is captured either live (perf record running when we mmap) or in deferred
342  // mode, via /proc/PID/maps. The MMAP record is used as a marker of a jitdump
343  // file for more meta data info about the jitted code. Perf report/annotate
344  // detect this special filename and process the jitdump file.
345  //
346  // Mapping must be PROT_EXEC to ensure it is captured by perf record
347  // even when not using -d option.
348  MarkerAddr = ::mmap(NULL, sys::Process::getPageSizeEstimate(),
349  PROT_READ | PROT_EXEC, MAP_PRIVATE, DumpFd, 0);
350 
351  if (MarkerAddr == MAP_FAILED) {
352  errs() << "could not mmap JIT marker\n";
353  return false;
354  }
355  return true;
356 }
357 
358 void PerfJITEventListener::CloseMarker() {
359  if (!MarkerAddr)
360  return;
361 
362  munmap(MarkerAddr, sys::Process::getPageSizeEstimate());
363  MarkerAddr = nullptr;
364 }
365 
366 bool PerfJITEventListener::FillMachine(LLVMPerfJitHeader &hdr) {
367  char id[16];
368  struct {
369  uint16_t e_type;
370  uint16_t e_machine;
371  } info;
372 
373  size_t RequiredMemory = sizeof(id) + sizeof(info);
374 
376  MemoryBuffer::getFileSlice("/proc/self/exe",
377  RequiredMemory,
378  0);
379 
380  // This'll not guarantee that enough data was actually read from the
381  // underlying file. Instead the trailing part of the buffer would be
382  // zeroed. Given the ELF signature check below that seems ok though,
383  // it's unlikely that the file ends just after that, and the
384  // consequence would just be that perf wouldn't recognize the
385  // signature.
386  if (auto EC = MB.getError()) {
387  errs() << "could not open /proc/self/exe: " << EC.message() << "\n";
388  return false;
389  }
390 
391  memcpy(&id, (*MB)->getBufferStart(), sizeof(id));
392  memcpy(&info, (*MB)->getBufferStart() + sizeof(id), sizeof(info));
393 
394  // check ELF signature
395  if (id[0] != 0x7f || id[1] != 'E' || id[2] != 'L' || id[3] != 'F') {
396  errs() << "invalid elf signature\n";
397  return false;
398  }
399 
400  hdr.ElfMach = info.e_machine;
401 
402  return true;
403 }
404 
405 void PerfJITEventListener::NotifyCode(Expected<llvm::StringRef> &Symbol,
406  uint64_t CodeAddr, uint64_t CodeSize) {
407  assert(SuccessfullyInitialized);
408 
409  // 0 length functions can't have samples.
410  if (CodeSize == 0)
411  return;
412 
413  LLVMPerfJitRecordCodeLoad rec;
414  rec.Prefix.Id = JIT_CODE_LOAD;
415  rec.Prefix.TotalSize = sizeof(rec) + // debug record itself
416  Symbol->size() + 1 + // symbol name
417  CodeSize; // and code
418  rec.Prefix.Timestamp = perf_get_timestamp();
419 
420  rec.CodeSize = CodeSize;
421  rec.Vma = 0;
422  rec.CodeAddr = CodeAddr;
423  rec.Pid = Pid;
424  rec.Tid = get_threadid();
425 
426  // avoid interspersing output
427  std::lock_guard<sys::Mutex> Guard(Mutex);
428 
429  rec.CodeIndex = CodeGeneration++; // under lock!
430 
431  Dumpstream->write(reinterpret_cast<const char *>(&rec), sizeof(rec));
432  Dumpstream->write(Symbol->data(), Symbol->size() + 1);
433  Dumpstream->write(reinterpret_cast<const char *>(CodeAddr), CodeSize);
434 }
435 
436 void PerfJITEventListener::NotifyDebug(uint64_t CodeAddr,
437  DILineInfoTable Lines) {
438  assert(SuccessfullyInitialized);
439 
440  // Didn't get useful debug info.
441  if (Lines.empty())
442  return;
443 
444  LLVMPerfJitRecordDebugInfo rec;
445  rec.Prefix.Id = JIT_CODE_DEBUG_INFO;
446  rec.Prefix.TotalSize = sizeof(rec); // will be increased further
447  rec.Prefix.Timestamp = perf_get_timestamp();
448  rec.CodeAddr = CodeAddr;
449  rec.NrEntry = Lines.size();
450 
451  // compute total size size of record (variable due to filenames)
452  DILineInfoTable::iterator Begin = Lines.begin();
453  DILineInfoTable::iterator End = Lines.end();
454  for (DILineInfoTable::iterator It = Begin; It != End; ++It) {
455  DILineInfo &line = It->second;
456  rec.Prefix.TotalSize += sizeof(LLVMPerfJitDebugEntry);
457  rec.Prefix.TotalSize += line.FileName.size() + 1;
458  }
459 
460  // The debug_entry describes the source line information. It is defined as
461  // follows in order:
462  // * uint64_t code_addr: address of function for which the debug information
463  // is generated
464  // * uint32_t line : source file line number (starting at 1)
465  // * uint32_t discrim : column discriminator, 0 is default
466  // * char name[n] : source file name in ASCII, including null termination
467 
468  // avoid interspersing output
469  std::lock_guard<sys::Mutex> Guard(Mutex);
470 
471  Dumpstream->write(reinterpret_cast<const char *>(&rec), sizeof(rec));
472 
473  for (DILineInfoTable::iterator It = Begin; It != End; ++It) {
474  LLVMPerfJitDebugEntry LineInfo;
475  DILineInfo &Line = It->second;
476 
477  LineInfo.Addr = It->first;
478  // The function re-created by perf is preceded by a elf
479  // header. Need to adjust for that, otherwise the results are
480  // wrong.
481  LineInfo.Addr += 0x40;
482  LineInfo.Lineno = Line.Line;
483  LineInfo.Discrim = Line.Discriminator;
484 
485  Dumpstream->write(reinterpret_cast<const char *>(&LineInfo),
486  sizeof(LineInfo));
487  Dumpstream->write(Line.FileName.c_str(), Line.FileName.size() + 1);
488  }
489 }
490 
491 // There should be only a single event listener per process, otherwise perf gets
492 // confused.
494 
495 } // end anonymous namespace
496 
497 namespace llvm {
499  return &*PerfListener;
500 }
501 
502 } // namespace llvm
503 
505 {
506  return wrap(JITEventListener::createPerfJITEventListener());
507 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
MemoryBuffer.h
llvm::sys::fs::openFileForWrite
std::error_code openFileForWrite(const Twine &Name, int &ResultFD, CreationDisposition Disp=CD_CreateAlways, OpenFlags Flags=OF_None, unsigned Mode=0666)
Opens the file with the given name in a write-only or read-write mode, returning its open file descri...
Definition: FileSystem.h:1065
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:22
llvm::sys::path::home_directory
bool home_directory(SmallVectorImpl< char > &result)
Get the user's home directory.
FileSystem.h
llvm::sys::fs::OF_None
@ OF_None
Definition: FileSystem.h:757
FileLineInfoKind
DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind
Definition: PerfJITEventListener.cpp:42
llvm::cl::Prefix
@ Prefix
Definition: CommandLine.h:164
llvm::codeview::DebugSubsectionKind::Lines
@ Lines
llvm::RuntimeDyld::LoadedObjectInfo::getObjectForDebug
virtual object::OwningBinary< object::ObjectFile > getObjectForDebug(const object::ObjectFile &Obj) const =0
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
llvm::raw_string_ostream
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:632
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1175
Path.h
Timestamp
uint64_t Timestamp
Definition: Profile.cpp:320
ManagedStatic.h
llvm::object::OwningBinary::getBinary
T * getBinary()
Definition: Binary.h:227
DWARFContext.h
SymbolSize.h
ret
to esp esp setne al movzbw ax esp setg cl movzbw cx cmove cx cl jne LBB1_2 esp ret(also really horrible code on ppc). This is due to the expand code for 64-bit compares. GCC produces multiple branches
llvm::sys::Process::Pid
int32_t Pid
Definition: Process.h:46
llvm::errs
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Definition: raw_ostream.cpp:893
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:42
LLVM_PERF_JIT_MAGIC
#define LLVM_PERF_JIT_MAGIC
Definition: PerfJITEventListener.cpp:49
llvm::consumeError
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:1043
Context
ManagedStatic< detail::RecordContext > Context
Definition: Record.cpp:96
llvm::sys::Process
A collection of legacy interfaces for querying information about the current executing process.
Definition: Process.h:44
Process.h
llvm::object
Definition: ObjectFileTransformer.h:18
llvm::object::ObjectFile::section_end
virtual section_iterator section_end() const =0
Twine.h
llvm::get_threadid
uint64_t get_threadid()
Return the current thread id, as used in various OS system calls.
llvm::sys::fs::createUniqueDirectory
std::error_code createUniqueDirectory(const Twine &Prefix, SmallVectorImpl< char > &ResultPath)
Definition: Path.cpp:882
llvm::ManagedStatic
ManagedStatic - This transparently changes the behavior of global statics to be lazily constructed on...
Definition: ManagedStatic.h:83
llvm::ErrorOr::getError
std::error_code getError() const
Definition: ErrorOr.h:153
llvm::sys::fs::create_directories
std::error_code create_directories(const Twine &path, bool IgnoreExisting=true, perms Perms=owner_all|group_all)
Create all the non-existent directories in path.
Definition: Path.cpp:964
llvm::sys::SmartMutex< false >
llvm::sys::fs::openFileForReadWrite
std::error_code openFileForReadWrite(const Twine &Name, int &ResultFD, CreationDisposition Disp, OpenFlags Flags, unsigned Mode=0666)
Opens the file with the given name in a write-only or read-write mode, returning its open file descri...
Definition: FileSystem.h:1106
llvm::SmallString< 64 >
LLVMCreatePerfJITEventListener
LLVMJITEventListenerRef LLVMCreatePerfJITEventListener(void)
Definition: PerfJITEventListener.cpp:504
llvm::SmallString::append
void append(StringRef RHS)
Append from a StringRef.
Definition: SmallString.h:67
llvm::DILineInfo::Line
uint32_t Line
Definition: DIContext.h:40
llvm::object::SymbolRef::getSection
Expected< section_iterator > getSection() const
Get section this symbol is defined in reference to.
Definition: ObjectFile.h:408
Threading.h
uint64_t
Addr
uint64_t Addr
Definition: ELFObjHandler.cpp:79
llvm::DILineInfo
A format-neutral container for source line information.
Definition: DIContext.h:31
llvm::DILineInfoSpecifier::FileLineInfoKind
FileLineInfoKind
Definition: DIContext.h:136
llvm::HighlightColor::Address
@ Address
JIT_LANG
#define JIT_LANG
Definition: PerfJITEventListener.cpp:48
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ObjectFile.h
memcpy
<%struct.s * > cast struct s *S to sbyte *< sbyte * > sbyte uint cast struct s *agg result to sbyte *< sbyte * > sbyte uint cast struct s *memtmp to sbyte *< sbyte * > sbyte uint ret void llc ends up issuing two memcpy or custom lower memcpy(of small size) to be ldmia/stmia. I think option 2 is better but the current register allocator cannot allocate a chunk of registers at a time. A feasible temporary solution is to use specific physical registers at the lowering time for small(<
llvm::codeview::CompileSym2Flags::EC
@ EC
llvm::DILineInfo::Discriminator
uint32_t Discriminator
Definition: DIContext.h:46
info
lazy value info
Definition: LazyValueInfo.cpp:59
llvm::JITEventListener
JITEventListener - Abstract interface for use by the JIT to notify clients about significant events d...
Definition: JITEventListener.h:40
llvm::wrap
LLVMAttributeRef wrap(Attribute Attr)
Definition: Attributes.h:255
llvm::object::ObjectFile
This class is the base class for all object file types.
Definition: ObjectFile.h:227
llvm::msf::Magic
static const char Magic[]
Definition: MSFCommon.h:23
uint32_t
Mutex.h
llvm::sys::Mutex
SmartMutex< false > Mutex
Mutex - A standard, always enforced mutex.
Definition: Mutex.h:68
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
llvm::object::SymbolRef::Type
Type
Definition: ObjectFile.h:170
uint16_t
llvm::object::OwningBinary
Definition: RuntimeDyld.h:36
llvm::RuntimeDyld::LoadedObjectInfo
Information about the loaded object.
Definition: RuntimeDyld.h:69
llvm::JITEventListener::createPerfJITEventListener
static JITEventListener * createPerfJITEventListener()
Definition: JITEventListener.h:101
LLVM_PERF_JIT_VERSION
#define LLVM_PERF_JIT_VERSION
Definition: PerfJITEventListener.cpp:52
llvm::SmallString::str
StringRef str() const
Explicit conversion to StringRef.
Definition: SmallString.h:259
llvm::ARMBuildAttrs::Symbol
@ Symbol
Definition: ARMBuildAttributes.h:83
llvm::object::computeSymbolSizes
std::vector< std::pair< SymbolRef, uint64_t > > computeSymbolSizes(const ObjectFile &O)
Definition: SymbolSize.cpp:50
llvm::Expected::takeError
Error takeError()
Take ownership of the stored error.
Definition: Error.h:597
llvm::DILineInfo::FileName
std::string FileName
Definition: DIContext.h:36
Version
uint64_t Version
Definition: RawMemProfReader.cpp:25
llvm::object::SymbolRef::getType
Expected< SymbolRef::Type > getType() const
Definition: ObjectFile.h:412
llvm::SmallVectorImpl::iterator
typename SuperClass::iterator iterator
Definition: SmallVector.h:556
llvm::ErrorOr
Represents either an error or a value T.
Definition: ErrorOr.h:56
llvm::object::SectionedAddress
Definition: ObjectFile.h:143
llvm::object::SymbolRef
This is a value type class that represents a single symbol in the list of symbols in the object file.
Definition: ObjectFile.h:166
llvm::sys::fs::CD_CreateNew
@ CD_CreateNew
CD_CreateNew - When opening a file:
Definition: FileSystem.h:738
raw_ostream.h
llvm::object::SymbolRef::getName
Expected< StringRef > getName() const
Definition: ObjectFile.h:388
llvm::AMDGPU::VGPRIndexMode::Id
Id
Definition: SIDefines.h:232
LLVMJITEventListenerRef
struct LLVMOpaqueJITEventListener * LLVMJITEventListenerRef
Definition: Types.h:163
Errno.h
llvm::object::SymbolRef::getAddress
Expected< uint64_t > getAddress() const
Returns the symbol virtual address (i.e.
Definition: ObjectFile.h:392
Debug.h
JITEventListener.h