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//##############################################################################
50namespace llvm {
51namespace orc {
52
53// A class that represents a simple LLVM-based Orc JIT. Based on the
54// KaleidoscopeJIT example in the LLVM tree.
55class GlowJIT {
56private:
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
106public:
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
126namespace glow {
127using GlowJIT = llvm::orc::GlowJIT;
128}
129
130//##############################################################################
131#elif GLOW_JIT_ORC_VERSION == 2
132//##############################################################################
133
134namespace glow {
135
136class 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
166public:
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};
175using 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