[Darwin][Driver][clang] apple-none-macho orders the resource directory after internal...
[llvm-project.git] / llvm / lib / ExecutionEngine / Orc / TargetProcess / JITLoaderVTune.cpp
blobfb7cf94fa0654a5a258da9e44517b3d934cbbc65
1 //===------- JITLoaderVTune.cpp - Register profiler objects -----*- C++ -*-===//
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 // Register objects for access by profilers via the VTune JIT interface.
10 //===----------------------------------------------------------------------===//
12 #include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderVTune.h"
13 #include "llvm/ExecutionEngine/Orc/Shared/VTuneSharedStructs.h"
15 #if LLVM_USE_INTEL_JITEVENTS
16 #include "IntelJITEventsWrapper.h"
17 #include "ittnotify.h"
19 using namespace llvm;
20 using namespace llvm::orc;
22 namespace {
23 class JITEventWrapper {
24 public:
25 static std::unique_ptr<IntelJITEventsWrapper> Wrapper;
27 std::unique_ptr<IntelJITEventsWrapper> JITEventWrapper::Wrapper;
28 } // namespace
30 static Error registerJITLoaderVTuneRegisterImpl(const VTuneMethodBatch &MB) {
31 const size_t StringsSize = MB.Strings.size();
33 for (const auto &MethodInfo : MB.Methods) {
34 iJIT_Method_Load MethodMessage;
35 memset(&MethodMessage, 0, sizeof(iJIT_Method_Load));
37 MethodMessage.method_id = MethodInfo.MethodID;
38 if (MethodInfo.NameSI != 0 && MethodInfo.NameSI < StringsSize) {
39 MethodMessage.method_name =
40 const_cast<char *>(MB.Strings.at(MethodInfo.NameSI).data());
41 } else {
42 MethodMessage.method_name = NULL;
44 if (MethodInfo.ClassFileSI != 0 && MethodInfo.ClassFileSI < StringsSize) {
45 MethodMessage.class_file_name =
46 const_cast<char *>(MB.Strings.at(MethodInfo.ClassFileSI).data());
47 } else {
48 MethodMessage.class_file_name = NULL;
50 if (MethodInfo.SourceFileSI != 0 && MethodInfo.SourceFileSI < StringsSize) {
51 MethodMessage.source_file_name =
52 const_cast<char *>(MB.Strings.at(MethodInfo.SourceFileSI).data());
53 } else {
54 MethodMessage.source_file_name = NULL;
57 MethodMessage.method_load_address = MethodInfo.LoadAddr.toPtr<void *>();
58 MethodMessage.method_size = MethodInfo.LoadSize;
59 MethodMessage.class_id = 0;
61 MethodMessage.user_data = NULL;
62 MethodMessage.user_data_size = 0;
63 MethodMessage.env = iJDE_JittingAPI;
65 std::vector<LineNumberInfo> LineInfo;
66 for (const auto &LInfo : MethodInfo.LineTable) {
67 LineInfo.push_back(LineNumberInfo{LInfo.first, LInfo.second});
70 if (LineInfo.size() == 0) {
71 MethodMessage.line_number_size = 0;
72 MethodMessage.line_number_table = 0;
73 } else {
74 MethodMessage.line_number_size = LineInfo.size();
75 MethodMessage.line_number_table = &*LineInfo.begin();
77 JITEventWrapper::Wrapper->iJIT_NotifyEvent(
78 iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, &MethodMessage);
81 return Error::success();
84 static void registerJITLoaderVTuneUnregisterImpl(
85 const std::vector<std::pair<uint64_t, uint64_t>> &UM) {
86 for (auto &Method : UM) {
87 JITEventWrapper::Wrapper->iJIT_NotifyEvent(
88 iJVM_EVENT_TYPE_METHOD_UNLOAD_START,
89 const_cast<uint64_t *>(&Method.first));
93 extern "C" llvm::orc::shared::CWrapperFunctionResult
94 llvm_orc_registerVTuneImpl(const char *Data, uint64_t Size) {
95 using namespace orc::shared;
96 if (!JITEventWrapper::Wrapper)
97 JITEventWrapper::Wrapper.reset(new IntelJITEventsWrapper);
99 return WrapperFunction<SPSError(SPSVTuneMethodBatch)>::handle(
100 Data, Size, registerJITLoaderVTuneRegisterImpl)
101 .release();
104 extern "C" llvm::orc::shared::CWrapperFunctionResult
105 llvm_orc_unregisterVTuneImpl(const char *Data, uint64_t Size) {
106 using namespace orc::shared;
107 return WrapperFunction<void(SPSVTuneUnloadedMethodIDs)>::handle(
108 Data, Size, registerJITLoaderVTuneUnregisterImpl)
109 .release();
112 // For Testing: following code comes from llvm-jitlistener.cpp in llvm tools
113 namespace {
114 using SourceLocations = std::vector<std::pair<std::string, unsigned int>>;
115 using NativeCodeMap = std::map<uint64_t, SourceLocations>;
116 NativeCodeMap ReportedDebugFuncs;
117 } // namespace
119 static int NotifyEvent(iJIT_JVM_EVENT EventType, void *EventSpecificData) {
120 switch (EventType) {
121 case iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED: {
122 if (!EventSpecificData) {
123 errs() << "Error: The JIT event listener did not provide a event data.";
124 return -1;
126 iJIT_Method_Load *msg = static_cast<iJIT_Method_Load *>(EventSpecificData);
128 ReportedDebugFuncs[msg->method_id];
130 outs() << "Method load [" << msg->method_id << "]: " << msg->method_name
131 << ", Size = " << msg->method_size << "\n";
133 for (unsigned int i = 0; i < msg->line_number_size; ++i) {
134 if (!msg->line_number_table) {
135 errs() << "A function with a non-zero line count had no line table.";
136 return -1;
138 std::pair<std::string, unsigned int> loc(
139 std::string(msg->source_file_name),
140 msg->line_number_table[i].LineNumber);
141 ReportedDebugFuncs[msg->method_id].push_back(loc);
142 outs() << " Line info @ " << msg->line_number_table[i].Offset << ": "
143 << msg->source_file_name << ", line "
144 << msg->line_number_table[i].LineNumber << "\n";
146 outs() << "\n";
147 } break;
148 case iJVM_EVENT_TYPE_METHOD_UNLOAD_START: {
149 if (!EventSpecificData) {
150 errs() << "Error: The JIT event listener did not provide a event data.";
151 return -1;
153 unsigned int UnloadId =
154 *reinterpret_cast<unsigned int *>(EventSpecificData);
155 assert(1 == ReportedDebugFuncs.erase(UnloadId));
156 outs() << "Method unload [" << UnloadId << "]\n";
157 } break;
158 default:
159 break;
161 return 0;
164 static iJIT_IsProfilingActiveFlags IsProfilingActive(void) {
165 // for testing, pretend we have an Intel Parallel Amplifier XE 2011
166 // instance attached
167 return iJIT_SAMPLING_ON;
170 static unsigned int GetNewMethodID(void) {
171 static unsigned int id = 0;
172 return ++id;
175 extern "C" llvm::orc::shared::CWrapperFunctionResult
176 llvm_orc_test_registerVTuneImpl(const char *Data, uint64_t Size) {
177 using namespace orc::shared;
178 JITEventWrapper::Wrapper.reset(new IntelJITEventsWrapper(
179 NotifyEvent, NULL, NULL, IsProfilingActive, 0, 0, GetNewMethodID));
180 return WrapperFunction<SPSError(SPSVTuneMethodBatch)>::handle(
181 Data, Size, registerJITLoaderVTuneRegisterImpl)
182 .release();
185 #else
187 using namespace llvm;
188 using namespace llvm::orc;
190 static Error unsupportedBatch(const VTuneMethodBatch &MB) {
191 return llvm::make_error<StringError>("unsupported for Intel VTune",
192 inconvertibleErrorCode());
195 static void unsuppported(const std::vector<std::pair<uint64_t, uint64_t>> &UM) {
199 extern "C" llvm::orc::shared::CWrapperFunctionResult
200 llvm_orc_registerVTuneImpl(const char *Data, uint64_t Size) {
201 using namespace orc::shared;
202 return WrapperFunction<SPSError(SPSVTuneMethodBatch)>::handle(
203 Data, Size, unsupportedBatch)
204 .release();
207 extern "C" llvm::orc::shared::CWrapperFunctionResult
208 llvm_orc_unregisterVTuneImpl(const char *Data, uint64_t Size) {
209 using namespace orc::shared;
210 return WrapperFunction<void(SPSVTuneUnloadedMethodIDs)>::handle(Data, Size,
211 unsuppported)
212 .release();
215 extern "C" llvm::orc::shared::CWrapperFunctionResult
216 llvm_orc_test_registerVTuneImpl(const char *Data, uint64_t Size) {
217 using namespace orc::shared;
218 return WrapperFunction<SPSError(SPSVTuneMethodBatch)>::handle(
219 Data, Size, unsupportedBatch)
220 .release();
223 #endif