LLVM 24.0.0git
VTuneSupportPlugin.cpp
Go to the documentation of this file.
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//===----------------------------------------------------------------------===//
16
17using namespace llvm;
18using namespace llvm::orc;
19using namespace llvm::jitlink;
20
21static constexpr StringRef RegisterVTuneImplName = "llvm_orc_registerVTuneImpl";
23 "llvm_orc_unregisterVTuneImpl";
25 "llvm_orc_test_registerVTuneImpl";
26
27// Controller-interface descriptors for the executor's VTune-support wrapper
28// calls.
35} // namespace llvm::orc::vtune_sps_ci
36
38 ExecutorAddr RegisterImplAddr,
39 ExecutorAddr UnregisterImplAddr,
40 bool EmitDebugInfo)
41 : EPC(EPC), RegisterVTuneImplAddr(RegisterImplAddr),
42 UnregisterVTuneImpl(
43 sps::ProxySpec<Proxy<void(VTuneUnloadedMethodIDs)>,
44 vtune_sps_ci::UnregisterVTuneImpl>::dispatch,
45 UnregisterImplAddr),
46 EmitDebugInfo(EmitDebugInfo) {}
47
48static VTuneMethodBatch getMethodBatch(LinkGraph &G, bool EmitDebugInfo) {
49 VTuneMethodBatch Batch;
50 std::unique_ptr<DWARFContext> DC;
52 if (EmitDebugInfo) {
53 auto EDC = createDWARFContext(G);
54 if (!EDC) {
55 EmitDebugInfo = false;
56 } else {
57 DC = std::move(EDC->first);
58 DCBacking = std::move(EDC->second);
59 }
60 }
61
62 auto GetStringIdx = [Deduplicator = StringMap<uint32_t>(),
63 &Batch](StringRef S) mutable {
64 auto [I, Inserted] = Deduplicator.try_emplace(S);
65 if (Inserted) {
66 Batch.Strings.push_back(S.str());
67 I->second = Batch.Strings.size();
68 }
69 return I->second;
70 };
71 for (auto Sym : G.defined_symbols()) {
72 if (!Sym->isCallable())
73 continue;
74
75 Batch.Methods.push_back(VTuneMethodInfo());
76 auto &Method = Batch.Methods.back();
77 Method.MethodID = 0;
78 Method.ParentMI = 0;
79 Method.LoadAddr = Sym->getAddress();
80 Method.LoadSize = Sym->getSize();
81 Method.NameSI = GetStringIdx(*Sym->getName());
82 Method.ClassFileSI = 0;
83 Method.SourceFileSI = 0;
84
85 if (!EmitDebugInfo)
86 continue;
87
88 auto &Section = Sym->getSection();
89 auto Addr = Sym->getAddress();
90 auto SAddr =
92 DILineInfoTable LinesInfo = DC->getLineInfoForAddressRange(
93 SAddr, Sym->getSize(),
95 Method.SourceFileSI = Batch.Strings.size();
96 Batch.Strings.push_back(
97 DC->getLineInfoForAddress(SAddr).value_or(DILineInfo()).FileName);
98 for (auto &LInfo : LinesInfo) {
99 Method.LineTable.push_back(
100 std::pair<unsigned, unsigned>{/*unsigned*/ Sym->getOffset(),
101 /*DILineInfo*/ LInfo.second.Line});
102 }
103 }
104 return Batch;
105}
106
108 LinkGraph &G,
109 PassConfiguration &Config) {
110 Config.PostFixupPasses.push_back([this, MR = &MR](LinkGraph &G) {
111 // the object file is generated but not linked yet
112 auto Batch = getMethodBatch(G, EmitDebugInfo);
113 if (Batch.Methods.empty()) {
114 return Error::success();
115 }
116 {
117 std::lock_guard<std::mutex> Lock(PluginMutex);
118 uint64_t Allocated = Batch.Methods.size();
119 uint64_t Start = NextMethodID;
120 NextMethodID += Allocated;
121 for (size_t i = Start; i < NextMethodID; ++i) {
122 Batch.Methods[i - Start].MethodID = i;
123 }
124 this->PendingMethodIDs[MR] = {Start, Allocated};
125 }
126 G.allocActions().push_back(
129 RegisterVTuneImplAddr, Batch)),
130 {}});
131 return Error::success();
132 });
133}
134
136 if (auto Err = MR.withResourceKeyDo([this, MR = &MR](ResourceKey K) {
137 std::lock_guard<std::mutex> Lock(PluginMutex);
138 auto I = PendingMethodIDs.find(MR);
139 if (I == PendingMethodIDs.end())
140 return;
141
142 LoadedMethodIDs[K].push_back(I->second);
143 PendingMethodIDs.erase(I);
144 })) {
145 return Err;
146 }
147 return Error::success();
148}
149
151 std::lock_guard<std::mutex> Lock(PluginMutex);
152 PendingMethodIDs.erase(&MR);
153 return Error::success();
154}
155
157 // Unregistration not required if not provided
158 if (!UnregisterVTuneImpl) {
159 return Error::success();
160 }
161 VTuneUnloadedMethodIDs UnloadedIDs;
162 {
163 std::lock_guard<std::mutex> Lock(PluginMutex);
164 auto I = LoadedMethodIDs.find(K);
165 if (I == LoadedMethodIDs.end())
166 return Error::success();
167
168 UnloadedIDs = std::move(I->second);
169 LoadedMethodIDs.erase(I);
170 }
171 if (auto Err = UnregisterVTuneImpl(EPC.getExecutionSession(), UnloadedIDs))
172 return Err;
173
174 return Error::success();
175}
176
178 ResourceKey DstKey,
179 ResourceKey SrcKey) {
180 std::lock_guard<std::mutex> Lock(PluginMutex);
181 auto I = LoadedMethodIDs.find(SrcKey);
182 if (I == LoadedMethodIDs.end())
183 return;
184
185 auto &Dest = LoadedMethodIDs[DstKey];
186 llvm::append_range(Dest, I->second);
187 LoadedMethodIDs.erase(SrcKey);
188}
189
192 bool EmitDebugInfo, bool TestMode) {
193 auto &ES = EPC.getExecutionSession();
194 auto RegisterImplName =
195 ES.intern(TestMode ? RegisterTestVTuneImplName : RegisterVTuneImplName);
196 auto UnregisterImplName = ES.intern(UnregisterVTuneImplName);
197 SymbolLookupSet SLS{RegisterImplName, UnregisterImplName};
198 auto Res = ES.lookup(makeJITDylibSearchOrder({&JD}), std::move(SLS));
199 if (!Res)
200 return Res.takeError();
201 ExecutorAddr RegisterImplAddr(
202 Res->find(RegisterImplName)->second.getAddress());
203 ExecutorAddr UnregisterImplAddr(
204 Res->find(UnregisterImplName)->second.getAddress());
205 return std::make_unique<VTuneSupportPlugin>(
206 EPC, RegisterImplAddr, UnregisterImplAddr, EmitDebugInfo);
207}
#define I(x, y, z)
Definition MD5.cpp:57
#define G(x, y, z)
Definition MD5.cpp:55
static constexpr StringRef RegisterVTuneImplName
static constexpr StringRef RegisterTestVTuneImplName
static constexpr StringRef UnregisterVTuneImplName
static VTuneMethodBatch getMethodBatch(LinkGraph &G, bool EmitDebugInfo)
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Tagged union holding either a T or a Error.
Definition Error.h:485
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition StringMap.h:129
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Represents an address in the executor process.
ExecutorProcessControl supports interaction with a JIT target process.
Represents a JIT'd dynamic library.
Definition Core.h:676
Tracks responsibility for materialization, and mediates interactions between MaterializationUnits and...
Definition Core.h:350
Error withResourceKeyDo(Func &&F) const
Runs the given callback under the session lock, passing in the associated ResourceKey.
Definition Core.h:369
A set of symbols to look up, each associated with a SymbolLookupFlags value.
A symbol name together with the naming level (SymbolNameKind) it is expressed in, so that a Mangler /...
static constexpr SymbolNameSpec c(StringRef Name)
void notifyTransferringResources(JITDylib &JD, ResourceKey DstKey, ResourceKey SrcKey) override
static Expected< std::unique_ptr< VTuneSupportPlugin > > Create(ExecutorProcessControl &EPC, JITDylib &JD, bool EmitDebugInfo, bool TestMode=false)
VTuneSupportPlugin(ExecutorProcessControl &EPC, ExecutorAddr RegisterImplAddr, ExecutorAddr UnregisterImplAddr, bool EmitDebugInfo)
Error notifyEmitted(MaterializationResponsibility &MR) override
void modifyPassConfig(MaterializationResponsibility &MR, jitlink::LinkGraph &G, jitlink::PassConfiguration &Config) override
Error notifyFailed(MaterializationResponsibility &MR) override
Error notifyRemovingResources(JITDylib &JD, ResourceKey K) override
A utility class for serializing to a blob from a variadic list.
static Expected< WrapperFunctionCall > Create(ExecutorAddr FnAddr, const ArgTs &...Args)
Create a WrapperFunctionCall using the given SPS serializer to serialize the arguments.
SPSSequence< SPSTuple< uint64_t, uint64_t > > SPSVTuneUnloadedMethodIDs
JITDylibSearchOrder makeJITDylibSearchOrder(ArrayRef< JITDylib * > JDs, JITDylibLookupFlags Flags=JITDylibLookupFlags::MatchExportedSymbolsOnly)
Convenience function for creating a search order from an ArrayRef of JITDylib*, all with the same fla...
Definition Core.h:154
uintptr_t ResourceKey
Definition Core.h:61
SmallVector< std::pair< uint64_t, uint64_t > > VTuneUnloadedMethodIDs
LLVM_ABI Expected< std::pair< std::unique_ptr< DWARFContext >, StringMap< std::unique_ptr< MemoryBuffer > > > > createDWARFContext(jitlink::LinkGraph &G)
This is an optimization pass for GlobalISel generic memory operations.
SmallVector< std::pair< uint64_t, DILineInfo >, 16 > DILineInfoTable
Definition DIContext.h:92
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition STLExtras.h:2224
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition Error.h:769
A format-neutral container for source line information.
Definition DIContext.h:33
void(shared::SPSVTuneUnloadedMethodIDs) SPSSig