Taints the non-acquire RMW's store address with the load part
[oota-llvm.git] / 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 "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   typedef std::vector<std::unique_ptr<object::ObjectFile>> OwningObjectVec;
41   typedef std::vector<std::unique_ptr<MemoryBuffer>> OwningBufferVec;
42
43 public:
44   /// @brief Handle to a set of compiled modules.
45   typedef ObjSetHandleT ModuleSetHandleT;
46
47   /// @brief Construct an IRCompileLayer with the given BaseLayer, which must
48   ///        implement the ObjectLayer concept.
49   IRCompileLayer(BaseLayerT &BaseLayer, CompileFtor Compile)
50       : BaseLayer(BaseLayer), Compile(std::move(Compile)), ObjCache(nullptr) {}
51
52   /// @brief Set an ObjectCache to query before compiling.
53   void setObjectCache(ObjectCache *NewCache) { ObjCache = NewCache; }
54
55   /// @brief Compile each module in the given module set, then add the resulting
56   ///        set of objects to the base layer along with the memory manager and
57   ///        symbol resolver.
58   ///
59   /// @return A handle for the added modules.
60   template <typename ModuleSetT, typename MemoryManagerPtrT,
61             typename SymbolResolverPtrT>
62   ModuleSetHandleT addModuleSet(ModuleSetT Ms,
63                                 MemoryManagerPtrT MemMgr,
64                                 SymbolResolverPtrT Resolver) {
65     OwningObjectVec Objects;
66     OwningBufferVec Buffers;
67
68     for (const auto &M : Ms) {
69       std::unique_ptr<object::ObjectFile> Object;
70       std::unique_ptr<MemoryBuffer> Buffer;
71
72       if (ObjCache)
73         std::tie(Object, Buffer) = tryToLoadFromObjectCache(*M).takeBinary();
74
75       if (!Object) {
76         std::tie(Object, Buffer) = Compile(*M).takeBinary();
77         if (ObjCache)
78           ObjCache->notifyObjectCompiled(&*M, Buffer->getMemBufferRef());
79       }
80
81       Objects.push_back(std::move(Object));
82       Buffers.push_back(std::move(Buffer));
83     }
84
85     ModuleSetHandleT H =
86       BaseLayer.addObjectSet(Objects, std::move(MemMgr), std::move(Resolver));
87
88     return H;
89   }
90
91   /// @brief Remove the module set associated with the handle H.
92   void removeModuleSet(ModuleSetHandleT H) { BaseLayer.removeObjectSet(H); }
93
94   /// @brief Search for the given named symbol.
95   /// @param Name The name of the symbol to search for.
96   /// @param ExportedSymbolsOnly If true, search only for exported symbols.
97   /// @return A handle for the given named symbol, if it exists.
98   JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
99     return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
100   }
101
102   /// @brief Get the address of the given symbol in the context of the set of
103   ///        compiled modules represented by the handle H. This call is
104   ///        forwarded to the base layer's implementation.
105   /// @param H The handle for the module set to search in.
106   /// @param Name The name of the symbol to search for.
107   /// @param ExportedSymbolsOnly If true, search only for exported symbols.
108   /// @return A handle for the given named symbol, if it is found in the
109   ///         given module set.
110   JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name,
111                          bool ExportedSymbolsOnly) {
112     return BaseLayer.findSymbolIn(H, Name, ExportedSymbolsOnly);
113   }
114
115   /// @brief Immediately emit and finalize the moduleOB set represented by the
116   ///        given handle.
117   /// @param H Handle for module set to emit/finalize.
118   void emitAndFinalize(ModuleSetHandleT H) {
119     BaseLayer.emitAndFinalize(H);
120   }
121
122 private:
123   object::OwningBinary<object::ObjectFile>
124   tryToLoadFromObjectCache(const Module &M) {
125     std::unique_ptr<MemoryBuffer> ObjBuffer = ObjCache->getObject(&M);
126     if (!ObjBuffer)
127       return object::OwningBinary<object::ObjectFile>();
128
129     ErrorOr<std::unique_ptr<object::ObjectFile>> Obj =
130         object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef());
131     if (!Obj)
132       return object::OwningBinary<object::ObjectFile>();
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