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