Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/TargetProcess/JITLoaderVTune.cpp
35323 views
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
//===----------------------------------------------------------------------===//
11
12
#include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderVTune.h"
13
#include "llvm/ExecutionEngine/Orc/Shared/VTuneSharedStructs.h"
14
#include <map>
15
16
#if LLVM_USE_INTEL_JITEVENTS
17
#include "IntelJITEventsWrapper.h"
18
#include "ittnotify.h"
19
20
using namespace llvm;
21
using namespace llvm::orc;
22
23
namespace {
24
class JITEventWrapper {
25
public:
26
static std::unique_ptr<IntelJITEventsWrapper> Wrapper;
27
};
28
std::unique_ptr<IntelJITEventsWrapper> JITEventWrapper::Wrapper;
29
} // namespace
30
31
static Error registerJITLoaderVTuneRegisterImpl(const VTuneMethodBatch &MB) {
32
const size_t StringsSize = MB.Strings.size();
33
34
for (const auto &MethodInfo : MB.Methods) {
35
iJIT_Method_Load MethodMessage;
36
memset(&MethodMessage, 0, sizeof(iJIT_Method_Load));
37
38
MethodMessage.method_id = MethodInfo.MethodID;
39
if (MethodInfo.NameSI != 0 && MethodInfo.NameSI < StringsSize) {
40
MethodMessage.method_name =
41
const_cast<char *>(MB.Strings.at(MethodInfo.NameSI).data());
42
} else {
43
MethodMessage.method_name = NULL;
44
}
45
if (MethodInfo.ClassFileSI != 0 && MethodInfo.ClassFileSI < StringsSize) {
46
MethodMessage.class_file_name =
47
const_cast<char *>(MB.Strings.at(MethodInfo.ClassFileSI).data());
48
} else {
49
MethodMessage.class_file_name = NULL;
50
}
51
if (MethodInfo.SourceFileSI != 0 && MethodInfo.SourceFileSI < StringsSize) {
52
MethodMessage.source_file_name =
53
const_cast<char *>(MB.Strings.at(MethodInfo.SourceFileSI).data());
54
} else {
55
MethodMessage.source_file_name = NULL;
56
}
57
58
MethodMessage.method_load_address = MethodInfo.LoadAddr.toPtr<void *>();
59
MethodMessage.method_size = MethodInfo.LoadSize;
60
MethodMessage.class_id = 0;
61
62
MethodMessage.user_data = NULL;
63
MethodMessage.user_data_size = 0;
64
MethodMessage.env = iJDE_JittingAPI;
65
66
std::vector<LineNumberInfo> LineInfo;
67
for (const auto &LInfo : MethodInfo.LineTable) {
68
LineInfo.push_back(LineNumberInfo{LInfo.first, LInfo.second});
69
}
70
71
if (LineInfo.size() == 0) {
72
MethodMessage.line_number_size = 0;
73
MethodMessage.line_number_table = 0;
74
} else {
75
MethodMessage.line_number_size = LineInfo.size();
76
MethodMessage.line_number_table = &*LineInfo.begin();
77
}
78
JITEventWrapper::Wrapper->iJIT_NotifyEvent(
79
iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, &MethodMessage);
80
}
81
82
return Error::success();
83
}
84
85
static void registerJITLoaderVTuneUnregisterImpl(
86
const std::vector<std::pair<uint64_t, uint64_t>> &UM) {
87
for (auto &Method : UM) {
88
JITEventWrapper::Wrapper->iJIT_NotifyEvent(
89
iJVM_EVENT_TYPE_METHOD_UNLOAD_START,
90
const_cast<uint64_t *>(&Method.first));
91
}
92
}
93
94
extern "C" llvm::orc::shared::CWrapperFunctionResult
95
llvm_orc_registerVTuneImpl(const char *Data, uint64_t Size) {
96
using namespace orc::shared;
97
if (!JITEventWrapper::Wrapper)
98
JITEventWrapper::Wrapper.reset(new IntelJITEventsWrapper);
99
100
return WrapperFunction<SPSError(SPSVTuneMethodBatch)>::handle(
101
Data, Size, registerJITLoaderVTuneRegisterImpl)
102
.release();
103
}
104
105
extern "C" llvm::orc::shared::CWrapperFunctionResult
106
llvm_orc_unregisterVTuneImpl(const char *Data, uint64_t Size) {
107
using namespace orc::shared;
108
return WrapperFunction<void(SPSVTuneUnloadedMethodIDs)>::handle(
109
Data, Size, registerJITLoaderVTuneUnregisterImpl)
110
.release();
111
}
112
113
// For Testing: following code comes from llvm-jitlistener.cpp in llvm tools
114
namespace {
115
using SourceLocations = std::vector<std::pair<std::string, unsigned int>>;
116
using NativeCodeMap = std::map<uint64_t, SourceLocations>;
117
NativeCodeMap ReportedDebugFuncs;
118
} // namespace
119
120
static int NotifyEvent(iJIT_JVM_EVENT EventType, void *EventSpecificData) {
121
switch (EventType) {
122
case iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED: {
123
if (!EventSpecificData) {
124
errs() << "Error: The JIT event listener did not provide a event data.";
125
return -1;
126
}
127
iJIT_Method_Load *msg = static_cast<iJIT_Method_Load *>(EventSpecificData);
128
129
ReportedDebugFuncs[msg->method_id];
130
131
outs() << "Method load [" << msg->method_id << "]: " << msg->method_name
132
<< ", Size = " << msg->method_size << "\n";
133
134
for (unsigned int i = 0; i < msg->line_number_size; ++i) {
135
if (!msg->line_number_table) {
136
errs() << "A function with a non-zero line count had no line table.";
137
return -1;
138
}
139
std::pair<std::string, unsigned int> loc(
140
std::string(msg->source_file_name),
141
msg->line_number_table[i].LineNumber);
142
ReportedDebugFuncs[msg->method_id].push_back(loc);
143
outs() << " Line info @ " << msg->line_number_table[i].Offset << ": "
144
<< msg->source_file_name << ", line "
145
<< msg->line_number_table[i].LineNumber << "\n";
146
}
147
outs() << "\n";
148
} break;
149
case iJVM_EVENT_TYPE_METHOD_UNLOAD_START: {
150
if (!EventSpecificData) {
151
errs() << "Error: The JIT event listener did not provide a event data.";
152
return -1;
153
}
154
unsigned int UnloadId =
155
*reinterpret_cast<unsigned int *>(EventSpecificData);
156
assert(1 == ReportedDebugFuncs.erase(UnloadId));
157
outs() << "Method unload [" << UnloadId << "]\n";
158
} break;
159
default:
160
break;
161
}
162
return 0;
163
}
164
165
static iJIT_IsProfilingActiveFlags IsProfilingActive(void) {
166
// for testing, pretend we have an Intel Parallel Amplifier XE 2011
167
// instance attached
168
return iJIT_SAMPLING_ON;
169
}
170
171
static unsigned int GetNewMethodID(void) {
172
static unsigned int id = 0;
173
return ++id;
174
}
175
176
extern "C" llvm::orc::shared::CWrapperFunctionResult
177
llvm_orc_test_registerVTuneImpl(const char *Data, uint64_t Size) {
178
using namespace orc::shared;
179
JITEventWrapper::Wrapper.reset(new IntelJITEventsWrapper(
180
NotifyEvent, NULL, NULL, IsProfilingActive, 0, 0, GetNewMethodID));
181
return WrapperFunction<SPSError(SPSVTuneMethodBatch)>::handle(
182
Data, Size, registerJITLoaderVTuneRegisterImpl)
183
.release();
184
}
185
186
#else
187
188
using namespace llvm;
189
using namespace llvm::orc;
190
191
static Error unsupportedBatch(const VTuneMethodBatch &MB) {
192
return llvm::make_error<StringError>("unsupported for Intel VTune",
193
inconvertibleErrorCode());
194
}
195
196
static void unsuppported(const std::vector<std::pair<uint64_t, uint64_t>> &UM) {
197
198
}
199
200
extern "C" llvm::orc::shared::CWrapperFunctionResult
201
llvm_orc_registerVTuneImpl(const char *Data, uint64_t Size) {
202
using namespace orc::shared;
203
return WrapperFunction<SPSError(SPSVTuneMethodBatch)>::handle(
204
Data, Size, unsupportedBatch)
205
.release();
206
}
207
208
extern "C" llvm::orc::shared::CWrapperFunctionResult
209
llvm_orc_unregisterVTuneImpl(const char *Data, uint64_t Size) {
210
using namespace orc::shared;
211
return WrapperFunction<void(SPSVTuneUnloadedMethodIDs)>::handle(Data, Size,
212
unsuppported)
213
.release();
214
}
215
216
extern "C" llvm::orc::shared::CWrapperFunctionResult
217
llvm_orc_test_registerVTuneImpl(const char *Data, uint64_t Size) {
218
using namespace orc::shared;
219
return WrapperFunction<SPSError(SPSVTuneMethodBatch)>::handle(
220
Data, Size, unsupportedBatch)
221
.release();
222
}
223
224
#endif
225
226