]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/ExecutionEngine/Orc/Legacy.h
Merge lld trunk r351319, resolve conflicts, and update FREEBSD-Xlist.
[FreeBSD/FreeBSD.git] / contrib / llvm / include / llvm / ExecutionEngine / Orc / Legacy.h
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   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 class LambdaSymbolResolver final : public SymbolResolver {
51 public:
52   template <typename GetResponsibilitySetFnRef, typename LookupFnRef>
53   LambdaSymbolResolver(GetResponsibilitySetFnRef &&GetResponsibilitySet,
54                        LookupFnRef &&Lookup)
55       : GetResponsibilitySet(
56             std::forward<GetResponsibilitySetFnRef>(GetResponsibilitySet)),
57         Lookup(std::forward<LookupFnRef>(Lookup)) {}
58
59   SymbolNameSet getResponsibilitySet(const SymbolNameSet &Symbols) final {
60     return GetResponsibilitySet(Symbols);
61   }
62
63   SymbolNameSet lookup(std::shared_ptr<AsynchronousSymbolQuery> Query,
64                        SymbolNameSet Symbols) final {
65     return Lookup(std::move(Query), std::move(Symbols));
66   }
67
68 private:
69   GetResponsibilitySetFn GetResponsibilitySet;
70   LookupFn Lookup;
71 };
72
73 /// Creates a SymbolResolver implementation from the pair of supplied
74 ///        function objects.
75 template <typename GetResponsibilitySetFn, typename LookupFn>
76 std::unique_ptr<LambdaSymbolResolver<
77     typename std::remove_cv<
78         typename std::remove_reference<GetResponsibilitySetFn>::type>::type,
79     typename std::remove_cv<
80         typename std::remove_reference<LookupFn>::type>::type>>
81 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       std::forward<LookupFn>(Lookup));
91 }
92
93 /// Legacy adapter. Remove once we kill off the old ORC layers.
94 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   SymbolResolver &R;
105   MaterializationResponsibility *MR;
106 };
107
108 /// 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 getResponsibilitySetWithLegacyFn(const SymbolNameSet &Symbols,
119                                  FindSymbolFn FindSymbol) {
120   SymbolNameSet Result;
121
122   for (auto &S : Symbols) {
123     if (JITSymbol Sym = FindSymbol(*S)) {
124       if (!Sym.getFlags().isStrong())
125         Result.insert(S);
126     } else if (auto Err = Sym.takeError())
127       return std::move(Err);
128   }
129
130   return Result;
131 }
132
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 ///        result in Query. If any JITSymbol returned by FindSymbol is in an
137 ///        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 ///
141 /// Useful for implementing lookup bodies that query legacy resolvers.
142 template <typename FindSymbolFn>
143 SymbolNameSet
144 lookupWithLegacyFn(ExecutionSession &ES, AsynchronousSymbolQuery &Query,
145                    const SymbolNameSet &Symbols, FindSymbolFn FindSymbol) {
146   SymbolNameSet SymbolsNotFound;
147   bool NewSymbolsResolved = false;
148
149   for (auto &S : Symbols) {
150     if (JITSymbol Sym = FindSymbol(*S)) {
151       if (auto Addr = Sym.getAddress()) {
152         Query.resolve(S, JITEvaluatedSymbol(*Addr, Sym.getFlags()));
153         Query.notifySymbolReady();
154         NewSymbolsResolved = true;
155       } else {
156         ES.legacyFailQuery(Query, Addr.takeError());
157         return SymbolNameSet();
158       }
159     } else if (auto Err = Sym.takeError()) {
160       ES.legacyFailQuery(Query, std::move(Err));
161       return SymbolNameSet();
162     } else
163       SymbolsNotFound.insert(S);
164   }
165
166   if (NewSymbolsResolved && Query.isFullyResolved())
167     Query.handleFullyResolved();
168
169   if (NewSymbolsResolved && Query.isFullyReady())
170     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
187   SymbolNameSet getResponsibilitySet(const SymbolNameSet &Symbols) final {
188     if (auto ResponsibilitySet =
189             getResponsibilitySetWithLegacyFn(Symbols, LegacyLookup))
190       return std::move(*ResponsibilitySet);
191     else {
192       ReportError(ResponsibilitySet.takeError());
193       return SymbolNameSet();
194     }
195   }
196
197   SymbolNameSet lookup(std::shared_ptr<AsynchronousSymbolQuery> Query,
198                        SymbolNameSet Symbols) final {
199     return lookupWithLegacyFn(ES, *Query, Symbols, LegacyLookup);
200   }
201
202 private:
203   ExecutionSession &ES;
204   LegacyLookupFn LegacyLookup;
205   ErrorReporter ReportError;
206 };
207
208 template <typename LegacyLookupFn>
209 std::shared_ptr<LegacyLookupFnResolver<LegacyLookupFn>>
210 createLegacyLookupResolver(ExecutionSession &ES, LegacyLookupFn LegacyLookup,
211                            std::function<void(Error)> ErrorReporter) {
212   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