]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h
Merge compiler-rt trunk r291476.
[FreeBSD/FreeBSD.git] / contrib / llvm / include / llvm / ExecutionEngine / Orc / IRCompileLayer.h
1 //===------ IRCompileLayer.h -- Eagerly compile IR for JIT ------*- 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 the definition for a basic, eagerly compiling layer of the JIT.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_EXECUTIONENGINE_ORC_IRCOMPILELAYER_H
15 #define LLVM_EXECUTIONENGINE_ORC_IRCOMPILELAYER_H
16
17 #include "llvm/ExecutionEngine/ObjectCache.h"
18 #include "llvm/ExecutionEngine/JITSymbol.h"
19 #include "llvm/Object/ObjectFile.h"
20 #include <memory>
21
22 namespace llvm {
23 namespace orc {
24
25 /// @brief Eager IR compiling layer.
26 ///
27 ///   This layer accepts sets of LLVM IR Modules (via addModuleSet). It
28 /// immediately compiles each IR module to an object file (each IR Module is
29 /// compiled separately). The resulting set of object files is then added to
30 /// the layer below, which must implement the object layer concept.
31 template <typename BaseLayerT> class IRCompileLayer {
32 public:
33   typedef std::function<object::OwningBinary<object::ObjectFile>(Module &)>
34       CompileFtor;
35
36 private:
37   typedef typename BaseLayerT::ObjSetHandleT ObjSetHandleT;
38
39 public:
40   /// @brief Handle to a set of compiled modules.
41   typedef ObjSetHandleT ModuleSetHandleT;
42
43   /// @brief Construct an IRCompileLayer with the given BaseLayer, which must
44   ///        implement the ObjectLayer concept.
45   IRCompileLayer(BaseLayerT &BaseLayer, CompileFtor Compile)
46       : BaseLayer(BaseLayer), Compile(std::move(Compile)), ObjCache(nullptr) {}
47
48   /// @brief Set an ObjectCache to query before compiling.
49   void setObjectCache(ObjectCache *NewCache) { ObjCache = NewCache; }
50
51   /// @brief Compile each module in the given module set, then add the resulting
52   ///        set of objects to the base layer along with the memory manager and
53   ///        symbol resolver.
54   ///
55   /// @return A handle for the added modules.
56   template <typename ModuleSetT, typename MemoryManagerPtrT,
57             typename SymbolResolverPtrT>
58   ModuleSetHandleT addModuleSet(ModuleSetT Ms,
59                                 MemoryManagerPtrT MemMgr,
60                                 SymbolResolverPtrT Resolver) {
61     std::vector<std::unique_ptr<object::OwningBinary<object::ObjectFile>>>
62       Objects;
63
64     for (const auto &M : Ms) {
65       auto Object =
66         llvm::make_unique<object::OwningBinary<object::ObjectFile>>();
67
68       if (ObjCache)
69         *Object = tryToLoadFromObjectCache(*M);
70
71       if (!Object->getBinary()) {
72         *Object = Compile(*M);
73         if (ObjCache)
74           ObjCache->notifyObjectCompiled(&*M,
75                                      Object->getBinary()->getMemoryBufferRef());
76       }
77
78       Objects.push_back(std::move(Object));
79     }
80
81     ModuleSetHandleT H =
82       BaseLayer.addObjectSet(std::move(Objects), std::move(MemMgr),
83                              std::move(Resolver));
84
85     return H;
86   }
87
88   /// @brief Remove the module set associated with the handle H.
89   void removeModuleSet(ModuleSetHandleT H) { BaseLayer.removeObjectSet(H); }
90
91   /// @brief Search for the given named symbol.
92   /// @param Name The name of the symbol to search for.
93   /// @param ExportedSymbolsOnly If true, search only for exported symbols.
94   /// @return A handle for the given named symbol, if it exists.
95   JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
96     return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
97   }
98
99   /// @brief Get the address of the given symbol in the context of the set of
100   ///        compiled modules represented by the handle H. This call is
101   ///        forwarded to the base layer's implementation.
102   /// @param H The handle for the module set to search in.
103   /// @param Name The name of the symbol to search for.
104   /// @param ExportedSymbolsOnly If true, search only for exported symbols.
105   /// @return A handle for the given named symbol, if it is found in the
106   ///         given module set.
107   JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name,
108                          bool ExportedSymbolsOnly) {
109     return BaseLayer.findSymbolIn(H, Name, ExportedSymbolsOnly);
110   }
111
112   /// @brief Immediately emit and finalize the moduleOB set represented by the
113   ///        given handle.
114   /// @param H Handle for module set to emit/finalize.
115   void emitAndFinalize(ModuleSetHandleT H) {
116     BaseLayer.emitAndFinalize(H);
117   }
118
119 private:
120   object::OwningBinary<object::ObjectFile>
121   tryToLoadFromObjectCache(const Module &M) {
122     std::unique_ptr<MemoryBuffer> ObjBuffer = ObjCache->getObject(&M);
123     if (!ObjBuffer)
124       return object::OwningBinary<object::ObjectFile>();
125
126     Expected<std::unique_ptr<object::ObjectFile>> Obj =
127         object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef());
128     if (!Obj) {
129       // TODO: Actually report errors helpfully.
130       consumeError(Obj.takeError());
131       return object::OwningBinary<object::ObjectFile>();
132     }
133
134     return object::OwningBinary<object::ObjectFile>(std::move(*Obj),
135                                                     std::move(ObjBuffer));
136   }
137
138   BaseLayerT &BaseLayer;
139   CompileFtor Compile;
140   ObjectCache *ObjCache;
141 };
142
143 } // End namespace orc.
144 } // End namespace llvm.
145
146 #endif // LLVM_EXECUTIONENGINE_ORC_IRCOMPILINGLAYER_H