Go to the documentation of this file.
18 #define DEBUG_TYPE "jitlink"
28 dbgs() <<
"Starting link phase 1 for graph " << G->getName() <<
"\n";
36 dbgs() <<
"Link graph \"" << G->getName() <<
"\" pre-pruning:\n";
43 dbgs() <<
"Link graph \"" << G->getName() <<
"\" post-pruning:\n";
51 Ctx->getMemoryManager().allocate(
52 Ctx->getJITLinkDylib(), *G,
54 auto *TmpSelf =
S.get();
68 dbgs() <<
"Link graph \"" << G->getName()
69 <<
"\" before post-allocation passes:\n";
78 LLVM_DEBUG(
dbgs() <<
"Resolving symbols defined in " << G->getName() <<
"\n");
80 if (
auto Err = Ctx->notifyResolved(*G))
83 auto ExternalSymbols = getExternalSymbolNames();
86 if (ExternalSymbols.empty()) {
88 dbgs() <<
"No external symbols for " << G->getName()
89 <<
". Proceeding immediately with link phase 3.\n";
93 auto &TmpSelf = *Self;
100 dbgs() <<
"Issuing lookup for external symbols for " << G->getName()
101 <<
" (may trigger materialization/linking of other graphs)...\n";
127 dbgs() <<
"Starting link phase 3 for graph " << G->getName() <<
"\n";
135 applyLookupResult(*LR);
138 dbgs() <<
"Link graph \"" << G->getName()
139 <<
"\" before pre-fixup passes:\n";
147 dbgs() <<
"Link graph \"" << G->getName() <<
"\" before copy-and-fixup:\n";
152 if (
auto Err = fixUpBlocks(*G))
156 dbgs() <<
"Link graph \"" << G->getName() <<
"\" after copy-and-fixup:\n";
164 auto *TmpSelf =
S.get();
173 dbgs() <<
"Starting link phase 4 for graph " << G->getName() <<
"\n";
177 return Ctx->notifyFailed(FR.
takeError());
181 LLVM_DEBUG({
dbgs() <<
"Link of graph " << G->getName() <<
" complete\n"; });
185 for (
auto &
P : Passes)
186 if (
auto Err =
P(*G))
194 for (
auto *Sym : G->external_symbols()) {
195 assert(!Sym->getAddress() &&
196 "External has already been assigned an address");
198 "Externals must be named");
203 UnresolvedExternals[Sym->getName()] = LookupFlags;
205 return UnresolvedExternals;
209 for (
auto *Sym : G->external_symbols()) {
210 assert(Sym->getOffset() == 0 &&
211 "External symbol is not at the start of its addressable block");
212 assert(!Sym->getAddress() &&
"Symbol already resolved");
213 assert(!Sym->isDefined() &&
"Symbol being resolved is already defined");
214 auto ResultI =
Result.find(Sym->getName());
215 if (ResultI !=
Result.end())
216 Sym->getAddressable().setAddress(
217 orc::ExecutorAddr(ResultI->second.getAddress()));
220 "Failed to resolve non-weak reference");
224 dbgs() <<
"Externals after applying lookup result:\n";
225 for (
auto *Sym : G->external_symbols())
226 dbgs() <<
" " << Sym->getName() <<
": "
227 <<
formatv(
"{0:x16}", Sym->getAddress().getValue()) <<
"\n";
231 void JITLinkerBase::abandonAllocAndBailOut(std::unique_ptr<JITLinkerBase> Self,
233 assert(Err &&
"Should not be bailing out on success value");
234 assert(Alloc &&
"can not call abandonAllocAndBailOut before allocation");
241 std::vector<Symbol *> Worklist;
245 for (
auto *Sym :
G.defined_symbols())
247 Worklist.push_back(Sym);
250 while (!Worklist.empty()) {
251 auto *Sym = Worklist.back();
254 auto &
B = Sym->getBlock();
257 if (VisitedBlocks.
count(&
B))
262 for (
auto &
E : Sym->getBlock().edges()) {
265 if (
E.getTarget().isDefined() && !
E.getTarget().isLive())
266 Worklist.push_back(&
E.getTarget());
269 E.getTarget().setLive(
true);
276 std::vector<Symbol *> SymbolsToRemove;
277 for (
auto *Sym :
G.defined_symbols())
279 SymbolsToRemove.push_back(Sym);
280 for (
auto *Sym : SymbolsToRemove) {
282 G.removeDefinedSymbol(*Sym);
289 std::vector<Block *> BlocksToRemove;
290 for (
auto *
B :
G.blocks())
291 if (!VisitedBlocks.
count(
B))
292 BlocksToRemove.push_back(
B);
293 for (
auto *
B : BlocksToRemove) {
302 std::vector<Symbol *> SymbolsToRemove;
303 for (
auto *Sym :
G.external_symbols())
305 SymbolsToRemove.push_back(Sym);
306 for (
auto *Sym : SymbolsToRemove) {
308 G.removeExternalSymbol(*Sym);
This is an optimization pass for GlobalISel generic memory operations.
void linkPhase3(std::unique_ptr< JITLinkerBase > Self, Expected< AsyncLookupResult > LookupResult)
SymbolLookupFlags
Flags for symbol lookup.
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
static ErrorSuccess success()
Create a success value.
void prune(LinkGraph &G)
Removes dead symbols/blocks/addressables.
Tagged union holding either a T or a Error.
std::pair< iterator, bool > insert(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
void linkPhase1(std::unique_ptr< JITLinkerBase > Self)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
std::vector< JITTargetAddress > LookupResult
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
DenseMap< StringRef, JITEvaluatedSymbol > AsyncLookupResult
A map of symbol names to resolved addresses.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
LinkGraphPassList PrePrunePasses
Pre-prune passes.
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Error joinErrors(Error E1, Error E2)
Concatenate errors.
std::vector< LinkGraphPassFunction > LinkGraphPassList
A list of LinkGraph passes.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LinkGraphPassList PreFixupPasses
Pre-fixup passes.
void linkPhase2(std::unique_ptr< JITLinkerBase > Self, AllocResult AR)
DenseMap< StringRef, SymbolLookupFlags > LookupMap
LinkGraphPassList PostFixupPasses
Post-fixup passes.
std::unique_ptr< JITLinkAsyncLookupContinuation > createLookupContinuation(Continuation Cont)
Create a lookup continuation from a function object.
StringRef - Represent a constant reference to a string, i.e.
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Lightweight error class with error context and mandatory checking.
void linkPhase4(std::unique_ptr< JITLinkerBase > Self, FinalizeResult FR)
Error takeError()
Take ownership of the stored error.
LinkGraphPassList PostAllocationPasses
Post-allocation passes.
LinkGraphPassList PostPrunePasses
Post-prune passes.