LLVM 22.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//===----------------------------------------------------------------------===//
15
16using namespace llvm;
17using namespace llvm::orc;
18using namespace llvm::jitlink;
19
20static constexpr StringRef RegisterVTuneImplName = "llvm_orc_registerVTuneImpl";
22 "llvm_orc_unregisterVTuneImpl";
24 "llvm_orc_test_registerVTuneImpl";
25
26static VTuneMethodBatch getMethodBatch(LinkGraph &G, bool EmitDebugInfo) {
27 VTuneMethodBatch Batch;
28 std::unique_ptr<DWARFContext> DC;
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, Inserted] = Deduplicator.try_emplace(S);
43 if (Inserted) {
44 Batch.Strings.push_back(S.str());
45 I->second = Batch.Strings.size();
46 }
47 return I->second;
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->getSection();
67 auto Addr = Sym->getAddress();
68 auto SAddr =
70 DILineInfoTable LinesInfo = DC->getLineInfoForAddressRange(
71 SAddr, Sym->getSize(),
72 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath);
73 Method.SourceFileSI = Batch.Strings.size();
74 Batch.Strings.push_back(
75 DC->getLineInfoForAddress(SAddr).value_or(DILineInfo()).FileName);
76 for (auto &LInfo : LinesInfo) {
77 Method.LineTable.push_back(
78 std::pair<unsigned, unsigned>{/*unsigned*/ Sym->getOffset(),
79 /*DILineInfo*/ LInfo.second.Line});
80 }
81 }
82 return Batch;
83}
84
86 LinkGraph &G,
88 Config.PostFixupPasses.push_back([this, MR = &MR](LinkGraph &G) {
89 // the object file is generated but not linked yet
90 auto Batch = getMethodBatch(G, EmitDebugInfo);
91 if (Batch.Methods.empty()) {
92 return Error::success();
93 }
94 {
95 std::lock_guard<std::mutex> Lock(PluginMutex);
96 uint64_t Allocated = Batch.Methods.size();
97 uint64_t Start = NextMethodID;
98 NextMethodID += Allocated;
99 for (size_t i = Start; i < NextMethodID; ++i) {
100 Batch.Methods[i - Start].MethodID = i;
101 }
102 this->PendingMethodIDs[MR] = {Start, Allocated};
103 }
104 G.allocActions().push_back(
107 RegisterVTuneImplAddr, Batch)),
108 {}});
109 return Error::success();
110 });
111}
112
114 if (auto Err = MR.withResourceKeyDo([this, MR = &MR](ResourceKey K) {
115 std::lock_guard<std::mutex> Lock(PluginMutex);
116 auto I = PendingMethodIDs.find(MR);
117 if (I == PendingMethodIDs.end())
118 return;
119
120 LoadedMethodIDs[K].push_back(I->second);
121 PendingMethodIDs.erase(I);
122 })) {
123 return Err;
124 }
125 return Error::success();
126}
127
129 std::lock_guard<std::mutex> Lock(PluginMutex);
130 PendingMethodIDs.erase(&MR);
131 return Error::success();
132}
133
135 // Unregistration not required if not provided
136 if (!UnregisterVTuneImplAddr) {
137 return Error::success();
138 }
139 VTuneUnloadedMethodIDs UnloadedIDs;
140 {
141 std::lock_guard<std::mutex> Lock(PluginMutex);
142 auto I = LoadedMethodIDs.find(K);
143 if (I == LoadedMethodIDs.end())
144 return Error::success();
145
146 UnloadedIDs = std::move(I->second);
147 LoadedMethodIDs.erase(I);
148 }
149 if (auto Err = EPC.callSPSWrapper<void(shared::SPSVTuneUnloadedMethodIDs)>(
150 UnregisterVTuneImplAddr, UnloadedIDs))
151 return Err;
152
153 return Error::success();
154}
155
157 ResourceKey DstKey,
158 ResourceKey SrcKey) {
159 std::lock_guard<std::mutex> Lock(PluginMutex);
160 auto I = LoadedMethodIDs.find(SrcKey);
161 if (I == LoadedMethodIDs.end())
162 return;
163
164 auto &Dest = LoadedMethodIDs[DstKey];
165 llvm::append_range(Dest, I->second);
166 LoadedMethodIDs.erase(SrcKey);
167}
168
171 bool EmitDebugInfo, bool TestMode) {
172 auto &ES = EPC.getExecutionSession();
173 auto RegisterImplName =
175 auto UnregisterImplName = ES.intern(UnregisterVTuneImplName);
176 SymbolLookupSet SLS{RegisterImplName, UnregisterImplName};
177 auto Res = ES.lookup(makeJITDylibSearchOrder({&JD}), std::move(SLS));
178 if (!Res)
179 return Res.takeError();
180 ExecutorAddr RegisterImplAddr(
181 Res->find(RegisterImplName)->second.getAddress());
182 ExecutorAddr UnregisterImplAddr(
183 Res->find(UnregisterImplName)->second.getAddress());
184 return std::make_unique<VTuneSupportPlugin>(
185 EPC, RegisterImplAddr, UnregisterImplAddr, EmitDebugInfo);
186}
uint64_t Addr
RelaxConfig Config
Definition: ELF_riscv.cpp:506
Symbol * Sym
Definition: ELF_riscv.cpp:479
#define I(x, y, z)
Definition: MD5.cpp:58
#define G(x, y, z)
Definition: MD5.cpp:56
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
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition: StringMap.h:133
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
SymbolStringPtr intern(StringRef SymName)
Add a symbol name to the SymbolStringPool and return a pointer to it.
Definition: Core.h:1409
Represents an address in the executor process.
ExecutorProcessControl supports interaction with a JIT target process.
Error callSPSWrapper(ExecutorAddr WrapperFnAddr, WrapperCallArgTs &&...WrapperCallArgs)
Run a wrapper function using SPS to serialize the arguments and deserialize the results.
ExecutionSession & getExecutionSession()
Return the ExecutionSession associated with this instance.
Represents a JIT'd dynamic library.
Definition: Core.h:902
Tracks responsibility for materialization, and mediates interactions between MaterializationUnits and...
Definition: Core.h:576
Error withResourceKeyDo(Func &&F) const
Runs the given callback under the session lock, passing in the associated ResourceKey.
Definition: Core.h:595
A set of symbols to look up, each associated with a SymbolLookupFlags value.
Definition: Core.h:195
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)
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.
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:178
LLVM_ABI Expected< std::pair< std::unique_ptr< DWARFContext >, StringMap< std::unique_ptr< MemoryBuffer > > > > createDWARFContext(jitlink::LinkGraph &G)
uintptr_t ResourceKey
Definition: Core.h:75
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition: STLExtras.h:2155
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:32