LLVM 20.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->getBlock().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(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
85 LinkGraph &G,
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(
106 RegisterVTuneImplAddr, Batch)),
107 {}});
108 return Error::success();
109 });
110}
111
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
128 std::lock_guard<std::mutex> Lock(PluginMutex);
129 PendingMethodIDs.erase(&MR);
130 return Error::success();
131}
132
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
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
170 bool EmitDebugInfo, bool TestMode) {
171 auto &ES = EPC.getExecutionSession();
172 auto RegisterImplName =
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}
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:160
static ErrorSuccess success()
Create a success value.
Definition: Error.h:337
Tagged union holding either a T or a Error.
Definition: Error.h:481
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition: StringMap.h:128
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
SymbolStringPtr intern(StringRef SymName)
Add a symbol name to the SymbolStringPool and return a pointer to it.
Definition: Core.h:1393
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:897
Tracks responsibility for materialization, and mediates interactions between MaterializationUnits and...
Definition: Core.h:571
Error withResourceKeyDo(Func &&F) const
Runs the given callback under the session lock, passing in the associated ResourceKey.
Definition: Core.h:590
A set of symbols to look up, each associated with a SymbolLookupFlags value.
Definition: Core.h:194
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:177
Expected< std::pair< std::unique_ptr< DWARFContext >, StringMap< std::unique_ptr< MemoryBuffer > > > > createDWARFContext(jitlink::LinkGraph &G)
uintptr_t ResourceKey
Definition: Core.h:74
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition: Error.h:756