LLVM: lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
15#include "ittnotify.h"
19#include "llvm/Config/config.h"
33
34using namespace llvm;
36
37#define DEBUG_TYPE "amplifier-jit-event-listener"
38
39namespace {
40
41class IntelIttnotifyInfo {
43 std::vectorstd::string SectionNamesVector;
44 std::vector<__itt_section_info> SectionInfoVector;
45 __itt_module_object *ModuleObject;
47
48public:
50 : ModuleObject(NULL), WrapperRef(Wrapper){};
51 ~IntelIttnotifyInfo() { delete ModuleObject; };
52
53 void setModuleName(const char *Name) { ModuleName = std::string(Name); }
54
55 const char *getModuleName() { return ModuleName.c_str(); }
56
57 void setModuleObject(__itt_module_object *ModuleObj) {
58 ModuleObject = ModuleObj;
59 }
60
61 __itt_module_object *getModuleObject() { return ModuleObject; }
62
63 __itt_section_info *getSectionInfoVectorBegin() {
64 if (SectionInfoVector.size())
65 return &SectionInfoVector[0];
66 return NULL;
67 }
68
70 unsigned int SectionSize) {
72 }
73
74 int fillSectionInformation(const ObjectFile &Obj,
76
77 int SectionCounter = 0;
78
79 for (auto &Section : Obj.sections()) {
80 uint64_t SectionLoadAddr = L.getSectionLoadAddress(Section);
81 if (SectionLoadAddr) {
83
84 __itt_section_info SectionInfo;
85 memset(&SectionInfo, 0, sizeof(SectionInfo));
86 SectionInfo.start_addr = reinterpret_cast<void *>(SectionLoadAddr);
87 SectionInfo.file_offset = ElfSection.getOffset();
88 SectionInfo.flags = ElfSection.getFlags();
89
91 auto SectionNameOrError = ElfSection.getName();
92 if (SectionNameOrError)
94
95 SectionNamesVector.push_back(SectionName.str());
96 SectionInfo.size = ElfSection.getSize();
98 SectionInfo.size);
99
100 if (ElfSection.isBSS()) {
101 SectionInfo.type = itt_section_type_bss;
102 } else if (ElfSection.isData()) {
103 SectionInfo.type = itt_section_type_data;
104 } else if (ElfSection.isText()) {
105 SectionInfo.type = itt_section_type_text;
106 }
107 SectionInfoVector.push_back(SectionInfo);
108 ++SectionCounter;
109 }
110 }
111
112
113
114 for (int I = 0; I < SectionCounter; ++I) {
115 SectionInfoVector[I].name = SectionNamesVector[I].c_str();
116 }
117 return SectionCounter;
118 }
119};
120
123
124 std::unique_ptr Wrapper;
125 MethodIDMap MethodIDs;
126
129
130 ObjectMap LoadedObjectMap;
131 std::map<ObjectKey, OwningBinary> DebugObjects;
132
133 std::map<ObjectKey, std::unique_ptr> KeyToIttnotify;
134
135public:
137 Wrapper.reset(libraryWrapper);
138 }
139
140 ~IntelJITEventListener() {
141 }
142
143 void notifyObjectLoaded(ObjectKey Key, const ObjectFile &Obj,
145
146 void notifyFreeingObject(ObjectKey Key) override;
147};
148
149static LineNumberInfo DILineInfoToIntelJITFormat(uintptr_t StartAddress,
150 uintptr_t Address,
153
154 Result.Offset = Address - StartAddress;
155 Result.LineNumber = Line.Line;
156
157 return Result;
158}
159
162 const char* FnName,
163 uintptr_t FnStart,
164 size_t FnSize) {
167
168 Result.method_id = Wrapper.iJIT_GetNewMethodID();
169 Result.method_name = const_cast<char*>(FnName);
170 Result.method_load_address = reinterpret_cast<void*>(FnStart);
171 Result.method_size = FnSize;
172
173 Result.class_id = 0;
174 Result.class_file_name = NULL;
175 Result.user_data = NULL;
176 Result.user_data_size = 0;
178
179 return Result;
180}
181
182int getBackwardCompatibilityMode() {
183
184 char *BackwardCompatibilityEnv = getenv("INTEL_JIT_BACKWARD_COMPATIBILITY");
185 int BackwardCompatibilityMode = 0;
186 if (BackwardCompatibilityEnv) {
187 StringRef(BackwardCompatibilityEnv)
188 .getAsInteger(10, BackwardCompatibilityMode);
189 }
190 return BackwardCompatibilityMode;
191}
192
193void IntelJITEventListener::notifyObjectLoaded(
196
197 int BackwardCompatibilityMode = getBackwardCompatibilityMode();
198 if (BackwardCompatibilityMode == 0) {
199 if (Obj.isELF()) {
200 std::unique_ptr ModuleIttnotify =
201 std::make_unique(*Wrapper);
202 ModuleIttnotify->setModuleName(
204 MD5Hash(Obj.getMemoryBufferRef().getBuffer()), true))
206 .c_str());
207
208 __itt_module_object *ModuleObject = new __itt_module_object();
209 ModuleObject->module_name = ModuleIttnotify->getModuleName();
210 ModuleObject->module_size = Obj.getMemoryBufferRef().getBufferSize();
212 ModuleObject->module_name,
213 ModuleObject->module_size);
214 ModuleObject->module_type = __itt_module_type_elf;
215 ModuleObject->section_number =
216 ModuleIttnotify->fillSectionInformation(Obj, L);
217 ModuleObject->module_buffer =
218 (void *)const_cast<char *>(Obj.getMemoryBufferRef().getBufferStart());
219 ModuleObject->module_id =
220 __itt_id_make((void *)&(*ModuleObject), ModuleObject->module_size);
221 ModuleObject->section_array =
222 ModuleIttnotify->getSectionInfoVectorBegin();
223 ModuleIttnotify->setModuleObject(ModuleObject);
224
225 __itt_module_load_with_sections(ModuleObject);
226
227 KeyToIttnotify[Key] = std::move(ModuleIttnotify);
228 }
229 } else if (BackwardCompatibilityMode == 1) {
230
233 if (!DebugObj)
234 return;
235
236
237 const void *ObjData = DebugObj->getData().data();
239 MethodAddressVector Functions;
240
241
242 for (const std::pair<SymbolRef, uint64_t> &P :
245 std::vector LineInfo;
246 std::string SourceFileName;
247
249 if (!SymTypeOrErr) {
250
252 continue;
253 }
256 continue;
257
259 if (!Name) {
260
262 continue;
263 }
264
266 if (!AddrOrErr) {
267
269 continue;
270 }
273
275 if (!SecOrErr) {
276
278 continue;
279 }
281 if (Sec == Obj.section_end())
282 continue;
284
285
286 Functions.push_back((void *)Addr);
287
288
290 FunctionDescToIntelJITFormat(*Wrapper, Name->data(), Addr, Size);
292 Context->getLineInfoForAddressRange({Addr, Index}, Size);
296 LineInfo.push_back(
297 DILineInfoToIntelJITFormat((uintptr_t)Addr, It->first, It->second));
298 }
299 if (LineInfo.size() == 0) {
303 } else {
304
305
306
307
308
309
311 last.Offset = FunctionMessage.method_size;
312 LineInfo.push_back(last);
313 for (size_t i = LineInfo.size() - 2; i > 0; --i)
314 LineInfo[i].LineNumber = LineInfo[i - 1].LineNumber;
315
316 SourceFileName = Lines.front().second.FileName;
318 const_cast<char *>(SourceFileName.c_str());
321 }
322
324 &FunctionMessage);
325 MethodIDs[(void *)Addr] = FunctionMessage.method_id;
326 }
327
328
329
330
331 LoadedObjectMap[ObjData] = Functions;
332 DebugObjects[Key] = std::move(DebugObjOwner);
333 }
334}
335
336void IntelJITEventListener::notifyFreeingObject(ObjectKey Key) {
337
338 int BackwardCompatibilityMode = getBackwardCompatibilityMode();
339 if (BackwardCompatibilityMode == 0) {
340 if (KeyToIttnotify.find(Key) == KeyToIttnotify.end())
341 return;
342 __itt_module_unload_with_sections(KeyToIttnotify[Key]->getModuleObject());
343 Wrapper->iJitIttNotifyInfo(
345 KeyToIttnotify[Key]->getModuleObject()->module_name,
346 KeyToIttnotify[Key]->getModuleObject()->module_size);
347 KeyToIttnotify.erase(Key);
348 } else if (BackwardCompatibilityMode == 1) {
349
350
351 if (DebugObjects.find(Key) == DebugObjects.end())
352 return;
353
354
355 const ObjectFile &DebugObj = *DebugObjects[Key].getBinary();
356 const void *ObjData = DebugObj.getData().data();
357
358
359 ObjectMap::iterator OI = LoadedObjectMap.find(ObjData);
360 if (OI == LoadedObjectMap.end())
361 return;
362 MethodAddressVector &Functions = OI->second;
363
364
365 for (MethodAddressVector::iterator FI = Functions.begin(),
366 FE = Functions.end();
367 FI != FE; ++FI) {
368 void *FnStart = const_cast<void *>(*FI);
369 MethodIDMap::iterator MI = MethodIDs.find(FnStart);
370 if (MI != MethodIDs.end()) {
372 &MI->second);
374 }
375 }
376
377
378 LoadedObjectMap.erase(OI);
379 DebugObjects.erase(Key);
380 }
381}
382
383}
384
385namespace llvm {
387 return new IntelJITEventListener(new IntelJITEventsWrapper);
388}
389
390
392 IntelJITEventsWrapper* TestImpl) {
393 return new IntelJITEventListener(TestImpl);
394}
395
396}
397
amdgpu aa AMDGPU Address space based Alias Analysis Wrapper
This file defines the DenseMap class.
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)
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
int iJitIttNotifyInfo(IttEventType EventType, const char *Name, unsigned int Size)
JITEventListener - Abstract interface for use by the JIT to notify clients about significant events d...
static JITEventListener * createIntelJITEventListener()
Information about the loaded object.
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.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
std::string str() const
str - Get the contents as an std::string.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
StringRef getData() const
uint64_t getFlags() const
uint64_t getOffset() const
This class is the base class for all object file types.
uint64_t getIndex() const
bool isData() const
Whether this section contains data, not instructions.
bool isBSS() const
Whether this section contains BSS uninitialized data.
bool isText() const
Whether this section contains instructions.
Expected< StringRef > getName() const
This is a value type class that represents a single symbol in the list of symbols in the object file.
Expected< SymbolRef::Type > getType() const
Expected< StringRef > getName() const
Expected< uint64_t > getAddress() const
Returns the symbol virtual address (i.e.
Expected< section_iterator > getSection() const
Get section this symbol is defined in reference to.
LLVM_C_ABI LLVMJITEventListenerRef LLVMCreateIntelJITEventListener(void)
struct LLVMOpaqueJITEventListener * LLVMJITEventListenerRef
@ iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED
@ iJVM_EVENT_TYPE_METHOD_UNLOAD_START
struct _LineNumberInfo LineNumberInfo
struct _iJIT_Method_Load iJIT_Method_Load
content_iterator< SectionRef > section_iterator
LLVM_ABI std::vector< std::pair< SymbolRef, uint64_t > > computeSymbolSizes(const ObjectFile &O)
uint64_t MD5Hash(const FunctionId &Obj)
This is an optimization pass for GlobalISel generic memory operations.
SmallVector< std::pair< uint64_t, DILineInfo >, 16 > DILineInfoTable
std::string utohexstr(uint64_t X, bool LowerCase=false, unsigned Width=0)
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVMAttributeRef wrap(Attribute Attr)
void consumeError(Error Err)
Consume a Error without doing anything.
unsigned int line_number_size
pLineNumberInfo line_number_table
A format-neutral container for source line information.