LLVM: lib/ExecutionEngine/Orc/DebugUtils.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
10
18
19#define DEBUG_TYPE "orc"
20
21using namespace llvm;
22
23namespace {
24
25#ifndef NDEBUG
26
28 cl::desc("debug print hidden symbols defined by "
29 "materialization units"),
31
33 cl::desc("debug print callable symbols defined by "
34 "materialization units"),
36
38 cl::desc("debug print data symbols defined by "
39 "materialization units"),
41
42#endif
43
44
45template struct PrintAll {
46 bool operator()(const T &E) { return true; }
47};
48
49bool anyPrintSymbolOptionSet() {
50#ifndef NDEBUG
51 return PrintHidden || PrintCallable || PrintData;
52#else
53 return false;
54#endif
55}
56
58#ifndef NDEBUG
59
60 if (!PrintHidden && !Flags.isExported())
61 return false;
62
63
64 if (PrintCallable && Flags.isCallable())
65 return true;
66
67
68 if (PrintData && !Flags.isCallable())
69 return true;
70
71
72 return false;
73#else
74 return false;
75#endif
76}
77
78
79template <typename Sequence,
80 typename Pred = PrintAll<typename Sequence::value_type>>
81class SequencePrinter {
82public:
83 SequencePrinter(const Sequence &S, char OpenSeq, char CloseSeq,
84 Pred ShouldPrint = Pred())
85 : S(S), OpenSeq(OpenSeq), CloseSeq(CloseSeq),
86 ShouldPrint(std::move(ShouldPrint)) {}
87
89 bool PrintComma = false;
90 OS << OpenSeq;
91 for (auto &E : S) {
92 if (ShouldPrint(E)) {
93 if (PrintComma)
94 OS << ',';
95 OS << ' ' << E;
96 PrintComma = true;
97 }
98 }
99 OS << ' ' << CloseSeq;
100 }
101
102private:
103 const Sequence &S;
104 char OpenSeq;
105 char CloseSeq;
106 mutable Pred ShouldPrint;
107};
108
109template <typename Sequence, typename Pred>
110SequencePrinter<Sequence, Pred> printSequence(const Sequence &S, char OpenSeq,
111 char CloseSeq, Pred P = Pred()) {
112 return SequencePrinter<Sequence, Pred>(S, OpenSeq, CloseSeq, std::move(P));
113}
114
115
116template <typename Sequence, typename Pred>
118 const SequencePrinter<Sequence, Pred> &Printer) {
120 return OS;
121}
122
123struct PrintSymbolFlagsMapElemsMatchingCLOpts {
125 return flagsMatchCLOpts(KV.second);
126 }
127};
128
129struct PrintSymbolMapElemsMatchingCLOpts {
131 return flagsMatchCLOpts(KV.second.getFlags());
132 }
133};
134
135}
136
137namespace llvm {
138namespace orc {
139
141 return OS << printSequence(Symbols, '{', '}', PrintAll());
142}
143
145 return OS << printSequence(Symbols, '[', ']', PrintAll());
146}
147
149 return OS << printSequence(Symbols, '[', ']', PrintAll());
150}
151
153 if (Flags.hasError())
154 OS << "[*ERROR*]";
155 if (Flags.isCallable())
156 OS << "[Callable]";
157 else
158 OS << "[Data]";
159 if (Flags.isWeak())
160 OS << "[Weak]";
161 else if (Flags.isCommon())
162 OS << "[Common]";
163
164 if (!Flags.isExported())
165 OS << "[Hidden]";
166
167 return OS;
168}
169
173
175 return OS << "(\"" << KV.first << "\", " << KV.second << ")";
176}
177
179 return OS << "(\"" << KV.first << "\": " << KV.second << ")";
180}
181
183 return OS << printSequence(SymbolFlags, '{', '}',
184 PrintSymbolFlagsMapElemsMatchingCLOpts());
185}
186
188 return OS << printSequence(Symbols, '{', '}',
189 PrintSymbolMapElemsMatchingCLOpts());
190}
191
194 return OS << "(" << KV.first->getName() << ", " << KV.second << ")";
195}
196
198 return OS << printSequence(Deps, '{', '}',
199 PrintAllSymbolDependenceMap::value\_type());
200}
201
203 OS << "MU@" << &MU << " (\"" << MU.getName() << "\"";
204 if (anyPrintSymbolOptionSet())
206 return OS << ")";
207}
208
210 switch (K) {
212 return OS << "Static";
214 return OS << "DLSym";
215 }
217}
218
221 switch (JDLookupFlags) {
223 return OS << "MatchExportedSymbolsOnly";
225 return OS << "MatchAllSymbols";
226 }
228}
229
231 switch (LookupFlags) {
233 return OS << "RequiredSymbol";
235 return OS << "WeaklyReferencedSymbol";
236 }
238}
239
242 return OS << "(" << KV.first << ", " << KV.second << ")";
243}
244
246 return OS << printSequence(LookupSet, '{', '}',
247 PrintAllSymbolLookupSet::value\_type());
248}
249
252 OS << "[";
253 if (!SearchOrder.empty()) {
254 assert(SearchOrder.front().first &&
255 "JITDylibList entries must not be null");
256 OS << " (\"" << SearchOrder.front().first->getName() << "\", "
257 << SearchOrder.begin()->second << ")";
259 assert(KV.first && "JITDylibList entries must not be null");
260 OS << ", (\"" << KV.first->getName() << "\", " << KV.second << ")";
261 }
262 }
263 OS << " ]";
264 return OS;
265}
266
268 OS << "{";
269 for (auto &KV : Aliases)
270 OS << " " << *KV.first << ": " << KV.second.Aliasee << " "
271 << KV.second.AliasFlags;
272 OS << " }";
273 return OS;
274}
275
277 switch (S) {
279 return OS << "Invalid";
281 return OS << "Never-Searched";
283 return OS << "Materializing";
285 return OS << "Resolved";
287 return OS << "Emitted";
289 return OS << "Ready";
290 }
292}
293
295 std::lock_guardstd::mutex Lock(SSP.PoolMutex);
297 for (auto &KV : SSP.Pool)
300 for (auto &[K, V] : Vec)
301 OS << K << ": " << V << "\n";
302 return OS;
303}
304
306 : DumpDir(std::move(DumpDir)),
307 IdentifierOverride(std::move(IdentifierOverride)) {
308
309
310 while (!this->DumpDir.empty() &&
312 this->DumpDir.pop_back();
313}
314
317 size_t Idx = 1;
318
319 std::string DumpPathStem;
321 << DumpDir << (DumpDir.empty() ? "" : "/") << getBufferIdentifier(*Obj);
322
323 std::string DumpPath = DumpPathStem + ".o";
325 DumpPath.clear();
326 raw_string_ostream(DumpPath) << DumpPathStem << "." << (++Idx) << ".o";
327 }
328
330 dbgs() << "Dumping object buffer [ " << (const void *)Obj->getBufferStart()
331 << " -- " << (const void *)(Obj->getBufferEnd() - 1) << " ] to "
332 << DumpPath << "\n";
333 });
334
335 std::error_code EC;
337 if (EC)
339 DumpStream.write(Obj->getBufferStart(), Obj->getBufferSize());
340
341 return std::move(Obj);
342}
343
345 if (!IdentifierOverride.empty())
346 return IdentifierOverride;
347 StringRef Identifier = B.getBufferIdentifier();
348 Identifier.consume_back(".o");
349 return Identifier;
350}
351
352}
353}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
dxil pretty DXIL Metadata Pretty Printer
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Tagged union holding either a T or a Error.
Flags for symbols in the JIT.
This interface provides simple read-only access to a block of memory, and provides simple methods for...
reference emplace_back(ArgTypes &&... Args)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
LLVM_ABI Expected< std::unique_ptr< MemoryBuffer > > operator()(std::unique_ptr< MemoryBuffer > Obj)
Dumps the given buffer to disk.
Definition DebugUtils.cpp:316
LLVM_ABI DumpObjects(std::string DumpDir="", std::string IdentifierOverride="")
Construct a DumpObjects transform that will dump objects to disk.
Definition DebugUtils.cpp:305
Represents a defining location for a JIT symbol.
const JITSymbolFlags & getFlags() const
const ExecutorAddr & getAddress() const
A MaterializationUnit represents a set of symbol definitions that can be materialized as a group,...
virtual StringRef getName() const =0
Return the name of this materialization unit.
const SymbolFlagsMap & getSymbols() const
Return the set of symbols that this source provides.
A set of symbols to look up, each associated with a SymbolLookupFlags value.
std::pair< SymbolStringPtr, SymbolLookupFlags > value_type
String pool for symbol names used by the JIT.
A raw_ostream that writes to a file descriptor.
This class implements an extremely fast bulk output stream that can only output to a stream.
raw_ostream & write(unsigned char C)
A raw_ostream that writes to an std::string.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
initializer< Ty > init(const Ty &Val)
std::vector< std::pair< JITDylib *, JITDylibLookupFlags > > JITDylibSearchOrder
A list of (JITDylib*, JITDylibLookupFlags) pairs to be used as a search order during symbol lookup.
LLVM_ABI raw_ostream & operator<<(raw_ostream &OS, const SymbolNameSet &Symbols)
Render a SymbolNameSet.
Definition DebugUtils.cpp:140
SymbolLookupFlags
Lookup flags that apply to each symbol in a lookup.
JITDylibLookupFlags
Lookup flags that apply to each dylib in the search order for a lookup.
@ MatchExportedSymbolsOnly
DenseMap< SymbolStringPtr, ExecutorSymbolDef > SymbolMap
A map from symbol names (as SymbolStringPtrs) to JITSymbols (address/flags pairs).
LookupKind
Describes the kind of lookup being performed.
std::vector< SymbolStringPtr > SymbolNameVector
A vector of symbol names.
DenseMap< JITDylib *, SymbolNameSet > SymbolDependenceMap
A map from JITDylibs to sets of symbols.
DenseSet< SymbolStringPtr > SymbolNameSet
A set of symbol names (represented by SymbolStringPtrs for.
SymbolState
Represents the state that a symbol has reached during materialization.
@ Materializing
Added to the symbol table, never queried.
@ NeverSearched
No symbol should be in this state.
@ Ready
Emitted to memory, but waiting on transitive dependencies.
@ Emitted
Assigned address, still materializing.
@ Resolved
Queried, materialization begun.
DenseMap< SymbolStringPtr, SymbolAliasMapEntry > SymbolAliasMap
A map of Symbols to (Symbol, Flags) pairs.
DenseMap< SymbolStringPtr, JITSymbolFlags > SymbolFlagsMap
A map from symbol names (as SymbolStringPtrs) to JITSymbolFlags.
LLVM_ABI bool exists(const basic_file_status &status)
Does file exist?
LLVM_ABI bool is_separator(char value, Style style=Style::native)
Check whether the given char is a path separator on the host OS.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Implement std::hash so that hash_code can be used in STL containers.
Function object to check whether the first component of a container supported by std::get (like std::...