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 /include/llvm/ExecutionEngine/Orc/Legacy.h | |
| parent | b8a2042aa938069e862750553db0e4d82d25822c (diff) | |
Notes
Diffstat (limited to 'include/llvm/ExecutionEngine/Orc/Legacy.h')
| -rw-r--r-- | include/llvm/ExecutionEngine/Orc/Legacy.h | 211 | 
1 files changed, 211 insertions, 0 deletions
diff --git a/include/llvm/ExecutionEngine/Orc/Legacy.h b/include/llvm/ExecutionEngine/Orc/Legacy.h new file mode 100644 index 000000000000..52c8c162ff0b --- /dev/null +++ b/include/llvm/ExecutionEngine/Orc/Legacy.h @@ -0,0 +1,211 @@ +//===--- Legacy.h -- Adapters for ExecutionEngine API interop ---*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Contains core ORC APIs. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_EXECUTIONENGINE_ORC_LEGACY_H +#define LLVM_EXECUTIONENGINE_ORC_LEGACY_H + +#include "llvm/ExecutionEngine/JITSymbol.h" +#include "llvm/ExecutionEngine/Orc/Core.h" + +namespace llvm { +namespace orc { + +/// SymbolResolver is a composable interface for looking up symbol flags +///        and addresses using the AsynchronousSymbolQuery type. It will +///        eventually replace the LegacyJITSymbolResolver interface as the +///        stardard ORC symbol resolver type. +/// +/// FIXME: SymbolResolvers should go away and be replaced with VSOs with +///        defenition generators. +class SymbolResolver { +public: +  virtual ~SymbolResolver() = default; + +  /// Returns the flags for each symbol in Symbols that can be found, +  ///        along with the set of symbol that could not be found. +  virtual SymbolFlagsMap lookupFlags(const SymbolNameSet &Symbols) = 0; + +  /// For each symbol in Symbols that can be found, assigns that symbols +  ///        value in Query. Returns the set of symbols that could not be found. +  virtual SymbolNameSet lookup(std::shared_ptr<AsynchronousSymbolQuery> Query, +                               SymbolNameSet Symbols) = 0; + +private: +  virtual void anchor(); +}; + +/// Implements SymbolResolver with a pair of supplied function objects +///        for convenience. See createSymbolResolver. +template <typename LookupFlagsFn, typename LookupFn> +class LambdaSymbolResolver final : public SymbolResolver { +public: +  template <typename LookupFlagsFnRef, typename LookupFnRef> +  LambdaSymbolResolver(LookupFlagsFnRef &&LookupFlags, LookupFnRef &&Lookup) +      : LookupFlags(std::forward<LookupFlagsFnRef>(LookupFlags)), +        Lookup(std::forward<LookupFnRef>(Lookup)) {} + +  SymbolFlagsMap lookupFlags(const SymbolNameSet &Symbols) final { +    return LookupFlags(Symbols); +  } + +  SymbolNameSet lookup(std::shared_ptr<AsynchronousSymbolQuery> Query, +                       SymbolNameSet Symbols) final { +    return Lookup(std::move(Query), std::move(Symbols)); +  } + +private: +  LookupFlagsFn LookupFlags; +  LookupFn Lookup; +}; + +/// Creates a SymbolResolver implementation from the pair of supplied +///        function objects. +template <typename LookupFlagsFn, typename LookupFn> +std::unique_ptr<LambdaSymbolResolver< +    typename std::remove_cv< +        typename std::remove_reference<LookupFlagsFn>::type>::type, +    typename std::remove_cv< +        typename std::remove_reference<LookupFn>::type>::type>> +createSymbolResolver(LookupFlagsFn &&LookupFlags, LookupFn &&Lookup) { +  using LambdaSymbolResolverImpl = LambdaSymbolResolver< +      typename std::remove_cv< +          typename std::remove_reference<LookupFlagsFn>::type>::type, +      typename std::remove_cv< +          typename std::remove_reference<LookupFn>::type>::type>; +  return llvm::make_unique<LambdaSymbolResolverImpl>( +      std::forward<LookupFlagsFn>(LookupFlags), std::forward<LookupFn>(Lookup)); +} + +class JITSymbolResolverAdapter : public JITSymbolResolver { +public: +  JITSymbolResolverAdapter(ExecutionSession &ES, SymbolResolver &R, +                           MaterializationResponsibility *MR); +  Expected<LookupFlagsResult> lookupFlags(const LookupSet &Symbols) override; +  Expected<LookupResult> lookup(const LookupSet &Symbols) override; + +private: +  ExecutionSession &ES; +  std::set<SymbolStringPtr> ResolvedStrings; +  SymbolResolver &R; +  MaterializationResponsibility *MR; +}; + +/// Use the given legacy-style FindSymbol function (i.e. a function that +///        takes a const std::string& or StringRef and returns a JITSymbol) to +///        find the flags for each symbol in Symbols and store their flags in +///        SymbolFlags. If any JITSymbol returned by FindSymbol is in an error +///        state the function returns immediately with that error, otherwise it +///        returns the set of symbols not found. +/// +/// Useful for implementing lookupFlags bodies that query legacy resolvers. +template <typename FindSymbolFn> +Expected<SymbolFlagsMap> lookupFlagsWithLegacyFn(const SymbolNameSet &Symbols, +                                                 FindSymbolFn FindSymbol) { +  SymbolFlagsMap SymbolFlags; + +  for (auto &S : Symbols) { +    if (JITSymbol Sym = FindSymbol(*S)) +      SymbolFlags[S] = Sym.getFlags(); +    else if (auto Err = Sym.takeError()) +      return std::move(Err); +  } + +  return SymbolFlags; +} + +/// Use the given legacy-style FindSymbol function (i.e. a function that +///        takes a const std::string& or StringRef and returns a JITSymbol) to +///        find the address and flags for each symbol in Symbols and store the +///        result in Query. If any JITSymbol returned by FindSymbol is in an +///        error then Query.notifyFailed(...) is called with that error and the +///        function returns immediately. On success, returns the set of symbols +///        not found. +/// +/// Useful for implementing lookup bodies that query legacy resolvers. +template <typename FindSymbolFn> +SymbolNameSet +lookupWithLegacyFn(ExecutionSession &ES, AsynchronousSymbolQuery &Query, +                   const SymbolNameSet &Symbols, FindSymbolFn FindSymbol) { +  SymbolNameSet SymbolsNotFound; +  bool NewSymbolsResolved = false; + +  for (auto &S : Symbols) { +    if (JITSymbol Sym = FindSymbol(*S)) { +      if (auto Addr = Sym.getAddress()) { +        Query.resolve(S, JITEvaluatedSymbol(*Addr, Sym.getFlags())); +        Query.notifySymbolReady(); +        NewSymbolsResolved = true; +      } else { +        ES.legacyFailQuery(Query, Addr.takeError()); +        return SymbolNameSet(); +      } +    } else if (auto Err = Sym.takeError()) { +      ES.legacyFailQuery(Query, std::move(Err)); +      return SymbolNameSet(); +    } else +      SymbolsNotFound.insert(S); +  } + +  if (NewSymbolsResolved && Query.isFullyResolved()) +    Query.handleFullyResolved(); + +  if (NewSymbolsResolved && Query.isFullyReady()) +    Query.handleFullyReady(); + +  return SymbolsNotFound; +} + +/// An ORC SymbolResolver implementation that uses a legacy +///        findSymbol-like function to perform lookup; +template <typename LegacyLookupFn> +class LegacyLookupFnResolver final : public SymbolResolver { +public: +  using ErrorReporter = std::function<void(Error)>; + +  LegacyLookupFnResolver(ExecutionSession &ES, LegacyLookupFn LegacyLookup, +                         ErrorReporter ReportError) +      : ES(ES), LegacyLookup(std::move(LegacyLookup)), +        ReportError(std::move(ReportError)) {} + +  SymbolFlagsMap lookupFlags(const SymbolNameSet &Symbols) final { +    if (auto SymbolFlags = lookupFlagsWithLegacyFn(Symbols, LegacyLookup)) +      return std::move(*SymbolFlags); +    else { +      ReportError(SymbolFlags.takeError()); +      return SymbolFlagsMap(); +    } +  } + +  SymbolNameSet lookup(std::shared_ptr<AsynchronousSymbolQuery> Query, +                       SymbolNameSet Symbols) final { +    return lookupWithLegacyFn(ES, *Query, Symbols, LegacyLookup); +  } + +private: +  ExecutionSession &ES; +  LegacyLookupFn LegacyLookup; +  ErrorReporter ReportError; +}; + +template <typename LegacyLookupFn> +std::shared_ptr<LegacyLookupFnResolver<LegacyLookupFn>> +createLegacyLookupResolver(ExecutionSession &ES, LegacyLookupFn LegacyLookup, +                           std::function<void(Error)> ErrorReporter) { +  return std::make_shared<LegacyLookupFnResolver<LegacyLookupFn>>( +      ES, std::move(LegacyLookup), std::move(ErrorReporter)); +} + +} // End namespace orc +} // End namespace llvm + +#endif // LLVM_EXECUTIONENGINE_ORC_LEGACY_H  | 
