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.