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<vtune_sps_ci::UnregisterVTuneImpl>::dispatch,
44 UnregisterImplAddr),
45 EmitDebugInfo(EmitDebugInfo) {}
46
47static VTuneMethodBatch getMethodBatch(LinkGraph &G, bool EmitDebugInfo) {
48 VTuneMethodBatch Batch;
49 std::unique_ptr<DWARFContext> DC;
51 if (EmitDebugInfo) {
52 auto EDC = createDWARFContext(G);
53 if (!EDC) {
54 EmitDebugInfo = false;
55 } else {
56 DC = std::move(EDC->first);
57 DCBacking = std::move(EDC->second);
58 }
59 }
60
61 auto GetStringIdx = [Deduplicator = StringMap<uint32_t>(),
62 &Batch](StringRef S) mutable {
63 auto [I, Inserted] = Deduplicator.try_emplace(S);
64 if (Inserted) {
65 Batch.Strings.push_back(S.str());
66 I->second = Batch.Strings.size();
67 }
68 return I->second;
69 };
70 for (auto Sym : G.defined_symbols()) {
71 if (!Sym->isCallable())
72 continue;
73
74 Batch.Methods.push_back(VTuneMethodInfo());
75 auto &Method = Batch.Methods.back();
76 Method.MethodID = 0;
77 Method.ParentMI = 0;
78 Method.LoadAddr = Sym->getAddress();
79 Method.LoadSize = Sym->getSize();
80 Method.NameSI = GetStringIdx(*Sym->getName());
81 Method.ClassFileSI = 0;
82 Method.SourceFileSI = 0;
83
84 if (!EmitDebugInfo)
85 continue;
86
87 auto &Section = Sym->getSection();
88 auto Addr = Sym->getAddress();
89 auto SAddr =
91 DILineInfoTable LinesInfo = DC->getLineInfoForAddressRange(
92 SAddr, Sym->getSize(),
94 Method.SourceFileSI = Batch.Strings.size();
95 Batch.Strings.push_back(
96 DC->getLineInfoForAddress(SAddr).value_or(DILineInfo()).FileName);
97 for (auto &LInfo : LinesInfo) {
98 Method.LineTable.push_back(
99 std::pair<unsigned, unsigned>{/*unsigned*/ Sym->getOffset(),
100 /*DILineInfo*/ LInfo.second.Line});
101 }
102 }
103 return Batch;
104}
105
107 LinkGraph &G,
108 PassConfiguration &Config) {
109 Config.PostFixupPasses.push_back([this, MR = &MR](LinkGraph &G) {
110 // the object file is generated but not linked yet
111 auto Batch = getMethodBatch(G, EmitDebugInfo);
112 if (Batch.Methods.empty()) {
113 return Error::success();
114 }
115 {
116 std::lock_guard<std::mutex> Lock(PluginMutex);
117 uint64_t Allocated = Batch.Methods.size();
118 uint64_t Start = NextMethodID;
119 NextMethodID += Allocated;
120 for (size_t i = Start; i < NextMethodID; ++i) {
121 Batch.Methods[i - Start].MethodID = i;
122 }
123 this->PendingMethodIDs[MR] = {Start, Allocated};
124 }
125 G.allocActions().push_back(
128 RegisterVTuneImplAddr, Batch)),
129 {}});
130 return Error::success();
131 });
132}
133
135 if (auto Err = MR.withResourceKeyDo([this, MR = &MR](ResourceKey K) {
136 std::lock_guard<std::mutex> Lock(PluginMutex);
137 auto I = PendingMethodIDs.find(MR);
138 if (I == PendingMethodIDs.end())
139 return;
140
141 LoadedMethodIDs[K].push_back(I->second);
142 PendingMethodIDs.erase(I);
143 })) {
144 return Err;
145 }
146 return Error::success();
147}
148
150 std::lock_guard<std::mutex> Lock(PluginMutex);
151 PendingMethodIDs.erase(&MR);
152 return Error::success();
153}
154
156 // Unregistration not required if not provided
157 if (!UnregisterVTuneImpl) {
158 return Error::success();
159 }
160 VTuneUnloadedMethodIDs UnloadedIDs;
161 {
162 std::lock_guard<std::mutex> Lock(PluginMutex);
163 auto I = LoadedMethodIDs.find(K);
164 if (I == LoadedMethodIDs.end())
165 return Error::success();
166
167 UnloadedIDs = std::move(I->second);
168 LoadedMethodIDs.erase(I);
169 }
170 if (auto Err = UnregisterVTuneImpl(EPC.getExecutionSession(), UnloadedIDs))
171 return Err;
172
173 return Error::success();
174}
175
177 ResourceKey DstKey,
178 ResourceKey SrcKey) {
179 std::lock_guard<std::mutex> Lock(PluginMutex);
180 auto I = LoadedMethodIDs.find(SrcKey);
181 if (I == LoadedMethodIDs.end())
182 return;
183
184 auto &Dest = LoadedMethodIDs[DstKey];
185 llvm::append_range(Dest, I->second);
186 LoadedMethodIDs.erase(SrcKey);
187}
188
191 bool EmitDebugInfo, bool TestMode) {
192 auto &ES = EPC.getExecutionSession();
193 auto RegisterImplName =
194 ES.intern(TestMode ? RegisterTestVTuneImplName : RegisterVTuneImplName);
195 auto UnregisterImplName = ES.intern(UnregisterVTuneImplName);
196 SymbolLookupSet SLS{RegisterImplName, UnregisterImplName};
197 auto Res = ES.lookup(makeJITDylibSearchOrder({&JD}), std::move(SLS));
198 if (!Res)
199 return Res.takeError();
200 ExecutorAddr RegisterImplAddr(
201 Res->find(RegisterImplName)->second.getAddress());
202 ExecutorAddr UnregisterImplAddr(
203 Res->find(UnregisterImplName)->second.getAddress());
204 return std::make_unique<VTuneSupportPlugin>(
205 EPC, RegisterImplAddr, UnregisterImplAddr, EmitDebugInfo);
206}
#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:668
Tracks responsibility for materialization, and mediates interactions between MaterializationUnits and...
Definition Core.h:343
Error withResourceKeyDo(Func &&F) const
Runs the given callback under the session lock, passing in the associated ResourceKey.
Definition Core.h:362
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:147
uintptr_t ResourceKey
Definition Core.h:62
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