brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.7 KiB · 9a90af0 Raw
106 lines · cpp
1//===----- CompileOnDemandLayer.cpp - Lazily emit IR on first call --------===//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"10#include "llvm/ExecutionEngine/Orc/Layer.h"11#include "llvm/IR/Module.h"12 13using namespace llvm;14using namespace llvm::orc;15 16CompileOnDemandLayer::CompileOnDemandLayer(17    ExecutionSession &ES, IRLayer &BaseLayer, LazyCallThroughManager &LCTMgr,18    IndirectStubsManagerBuilder BuildIndirectStubsManager)19    : IRLayer(ES, BaseLayer.getManglingOptions()), BaseLayer(BaseLayer),20      LCTMgr(LCTMgr),21      BuildIndirectStubsManager(std::move(BuildIndirectStubsManager)) {}22 23void CompileOnDemandLayer::setImplMap(ImplSymbolMap *Imp) {24  this->AliaseeImpls = Imp;25}26 27void CompileOnDemandLayer::emit(28    std::unique_ptr<MaterializationResponsibility> R, ThreadSafeModule TSM) {29  assert(TSM && "Null module");30 31  auto &ES = getExecutionSession();32 33  // Sort the callables and non-callables, build re-exports and lodge the34  // actual module with the implementation dylib.35  auto &PDR = getPerDylibResources(R->getTargetJITDylib());36 37  SymbolAliasMap NonCallables;38  SymbolAliasMap Callables;39 40  for (auto &KV : R->getSymbols()) {41    auto &Name = KV.first;42    auto &Flags = KV.second;43    if (Flags.isCallable())44      Callables[Name] = SymbolAliasMapEntry(Name, Flags);45    else46      NonCallables[Name] = SymbolAliasMapEntry(Name, Flags);47  }48 49  // Lodge symbols with the implementation dylib.50  if (auto Err = PDR.getImplDylib().define(51          std::make_unique<BasicIRLayerMaterializationUnit>(52              BaseLayer, *getManglingOptions(), std::move(TSM)))) {53    ES.reportError(std::move(Err));54    R->failMaterialization();55    return;56  }57 58  if (!NonCallables.empty())59    if (auto Err =60            R->replace(reexports(PDR.getImplDylib(), std::move(NonCallables),61                                 JITDylibLookupFlags::MatchAllSymbols))) {62      getExecutionSession().reportError(std::move(Err));63      R->failMaterialization();64      return;65    }66  if (!Callables.empty()) {67    if (auto Err = R->replace(68            lazyReexports(LCTMgr, PDR.getISManager(), PDR.getImplDylib(),69                          std::move(Callables), AliaseeImpls))) {70      getExecutionSession().reportError(std::move(Err));71      R->failMaterialization();72      return;73    }74  }75}76 77CompileOnDemandLayer::PerDylibResources &78CompileOnDemandLayer::getPerDylibResources(JITDylib &TargetD) {79  std::lock_guard<std::mutex> Lock(CODLayerMutex);80 81  auto I = DylibResources.find(&TargetD);82  if (I == DylibResources.end()) {83    auto &ImplD =84        getExecutionSession().createBareJITDylib(TargetD.getName() + ".impl");85    JITDylibSearchOrder NewLinkOrder;86    TargetD.withLinkOrderDo([&](const JITDylibSearchOrder &TargetLinkOrder) {87      NewLinkOrder = TargetLinkOrder;88    });89 90    assert(!NewLinkOrder.empty() && NewLinkOrder.front().first == &TargetD &&91           NewLinkOrder.front().second ==92               JITDylibLookupFlags::MatchAllSymbols &&93           "TargetD must be at the front of its own search order and match "94           "non-exported symbol");95    NewLinkOrder.insert(std::next(NewLinkOrder.begin()),96                        {&ImplD, JITDylibLookupFlags::MatchAllSymbols});97    ImplD.setLinkOrder(NewLinkOrder, false);98    TargetD.setLinkOrder(std::move(NewLinkOrder), false);99 100    PerDylibResources PDR(ImplD, BuildIndirectStubsManager());101    I = DylibResources.insert(std::make_pair(&TargetD, std::move(PDR))).first;102  }103 104  return I->second;105}106