15#define DEBUG_TYPE "jitlink" 
   27  if (
auto Err = runPasses(Passes.PrePrunePasses))
 
   28    return Ctx->notifyFailed(std::move(Err));
 
   31    dbgs() << 
"Link graph pre-pruning:\n";
 
   38    dbgs() << 
"Link graph post-pruning:\n";
 
   43  if (
auto Err = runPasses(Passes.PostPrunePasses))
 
   44    return Ctx->notifyFailed(std::move(Err));
 
   48        return S.getMemLifetime() == orc::MemLifetime::NoAlloc;
 
   54  Ctx->getMemoryManager().allocate(
 
   55      Ctx->getJITLinkDylib(), *G,
 
   60        auto *TmpSelf = S.get();
 
   61        TmpSelf->linkPhase2(std::move(S), std::move(AR));
 
 
   71    Alloc = std::move(*AR);
 
   76    dbgs() << 
"Link graph before post-allocation passes:\n";
 
   81  if (
auto Err = runPasses(Passes.PostAllocationPasses))
 
   82    return abandonAllocAndBailOut(std::move(Self), std::move(Err));
 
   85  LLVM_DEBUG(
dbgs() << 
"Resolving symbols defined in " << G->getName() << 
"\n");
 
   87  if (
auto Err = Ctx->notifyResolved(*G))
 
   88    return abandonAllocAndBailOut(std::move(Self), std::move(Err));
 
   90  auto ExternalSymbols = getExternalSymbolNames();
 
   93  if (ExternalSymbols.empty()) {
 
   95      dbgs() << 
"No external symbols for " << G->getName()
 
   96             << 
". Proceeding immediately with link phase 3.\n";
 
  100    auto &TmpSelf = *Self;
 
  107    dbgs() << 
"Issuing lookup for external symbols for " << G->getName()
 
  108           << 
" (may trigger materialization/linking of other graphs)...\n";
 
  121  Ctx->lookup(std::move(ExternalSymbols),
 
  123                  [S = std::move(Self)](
 
  126                    TmpSelf.linkPhase3(std::move(S), std::move(LookupResult));
 
 
  137    return abandonAllocAndBailOut(std::move(Self), LR.
takeError());
 
  140  applyLookupResult(*LR);
 
  143    dbgs() << 
"Link graph before pre-fixup passes:\n";
 
  147  if (
auto Err = runPasses(Passes.PreFixupPasses))
 
  148    return abandonAllocAndBailOut(std::move(Self), std::move(Err));
 
  151    dbgs() << 
"Link graph before copy-and-fixup:\n";
 
  156  if (
auto Err = fixUpBlocks(*G))
 
  157    return abandonAllocAndBailOut(std::move(Self), std::move(Err));
 
  160    dbgs() << 
"Link graph after copy-and-fixup:\n";
 
  164  if (
auto Err = runPasses(Passes.PostFixupPasses))
 
  165    return abandonAllocAndBailOut(std::move(Self), std::move(Err));
 
  173  Alloc->finalize([S = std::move(Self)](
FinalizeResult FR) 
mutable {
 
  177    auto *TmpSelf = S.get();
 
  178    TmpSelf->linkPhase4(std::move(S), std::move(FR));
 
 
  188    return Ctx->notifyFailed(FR.
takeError());
 
  190  Ctx->notifyFinalized(std::move(*FR));
 
 
  197    if (
auto Err = 
P(*
G))
 
  205  for (
auto *Sym : 
G->external_symbols()) {
 
  206    assert(!Sym->getAddress() &&
 
  207           "External has already been assigned an address");
 
  208    assert(Sym->hasName() && 
"Externals must be named");
 
  212    UnresolvedExternals[Sym->getName()] = LookupFlags;
 
  214  return UnresolvedExternals;
 
  218  for (
auto *Sym : G->external_symbols()) {
 
  219    assert(Sym->getOffset() == 0 &&
 
  220           "External symbol is not at the start of its addressable block");
 
  221    assert(!Sym->getAddress() && 
"Symbol already resolved");
 
  222    assert(!Sym->isDefined() && 
"Symbol being resolved is already defined");
 
  223    auto ResultI = 
Result.find(Sym->getName());
 
  224    if (ResultI != 
Result.end()) {
 
  225      Sym->getAddressable().setAddress(ResultI->second.getAddress());
 
  226      Sym->setLinkage(ResultI->second.getFlags().isWeak() ? 
Linkage::Weak 
  228      Sym->setScope(ResultI->second.getFlags().isExported() ? 
Scope::Default 
  231      assert(Sym->isWeaklyReferenced() &&
 
  232             "Failed to resolve non-weak reference");
 
  236    dbgs() << 
"Externals after applying lookup result:\n";
 
  237    for (
auto *Sym : G->external_symbols()) {
 
  238      dbgs() << 
"  " << Sym->getName() << 
": " 
  239             << 
formatv(
"{0:x16}", Sym->getAddress().getValue());
 
  240      switch (Sym->getLinkage()) {
 
  247      switch (Sym->getScope()) {
 
  251                         "side-effects-only linkage");
 
  255        dbgs() << 
" (exported)";
 
  263void JITLinkerBase::abandonAllocAndBailOut(std::unique_ptr<JITLinkerBase> Self,
 
  265  assert(Err && 
"Should not be bailing out on success value");
 
  266  assert(Alloc && 
"can not call abandonAllocAndBailOut before allocation");
 
  267  Alloc->abandon([S = std::move(Self), E1 = std::move(Err)](
Error E2) 
mutable {
 
  268    S->Ctx->notifyFailed(
joinErrors(std::move(E1), std::move(E2)));
 
  273  std::vector<Symbol *> Worklist;
 
  277  for (
auto *Sym : 
G.defined_symbols())
 
  279      Worklist.push_back(Sym);
 
  282  while (!Worklist.empty()) {
 
  283    auto *Sym = Worklist.back();
 
  286    auto &
B = Sym->getBlock();
 
  294    for (
auto &
E : Sym->getBlock().edges()) {
 
  297      if (
E.getTarget().isDefined() && !
E.getTarget().isLive())
 
  298        Worklist.push_back(&
E.getTarget());
 
  301      E.getTarget().setLive(
true);
 
  308    std::vector<Symbol *> SymbolsToRemove;
 
  309    for (
auto *Sym : 
G.defined_symbols())
 
  311        SymbolsToRemove.push_back(Sym);
 
  312    for (
auto *Sym : SymbolsToRemove) {
 
  314      G.removeDefinedSymbol(*Sym);
 
  321    std::vector<Block *> BlocksToRemove;
 
  322    for (
auto *
B : 
G.blocks())
 
  324        BlocksToRemove.push_back(
B);
 
  325    for (
auto *
B : BlocksToRemove) {
 
  334    std::vector<Symbol *> SymbolsToRemove;
 
  335    for (
auto *Sym : 
G.external_symbols())
 
  337        SymbolsToRemove.push_back(Sym);
 
  338    for (
auto *Sym : SymbolsToRemove) {
 
  340      G.removeExternalSymbol(*Sym);
 
 
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")
 
SmallPtrSet< const BasicBlock *, 8 > VisitedBlocks
 
Function const char * Passes
 
Implements a dense probed hash-table based set.
 
Lightweight error class with error context and mandatory checking.
 
static ErrorSuccess success()
Create a success value.
 
Tagged union holding either a T or a Error.
 
Error takeError()
Take ownership of the stored error.
 
DenseMap< orc::SymbolStringPtr, SymbolLookupFlags > LookupMap
 
Represents a finalized allocation.
 
void linkPhase4(std::unique_ptr< JITLinkerBase > Self, FinalizeResult FR)
 
void linkPhase3(std::unique_ptr< JITLinkerBase > Self, Expected< AsyncLookupResult > LookupResult)
 
Expected< std::unique_ptr< InFlightAlloc > > AllocResult
 
void linkPhase1(std::unique_ptr< JITLinkerBase > Self)
 
Expected< JITLinkMemoryManager::FinalizedAlloc > FinalizeResult
 
void linkPhase2(std::unique_ptr< JITLinkerBase > Self, AllocResult AR)
 
Represents an object file section.
 
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
 
std::unique_ptr< JITLinkAsyncLookupContinuation > createLookupContinuation(Continuation Cont)
Create a lookup continuation from a function object.
 
SymbolLookupFlags
Flags for symbol lookup.
 
void prune(LinkGraph &G)
Removes dead symbols/blocks/addressables.
 
DenseMap< orc::SymbolStringPtr, orc::ExecutorSymbolDef > AsyncLookupResult
A map of symbol names to resolved addresses.
 
std::vector< LinkGraphPassFunction > LinkGraphPassList
A list of LinkGraph passes.
 
This is an optimization pass for GlobalISel generic memory operations.
 
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
 
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
 
Error joinErrors(Error E1, Error E2)
Concatenate errors.
 
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.