1 | /** |
2 | * Copyright (c) Glow Contributors. See CONTRIBUTORS file. |
3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. |
6 | * You may obtain a copy of the License at |
7 | * |
8 | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | * |
10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. |
15 | */ |
16 | #ifndef GLOW_LLVMIRCODEGEN_GLOWJIT_H |
17 | #define GLOW_LLVMIRCODEGEN_GLOWJIT_H |
18 | |
19 | #include "llvm/ADT/STLExtras.h" |
20 | #include "llvm/ExecutionEngine/ExecutionEngine.h" |
21 | #include "llvm/ExecutionEngine/JITSymbol.h" |
22 | #include "llvm/ExecutionEngine/Orc/CompileUtils.h" |
23 | #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" |
24 | #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h" |
25 | #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h" |
26 | #include "llvm/ExecutionEngine/Orc/SymbolStringPool.h" |
27 | #include "llvm/ExecutionEngine/RTDyldMemoryManager.h" |
28 | #include "llvm/ExecutionEngine/SectionMemoryManager.h" |
29 | #include "llvm/IR/DataLayout.h" |
30 | #include "llvm/IR/Mangler.h" |
31 | #include "llvm/Support/DynamicLibrary.h" |
32 | #include "llvm/Support/raw_ostream.h" |
33 | #include "llvm/Target/TargetMachine.h" |
34 | #include <algorithm> |
35 | #include <memory> |
36 | #include <string> |
37 | #include <vector> |
38 | |
39 | #ifndef GLOW_JIT_ORC_VERSION |
40 | #if LLVM_VERSION_MAJOR < 11 |
41 | #define GLOW_JIT_ORC_VERSION 1 |
42 | #else |
43 | #define GLOW_JIT_ORC_VERSION 2 |
44 | #endif |
45 | #endif |
46 | |
47 | //############################################################################## |
48 | #if GLOW_JIT_ORC_VERSION == 1 |
49 | //############################################################################## |
50 | namespace llvm { |
51 | namespace orc { |
52 | |
53 | // A class that represents a simple LLVM-based Orc JIT. Based on the |
54 | // KaleidoscopeJIT example in the LLVM tree. |
55 | class GlowJIT { |
56 | private: |
57 | std::unique_ptr<llvm::TargetMachine> TM_; |
58 | const DataLayout DL_; |
59 | std::unique_ptr<llvm::LLVMContext> ctx_; |
60 | #if FACEBOOK_INTERNAL && LLVM_VERSION_MAJOR < 8 |
61 | SymbolStringPool SSP_; |
62 | ExecutionSession ES_; |
63 | std::shared_ptr<SymbolResolver> resolver_; |
64 | #else |
65 | std::shared_ptr<SymbolStringPool> SSP_; |
66 | ExecutionSession ES_; |
67 | /// Handles symbols that are overridden by the JIT engine (needed to manage |
68 | /// C++ destructors for static objects). |
69 | #if !FACEBOOK_INTERNAL |
70 | #if LLVM_VERSION_MAJOR == 7 || FACEBOOK_INTERNAL |
71 | LocalCXXRuntimeOverrides cxxSymbolOverride_; |
72 | #else |
73 | LegacyLocalCXXRuntimeOverrides cxxSymbolOverride_; |
74 | #endif |
75 | #endif |
76 | |
77 | /// Set of VModuleKeys for all modules in the CompileLayer. Needed in order to |
78 | /// iterate over available modules in some versions of resolveSymbol. |
79 | llvm::DenseSet<llvm::orc::VModuleKey> vModKeys_; |
80 | |
81 | std::shared_ptr<SymbolResolver> resolver_; |
82 | #endif |
83 | #if LLVM_VERSION_MAJOR == 7 || (LLVM_VERSION_MAJOR <= 8 && FACEBOOK_INTERNAL) |
84 | RTDyldObjectLinkingLayer objectLayer_; |
85 | IRCompileLayer<decltype(objectLayer_), SimpleCompiler> compileLayer_; |
86 | /// Records C++ constructor/destructor names of static objects. |
87 | std::vector<llvm::orc::CtorDtorRunner<decltype(compileLayer_)>> |
88 | irStaticDestructorRunners_; |
89 | #else |
90 | LegacyRTDyldObjectLinkingLayer objectLayer_; |
91 | LegacyIRCompileLayer<decltype(objectLayer_), SimpleCompiler> compileLayer_; |
92 | /// Object that records static C++ constructor/destructor names. |
93 | std::vector<LegacyCtorDtorRunner<decltype(compileLayer_)>> |
94 | irStaticDestructorRunners_; |
95 | #endif |
96 | |
97 | /// \returns the JITSymbol for the symbol named \p name. Differs from |
98 | /// findSymbol in that it handles resolving symbols outside of the |
99 | /// CompileLayer (e.g. in process symbols, overridden symbols). |
100 | /// Called indirectly by the ObjectLinkingLayer. |
101 | JITSymbol resolveSymbol(const std::string &name); |
102 | |
103 | /// \returns the mangled name for the C++ global symbol \p name. |
104 | std::string mangle(const std::string &name); |
105 | |
106 | public: |
107 | GlowJIT(std::unique_ptr<llvm::TargetMachine> TM); |
108 | ~GlowJIT(); |
109 | |
110 | TargetMachine &getTargetMachine() { return *TM_; } |
111 | |
112 | JITSymbol findSymbol(const std::string &name); |
113 | |
114 | using ModuleHandle = orc::VModuleKey; |
115 | |
116 | ModuleHandle addModule(std::unique_ptr<Module> M); |
117 | |
118 | void removeModule(ModuleHandle H); |
119 | |
120 | void setContext(std::unique_ptr<llvm::LLVMContext> ctx); |
121 | }; |
122 | |
123 | } // end namespace orc |
124 | } // end namespace llvm |
125 | |
126 | namespace glow { |
127 | using GlowJIT = llvm::orc::GlowJIT; |
128 | } |
129 | |
130 | //############################################################################## |
131 | #elif GLOW_JIT_ORC_VERSION == 2 |
132 | //############################################################################## |
133 | |
134 | namespace glow { |
135 | |
136 | class GlowJITOrcV2 { |
137 | friend class GlowJITDefGenerator; |
138 | |
139 | std::unique_ptr<llvm::TargetMachine> tm_; |
140 | const llvm::DataLayout dl_; |
141 | std::shared_ptr<llvm::orc::SymbolStringPool> ssp_; |
142 | llvm::orc::ExecutionSession es_; |
143 | llvm::orc::JITDylib &jd_; |
144 | |
145 | llvm::orc::RTDyldObjectLinkingLayer objectLayer_; |
146 | llvm::orc::IRCompileLayer compileLayer_; |
147 | llvm::orc::ThreadSafeContext ctx_; |
148 | |
149 | llvm::orc::MangleAndInterner mangler_; |
150 | |
151 | /// Handles symbols that are overridden by the JIT engine (needed to manage |
152 | /// C++ destructors for static objects). |
153 | llvm::orc::LocalCXXRuntimeOverrides cxxSymbolOverride_; |
154 | |
155 | /// Object that records static C++ constructor/destructor names. |
156 | std::vector<llvm::orc::CtorDtorRunner> irStaticDestructorRunners_; |
157 | |
158 | /// \returns the JITSymbol for the symbol named \p name. Differs from |
159 | /// findSymbol in that it handles resolving symbols outside of the |
160 | /// CompileLayer (e.g. in process symbols, overridden symbols). |
161 | /// Called indirectly by the ObjectLinkingLayer. |
162 | llvm::Error tryToGenerate(llvm::orc::LookupKind K, llvm::orc::JITDylib &JD, |
163 | llvm::orc::JITDylibLookupFlags JDLookupFlags, |
164 | const llvm::orc::SymbolLookupSet &LookupSet); |
165 | |
166 | public: |
167 | GlowJITOrcV2(std::unique_ptr<llvm::TargetMachine> tm); |
168 | virtual ~GlowJITOrcV2(); |
169 | |
170 | llvm::JITSymbol findSymbol(const std::string &name); |
171 | |
172 | void setContext(std::unique_ptr<llvm::LLVMContext> ctx); |
173 | void addModule(std::unique_ptr<llvm::Module> M); |
174 | }; |
175 | using GlowJIT = GlowJITOrcV2; |
176 | |
177 | } // namespace glow |
178 | #else |
179 | #error Unsupported GLOW_JIT_ORC_VERSION |
180 | #endif |
181 | |
182 | #endif // GLOW_LLVMIRCODEGEN_GLOWJIT_H |
183 | |