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/Debugging/VTuneSupportPlugin.cpp
35294 views
1
//===--- VTuneSupportPlugin.cpp -- Support for VTune profiler --*- 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
// Handles support for registering code with VIntel Tune's Amplfiier JIT API.
10
//
11
//===----------------------------------------------------------------------===//
12
#include "llvm/ExecutionEngine/Orc/Debugging/VTuneSupportPlugin.h"
13
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
14
#include "llvm/ExecutionEngine/Orc/Debugging/DebugInfoSupport.h"
15
16
using namespace llvm;
17
using namespace llvm::orc;
18
using namespace llvm::jitlink;
19
20
static constexpr StringRef RegisterVTuneImplName = "llvm_orc_registerVTuneImpl";
21
static constexpr StringRef UnregisterVTuneImplName =
22
"llvm_orc_unregisterVTuneImpl";
23
static constexpr StringRef RegisterTestVTuneImplName =
24
"llvm_orc_test_registerVTuneImpl";
25
26
static VTuneMethodBatch getMethodBatch(LinkGraph &G, bool EmitDebugInfo) {
27
VTuneMethodBatch Batch;
28
std::unique_ptr<DWARFContext> DC;
29
StringMap<std::unique_ptr<MemoryBuffer>> DCBacking;
30
if (EmitDebugInfo) {
31
auto EDC = createDWARFContext(G);
32
if (!EDC) {
33
EmitDebugInfo = false;
34
} else {
35
DC = std::move(EDC->first);
36
DCBacking = std::move(EDC->second);
37
}
38
}
39
40
auto GetStringIdx = [Deduplicator = StringMap<uint32_t>(),
41
&Batch](StringRef S) mutable {
42
auto I = Deduplicator.find(S);
43
if (I != Deduplicator.end())
44
return I->second;
45
46
Batch.Strings.push_back(S.str());
47
return Deduplicator[S] = Batch.Strings.size();
48
};
49
for (auto Sym : G.defined_symbols()) {
50
if (!Sym->isCallable())
51
continue;
52
53
Batch.Methods.push_back(VTuneMethodInfo());
54
auto &Method = Batch.Methods.back();
55
Method.MethodID = 0;
56
Method.ParentMI = 0;
57
Method.LoadAddr = Sym->getAddress();
58
Method.LoadSize = Sym->getSize();
59
Method.NameSI = GetStringIdx(Sym->getName());
60
Method.ClassFileSI = 0;
61
Method.SourceFileSI = 0;
62
63
if (!EmitDebugInfo)
64
continue;
65
66
auto &Section = Sym->getBlock().getSection();
67
auto Addr = Sym->getAddress();
68
auto SAddr =
69
object::SectionedAddress{Addr.getValue(), Section.getOrdinal()};
70
DILineInfoTable LinesInfo = DC->getLineInfoForAddressRange(
71
SAddr, Sym->getSize(),
72
DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath);
73
Method.SourceFileSI = Batch.Strings.size();
74
Batch.Strings.push_back(DC->getLineInfoForAddress(SAddr).FileName);
75
for (auto &LInfo : LinesInfo) {
76
Method.LineTable.push_back(
77
std::pair<unsigned, unsigned>{/*unsigned*/ Sym->getOffset(),
78
/*DILineInfo*/ LInfo.second.Line});
79
}
80
}
81
return Batch;
82
}
83
84
void VTuneSupportPlugin::modifyPassConfig(MaterializationResponsibility &MR,
85
LinkGraph &G,
86
PassConfiguration &Config) {
87
Config.PostFixupPasses.push_back([this, MR = &MR](LinkGraph &G) {
88
// the object file is generated but not linked yet
89
auto Batch = getMethodBatch(G, EmitDebugInfo);
90
if (Batch.Methods.empty()) {
91
return Error::success();
92
}
93
{
94
std::lock_guard<std::mutex> Lock(PluginMutex);
95
uint64_t Allocated = Batch.Methods.size();
96
uint64_t Start = NextMethodID;
97
NextMethodID += Allocated;
98
for (size_t i = Start; i < NextMethodID; ++i) {
99
Batch.Methods[i - Start].MethodID = i;
100
}
101
this->PendingMethodIDs[MR] = {Start, Allocated};
102
}
103
G.allocActions().push_back(
104
{cantFail(shared::WrapperFunctionCall::Create<
105
shared::SPSArgList<shared::SPSVTuneMethodBatch>>(
106
RegisterVTuneImplAddr, Batch)),
107
{}});
108
return Error::success();
109
});
110
}
111
112
Error VTuneSupportPlugin::notifyEmitted(MaterializationResponsibility &MR) {
113
if (auto Err = MR.withResourceKeyDo([this, MR = &MR](ResourceKey K) {
114
std::lock_guard<std::mutex> Lock(PluginMutex);
115
auto I = PendingMethodIDs.find(MR);
116
if (I == PendingMethodIDs.end())
117
return;
118
119
LoadedMethodIDs[K].push_back(I->second);
120
PendingMethodIDs.erase(I);
121
})) {
122
return Err;
123
}
124
return Error::success();
125
}
126
127
Error VTuneSupportPlugin::notifyFailed(MaterializationResponsibility &MR) {
128
std::lock_guard<std::mutex> Lock(PluginMutex);
129
PendingMethodIDs.erase(&MR);
130
return Error::success();
131
}
132
133
Error VTuneSupportPlugin::notifyRemovingResources(JITDylib &JD, ResourceKey K) {
134
// Unregistration not required if not provided
135
if (!UnregisterVTuneImplAddr) {
136
return Error::success();
137
}
138
VTuneUnloadedMethodIDs UnloadedIDs;
139
{
140
std::lock_guard<std::mutex> Lock(PluginMutex);
141
auto I = LoadedMethodIDs.find(K);
142
if (I == LoadedMethodIDs.end())
143
return Error::success();
144
145
UnloadedIDs = std::move(I->second);
146
LoadedMethodIDs.erase(I);
147
}
148
if (auto Err = EPC.callSPSWrapper<void(shared::SPSVTuneUnloadedMethodIDs)>(
149
UnregisterVTuneImplAddr, UnloadedIDs))
150
return Err;
151
152
return Error::success();
153
}
154
155
void VTuneSupportPlugin::notifyTransferringResources(JITDylib &JD,
156
ResourceKey DstKey,
157
ResourceKey SrcKey) {
158
std::lock_guard<std::mutex> Lock(PluginMutex);
159
auto I = LoadedMethodIDs.find(SrcKey);
160
if (I == LoadedMethodIDs.end())
161
return;
162
163
auto &Dest = LoadedMethodIDs[DstKey];
164
Dest.insert(Dest.end(), I->second.begin(), I->second.end());
165
LoadedMethodIDs.erase(SrcKey);
166
}
167
168
Expected<std::unique_ptr<VTuneSupportPlugin>>
169
VTuneSupportPlugin::Create(ExecutorProcessControl &EPC, JITDylib &JD,
170
bool EmitDebugInfo, bool TestMode) {
171
auto &ES = EPC.getExecutionSession();
172
auto RegisterImplName =
173
ES.intern(TestMode ? RegisterTestVTuneImplName : RegisterVTuneImplName);
174
auto UnregisterImplName = ES.intern(UnregisterVTuneImplName);
175
SymbolLookupSet SLS{RegisterImplName, UnregisterImplName};
176
auto Res = ES.lookup(makeJITDylibSearchOrder({&JD}), std::move(SLS));
177
if (!Res)
178
return Res.takeError();
179
ExecutorAddr RegisterImplAddr(
180
Res->find(RegisterImplName)->second.getAddress());
181
ExecutorAddr UnregisterImplAddr(
182
Res->find(UnregisterImplName)->second.getAddress());
183
return std::make_unique<VTuneSupportPlugin>(
184
EPC, RegisterImplAddr, UnregisterImplAddr, EmitDebugInfo);
185
}
186
187