diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 10:51:19 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 10:51:19 +0000 | 
| commit | eb11fae6d08f479c0799db45860a98af528fa6e7 (patch) | |
| tree | 44d492a50c8c1a7eb8e2d17ea3360ec4d066f042 /lib/ExecutionEngine/Orc/ExecutionUtils.cpp | |
| parent | b8a2042aa938069e862750553db0e4d82d25822c (diff) | |
Notes
Diffstat (limited to 'lib/ExecutionEngine/Orc/ExecutionUtils.cpp')
| -rw-r--r-- | lib/ExecutionEngine/Orc/ExecutionUtils.cpp | 154 | 
1 files changed, 150 insertions, 4 deletions
diff --git a/lib/ExecutionEngine/Orc/ExecutionUtils.cpp b/lib/ExecutionEngine/Orc/ExecutionUtils.cpp index b7220dba88e9..6157677ce355 100644 --- a/lib/ExecutionEngine/Orc/ExecutionUtils.cpp +++ b/lib/ExecutionEngine/Orc/ExecutionUtils.cpp @@ -13,10 +13,51 @@  #include "llvm/IR/Function.h"  #include "llvm/IR/GlobalVariable.h"  #include "llvm/IR/Module.h" +#include "llvm/Support/TargetRegistry.h" +#include "llvm/Target/TargetMachine.h"  namespace llvm {  namespace orc { +JITTargetMachineBuilder::JITTargetMachineBuilder(Triple TT) +    : TT(std::move(TT)) {} + +Expected<JITTargetMachineBuilder> JITTargetMachineBuilder::detectHost() { +  return JITTargetMachineBuilder(Triple(sys::getProcessTriple())); +} + +Expected<std::unique_ptr<TargetMachine>> +JITTargetMachineBuilder::createTargetMachine() { +  if (!Arch.empty()) { +    Triple::ArchType Type = Triple::getArchTypeForLLVMName(Arch); + +    if (Type == Triple::UnknownArch) +      return make_error<StringError>(std::string("Unknown arch: ") + Arch, +                                     inconvertibleErrorCode()); +  } + +  std::string ErrMsg; +  auto *TheTarget = TargetRegistry::lookupTarget(TT.getTriple(), ErrMsg); +  if (!TheTarget) +    return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode()); + +  auto *TM = +      TheTarget->createTargetMachine(TT.getTriple(), CPU, Features.getString(), +                                     Options, RM, CM, OptLevel, /*JIT*/ true); +  if (!TM) +    return make_error<StringError>("Could not allocate target machine", +                                   inconvertibleErrorCode()); + +  return std::unique_ptr<TargetMachine>(TM); +} + +JITTargetMachineBuilder &JITTargetMachineBuilder::addFeatures( +    const std::vector<std::string> &FeatureVec) { +  for (const auto &F : FeatureVec) +    Features.AddFeature(F); +  return *this; +} +  CtorDtorIterator::CtorDtorIterator(const GlobalVariable *GV, bool End)    : InitList(        GV ? dyn_cast_or_null<ConstantArray>(GV->getInitializer()) : nullptr), @@ -67,7 +108,9 @@ CtorDtorIterator::Element CtorDtorIterator::operator*() const {    }    ConstantInt *Priority = dyn_cast<ConstantInt>(CS->getOperand(0)); -  Value *Data = CS->getOperand(2); +  Value *Data = CS->getNumOperands() == 3 ? CS->getOperand(2) : nullptr; +  if (Data && !isa<GlobalValue>(Data)) +    Data = nullptr;    return Element(Priority->getZExtValue(), Func, Data);  } @@ -83,20 +126,123 @@ iterator_range<CtorDtorIterator> getDestructors(const Module &M) {                      CtorDtorIterator(DtorsList, true));  } -void LocalCXXRuntimeOverrides::runDestructors() { +void CtorDtorRunner2::add(iterator_range<CtorDtorIterator> CtorDtors) { +  if (CtorDtors.begin() == CtorDtors.end()) +    return; + +  MangleAndInterner Mangle( +      V.getExecutionSession(), +      (*CtorDtors.begin()).Func->getParent()->getDataLayout()); + +  for (const auto &CtorDtor : CtorDtors) { +    assert(CtorDtor.Func && CtorDtor.Func->hasName() && +           "Ctor/Dtor function must be named to be runnable under the JIT"); + +    if (CtorDtor.Data && cast<GlobalValue>(CtorDtor.Data)->isDeclaration()) { +      dbgs() << "  Skipping because why now?\n"; +      continue; +    } + +    CtorDtorsByPriority[CtorDtor.Priority].push_back( +        Mangle(CtorDtor.Func->getName())); +  } +} + +Error CtorDtorRunner2::run() { +  using CtorDtorTy = void (*)(); + +  SymbolNameSet Names; + +  for (auto &KV : CtorDtorsByPriority) { +    for (auto &Name : KV.second) { +      auto Added = Names.insert(Name).second; +      (void)Added; +      assert(Added && "Ctor/Dtor names clashed"); +    } +  } + +  if (auto CtorDtorMap = lookup({&V}, std::move(Names))) { +    for (auto &KV : CtorDtorsByPriority) { +      for (auto &Name : KV.second) { +        assert(CtorDtorMap->count(Name) && "No entry for Name"); +        auto CtorDtor = reinterpret_cast<CtorDtorTy>( +            static_cast<uintptr_t>((*CtorDtorMap)[Name].getAddress())); +        CtorDtor(); +      } +    } +    return Error::success(); +  } else +    return CtorDtorMap.takeError(); + +  CtorDtorsByPriority.clear(); + +  return Error::success(); +} + +void LocalCXXRuntimeOverridesBase::runDestructors() {    auto& CXXDestructorDataPairs = DSOHandleOverride;    for (auto &P : CXXDestructorDataPairs)      P.first(P.second);    CXXDestructorDataPairs.clear();  } -int LocalCXXRuntimeOverrides::CXAAtExitOverride(DestructorPtr Destructor, -                                                void *Arg, void *DSOHandle) { +int LocalCXXRuntimeOverridesBase::CXAAtExitOverride(DestructorPtr Destructor, +                                                    void *Arg, +                                                    void *DSOHandle) {    auto& CXXDestructorDataPairs =      *reinterpret_cast<CXXDestructorDataPairList*>(DSOHandle);    CXXDestructorDataPairs.push_back(std::make_pair(Destructor, Arg));    return 0;  } +Error LocalCXXRuntimeOverrides2::enable(VSO &V, MangleAndInterner &Mangle) { +  SymbolMap RuntimeInterposes( +      {{Mangle("__dso_handle"), +        JITEvaluatedSymbol(toTargetAddress(&DSOHandleOverride), +                           JITSymbolFlags::Exported)}, +       {Mangle("__cxa_atexit"), +        JITEvaluatedSymbol(toTargetAddress(&CXAAtExitOverride), +                           JITSymbolFlags::Exported)}}); + +  return V.define(absoluteSymbols(std::move(RuntimeInterposes))); +} + +DynamicLibraryFallbackGenerator::DynamicLibraryFallbackGenerator( +    sys::DynamicLibrary Dylib, const DataLayout &DL, SymbolPredicate Allow) +    : Dylib(std::move(Dylib)), Allow(std::move(Allow)), +      GlobalPrefix(DL.getGlobalPrefix()) {} + +SymbolNameSet DynamicLibraryFallbackGenerator:: +operator()(VSO &V, const SymbolNameSet &Names) { +  orc::SymbolNameSet Added; +  orc::SymbolMap NewSymbols; + +  bool HasGlobalPrefix = (GlobalPrefix != '\0'); + +  for (auto &Name : Names) { +    if (!Allow(Name) || (*Name).empty()) +      continue; + +    if (HasGlobalPrefix && (*Name).front() != GlobalPrefix) +      continue; + +    std::string Tmp((*Name).data() + (HasGlobalPrefix ? 1 : 0), (*Name).size()); +    if (void *Addr = Dylib.getAddressOfSymbol(Tmp.c_str())) { +      Added.insert(Name); +      NewSymbols[Name] = JITEvaluatedSymbol( +          static_cast<JITTargetAddress>(reinterpret_cast<uintptr_t>(Addr)), +          JITSymbolFlags::Exported); +    } +  } + +  // Add any new symbols to V. Since the fallback generator is only called for +  // symbols that are not already defined, this will never trigger a duplicate +  // definition error, so we can wrap this call in a 'cantFail'. +  if (!NewSymbols.empty()) +    cantFail(V.define(absoluteSymbols(std::move(NewSymbols)))); + +  return Added; +} +  } // End namespace orc.  } // End namespace llvm.  | 
