LCOV - code coverage report
Current view: top level - include/llvm/ExecutionEngine/Orc - Legacy.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 39 64 60.9 %
Date: 2018-10-20 13:21:21 Functions: 10 20 50.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===--- Legacy.h -- Adapters for ExecutionEngine API interop ---*- C++ -*-===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : // Contains core ORC APIs.
      11             : //
      12             : //===----------------------------------------------------------------------===//
      13             : 
      14             : #ifndef LLVM_EXECUTIONENGINE_ORC_LEGACY_H
      15             : #define LLVM_EXECUTIONENGINE_ORC_LEGACY_H
      16             : 
      17             : #include "llvm/ExecutionEngine/JITSymbol.h"
      18             : #include "llvm/ExecutionEngine/Orc/Core.h"
      19             : 
      20             : namespace llvm {
      21             : namespace orc {
      22             : 
      23             : /// SymbolResolver is a composable interface for looking up symbol flags
      24             : ///        and addresses using the AsynchronousSymbolQuery type. It will
      25             : ///        eventually replace the LegacyJITSymbolResolver interface as the
      26             : ///        stardard ORC symbol resolver type.
      27             : ///
      28             : /// FIXME: SymbolResolvers should go away and be replaced with VSOs with
      29             : ///        defenition generators.
      30             : class SymbolResolver {
      31             : public:
      32           0 :   virtual ~SymbolResolver() = default;
      33             : 
      34             :   /// Returns the subset of the given symbols that the caller is responsible for
      35             :   /// materializing.
      36             :   virtual SymbolNameSet getResponsibilitySet(const SymbolNameSet &Symbols) = 0;
      37             : 
      38             :   /// For each symbol in Symbols that can be found, assigns that symbols
      39             :   /// value in Query. Returns the set of symbols that could not be found.
      40             :   virtual SymbolNameSet lookup(std::shared_ptr<AsynchronousSymbolQuery> Query,
      41             :                                SymbolNameSet Symbols) = 0;
      42             : 
      43             : private:
      44             :   virtual void anchor();
      45             : };
      46             : 
      47             : /// Implements SymbolResolver with a pair of supplied function objects
      48             : ///        for convenience. See createSymbolResolver.
      49             : template <typename GetResponsibilitySetFn, typename LookupFn>
      50           3 : class LambdaSymbolResolver final : public SymbolResolver {
      51             : public:
      52             :   template <typename GetResponsibilitySetFnRef, typename LookupFnRef>
      53           3 :   LambdaSymbolResolver(GetResponsibilitySetFnRef &&GetResponsibilitySet,
      54             :                        LookupFnRef &&Lookup)
      55             :       : GetResponsibilitySet(
      56             :             std::forward<GetResponsibilitySetFnRef>(GetResponsibilitySet)),
      57           3 :         Lookup(std::forward<LookupFnRef>(Lookup)) {}
      58             : 
      59           2 :   SymbolNameSet getResponsibilitySet(const SymbolNameSet &Symbols) final {
      60           3 :     return GetResponsibilitySet(Symbols);
      61             :   }
      62           0 : 
      63           2 :   SymbolNameSet lookup(std::shared_ptr<AsynchronousSymbolQuery> Query,
      64             :                        SymbolNameSet Symbols) final {
      65           4 :     return Lookup(std::move(Query), std::move(Symbols));
      66           1 :   }
      67             : 
      68             : private:
      69           1 :   GetResponsibilitySetFn GetResponsibilitySet;
      70             :   LookupFn Lookup;
      71           3 : };
      72             : 
      73           0 : /// Creates a SymbolResolver implementation from the pair of supplied
      74             : ///        function objects.
      75           0 : template <typename GetResponsibilitySetFn, typename LookupFn>
      76             : std::unique_ptr<LambdaSymbolResolver<
      77           1 :     typename std::remove_cv<
      78             :         typename std::remove_reference<GetResponsibilitySetFn>::type>::type,
      79           3 :     typename std::remove_cv<
      80             :         typename std::remove_reference<LookupFn>::type>::type>>
      81           0 : createSymbolResolver(GetResponsibilitySetFn &&GetResponsibilitySet,
      82             :                      LookupFn &&Lookup) {
      83             :   using LambdaSymbolResolverImpl = LambdaSymbolResolver<
      84             :       typename std::remove_cv<
      85             :           typename std::remove_reference<GetResponsibilitySetFn>::type>::type,
      86             :       typename std::remove_cv<
      87             :           typename std::remove_reference<LookupFn>::type>::type>;
      88             :   return llvm::make_unique<LambdaSymbolResolverImpl>(
      89             :       std::forward<GetResponsibilitySetFn>(GetResponsibilitySet),
      90           0 :       std::forward<LookupFn>(Lookup));
      91             : }
      92             : 
      93             : /// Legacy adapter. Remove once we kill off the old ORC layers.
      94           9 : class JITSymbolResolverAdapter : public JITSymbolResolver {
      95             : public:
      96             :   JITSymbolResolverAdapter(ExecutionSession &ES, SymbolResolver &R,
      97             :                            MaterializationResponsibility *MR);
      98             :   Expected<LookupSet> getResponsibilitySet(const LookupSet &Symbols) override;
      99             :   void lookup(const LookupSet &Symbols, OnResolvedFunction OnResolved) override;
     100             : 
     101             : private:
     102             :   ExecutionSession &ES;
     103             :   std::set<SymbolStringPtr> ResolvedStrings;
     104           1 :   SymbolResolver &R;
     105             :   MaterializationResponsibility *MR;
     106             : };
     107             : 
     108          93 : /// Use the given legacy-style FindSymbol function (i.e. a function that takes
     109             : /// a const std::string& or StringRef and returns a JITSymbol) to get the
     110             : /// subset of symbols that the caller is responsible for materializing. If any
     111             : /// JITSymbol returned by FindSymbol is in an error state the function returns
     112             : /// immediately with that error.
     113             : ///
     114             : /// Useful for implementing getResponsibilitySet bodies that query legacy
     115             : /// resolvers.
     116             : template <typename FindSymbolFn>
     117             : Expected<SymbolNameSet>
     118           2 : getResponsibilitySetWithLegacyFn(const SymbolNameSet &Symbols,
     119             :                                  FindSymbolFn FindSymbol) {
     120             :   SymbolNameSet Result;
     121             : 
     122           4 :   for (auto &S : Symbols) {
     123           8 :     if (JITSymbol Sym = FindSymbol(*S)) {
     124             :       if (!Sym.getFlags().isStrong())
     125             :         Result.insert(S);
     126           1 :     } else if (auto Err = Sym.takeError())
     127             :       return std::move(Err);
     128             :   }
     129             : 
     130             :   return Result;
     131             : }
     132           1 : 
     133             : /// Use the given legacy-style FindSymbol function (i.e. a function that
     134             : ///        takes a const std::string& or StringRef and returns a JITSymbol) to
     135             : ///        find the address and flags for each symbol in Symbols and store the
     136           1 : ///        result in Query. If any JITSymbol returned by FindSymbol is in an
     137           0 : ///        error then Query.notifyFailed(...) is called with that error and the
     138             : ///        function returns immediately. On success, returns the set of symbols
     139             : ///        not found.
     140           0 : ///
     141             : /// Useful for implementing lookup bodies that query legacy resolvers.
     142             : template <typename FindSymbolFn>
     143             : SymbolNameSet
     144           2 : lookupWithLegacyFn(ExecutionSession &ES, AsynchronousSymbolQuery &Query,
     145             :                    const SymbolNameSet &Symbols, FindSymbolFn FindSymbol) {
     146           1 :   SymbolNameSet SymbolsNotFound;
     147             :   bool NewSymbolsResolved = false;
     148             : 
     149           6 :   for (auto &S : Symbols) {
     150          17 :     if (JITSymbol Sym = FindSymbol(*S)) {
     151           3 :       if (auto Addr = Sym.getAddress()) {
     152           6 :         Query.resolve(S, JITEvaluatedSymbol(*Addr, Sym.getFlags()));
     153           3 :         Query.notifySymbolReady();
     154           0 :         NewSymbolsResolved = true;
     155             :       } else {
     156           0 :         ES.legacyFailQuery(Query, Addr.takeError());
     157           0 :         return SymbolNameSet();
     158             :       }
     159           1 :     } else if (auto Err = Sym.takeError()) {
     160           0 :       ES.legacyFailQuery(Query, std::move(Err));
     161           0 :       return SymbolNameSet();
     162             :     } else
     163             :       SymbolsNotFound.insert(S);
     164           0 :   }
     165           0 : 
     166           2 :   if (NewSymbolsResolved && Query.isFullyResolved())
     167           2 :     Query.handleFullyResolved();
     168           0 : 
     169           2 :   if (NewSymbolsResolved && Query.isFullyReady())
     170           2 :     Query.handleFullyReady();
     171             : 
     172             :   return SymbolsNotFound;
     173             : }
     174             : 
     175             : /// An ORC SymbolResolver implementation that uses a legacy
     176             : ///        findSymbol-like function to perform lookup;
     177             : template <typename LegacyLookupFn>
     178             : class LegacyLookupFnResolver final : public SymbolResolver {
     179             : public:
     180             :   using ErrorReporter = std::function<void(Error)>;
     181             : 
     182             :   LegacyLookupFnResolver(ExecutionSession &ES, LegacyLookupFn LegacyLookup,
     183             :                          ErrorReporter ReportError)
     184             :       : ES(ES), LegacyLookup(std::move(LegacyLookup)),
     185             :         ReportError(std::move(ReportError)) {}
     186           1 : 
     187             :   SymbolNameSet getResponsibilitySet(const SymbolNameSet &Symbols) final {
     188             :     if (auto ResponsibilitySet =
     189             :             getResponsibilitySetWithLegacyFn(Symbols, LegacyLookup))
     190             :       return std::move(*ResponsibilitySet);
     191           2 :     else {
     192           4 :       ReportError(ResponsibilitySet.takeError());
     193           0 :       return SymbolNameSet();
     194           0 :     }
     195           0 :   }
     196             : 
     197             :   SymbolNameSet lookup(std::shared_ptr<AsynchronousSymbolQuery> Query,
     198           0 :                        SymbolNameSet Symbols) final {
     199           0 :     return lookupWithLegacyFn(ES, *Query, Symbols, LegacyLookup);
     200             :   }
     201           1 : 
     202           0 : private:
     203           0 :   ExecutionSession &ES;
     204             :   LegacyLookupFn LegacyLookup;
     205             :   ErrorReporter ReportError;
     206             : };
     207             : 
     208           1 : template <typename LegacyLookupFn>
     209           0 : std::shared_ptr<LegacyLookupFnResolver<LegacyLookupFn>>
     210             : createLegacyLookupResolver(ExecutionSession &ES, LegacyLookupFn LegacyLookup,
     211           1 :                            std::function<void(Error)> ErrorReporter) {
     212           0 :   return std::make_shared<LegacyLookupFnResolver<LegacyLookupFn>>(
     213             :       ES, std::move(LegacyLookup), std::move(ErrorReporter));
     214             : }
     215             : 
     216             : } // End namespace orc
     217             : } // End namespace llvm
     218             : 
     219             : #endif // LLVM_EXECUTIONENGINE_ORC_LEGACY_H

Generated by: LCOV version 1.13