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_LLVMBACKEND_H |
17 | #define GLOW_LLVMIRCODEGEN_LLVMBACKEND_H |
18 | |
19 | #include "glow/Backend/Backend.h" |
20 | #include "glow/Backend/CompiledFunction.h" |
21 | #include "glow/Base/Tensor.h" |
22 | #include "glow/LLVMIRCodeGen/GlowJIT.h" |
23 | #include "glow/LLVMIRCodeGen/LLVMIRGen.h" |
24 | |
25 | #include "llvm/ADT/ArrayRef.h" |
26 | #include "llvm/IR/IRBuilder.h" |
27 | |
28 | namespace glow { |
29 | |
30 | class AllocationsInfo; |
31 | class BundleSaver; |
32 | class PlaceholderBindings; |
33 | class LLVMIRGen; |
34 | |
35 | /// LLVM backend options used to configure e.g. the LLVM TargetMachine, ORC JIT |
36 | /// or BundleSaver. |
37 | class LLVMBackendOptions { |
38 | /// Target triple used by this backend. |
39 | std::string target_; |
40 | /// Arch used by this backend. |
41 | std::string arch_; |
42 | /// Cpu used by this backend. |
43 | std::string cpu_; |
44 | /// ABI to be used by this backend. |
45 | std::string abi_; |
46 | /// Float ABI to be used by this backend. |
47 | llvm::Optional<llvm::FloatABI::ABIType> floatABI_; |
48 | /// Code model used by this backend. |
49 | llvm::CodeModel::Model codeModel_; |
50 | /// Code model used by this backend for bundles. |
51 | llvm::CodeModel::Model bundleCodeModel_; |
52 | /// Relocation model used by this backend. |
53 | llvm::Reloc::Model relocModel_; |
54 | /// LLVM target features used by this backend. |
55 | llvm::SmallVector<std::string, 0> targetFeatures_; |
56 | /// Bundle API to use. |
57 | BundleApiType bundleAPI_; |
58 | |
59 | public: |
60 | LLVMBackendOptions(); |
61 | /// \returns target triple used by this backend. |
62 | const std::string &getTarget() const { return target_; } |
63 | /// Sets target triple used by this backend. |
64 | void setTarget(llvm::StringRef target) { target_ = target.str(); } |
65 | /// \returns arch used by this backend. |
66 | const std::string &getArch() const { return arch_; } |
67 | /// Sets arch used by this backend. |
68 | void setArch(llvm::StringRef arch) { arch_ = arch.str(); } |
69 | /// \returns cpu used by this backend. |
70 | const std::string &getCPU() const { return cpu_; } |
71 | /// Sets cpu used by this backend. |
72 | void setCPU(llvm::StringRef cpu) { cpu_ = cpu.str(); } |
73 | /// \returns ABI used by this backend. |
74 | const std::string &getABIName() const { return abi_; } |
75 | /// Sets ABI used by this backend. |
76 | void setABIName(llvm::StringRef abi) { abi_ = abi.str(); } |
77 | /// \returns Float ABI used by this backend. |
78 | llvm::Optional<llvm::FloatABI::ABIType> getFloatABI() const { |
79 | return floatABI_; |
80 | } |
81 | /// Sets Float ABI used by this backend. |
82 | void setFloatABI(llvm::Optional<llvm::FloatABI::ABIType> floatABI) { |
83 | floatABI_ = floatABI; |
84 | } |
85 | /// \returns code model used by this backend. |
86 | llvm::CodeModel::Model getCodeModel() const { return codeModel_; } |
87 | /// Sets code model used by this backend. |
88 | void setCodeModel(llvm::CodeModel::Model codeModel) { |
89 | codeModel_ = codeModel; |
90 | } |
91 | /// \returns code model used by this backend for bundles. |
92 | llvm::CodeModel::Model getBundleCodeModel() const { return bundleCodeModel_; } |
93 | /// Sets code model used by this backend for bundles. |
94 | void setBundleCodeModel(llvm::CodeModel::Model codeModel) { |
95 | bundleCodeModel_ = codeModel; |
96 | } |
97 | /// \returns bundle API used by this backend for bundles. |
98 | BundleApiType getBundleAPI() const { return bundleAPI_; } |
99 | /// Sets bundle API used by this backend for bundles. |
100 | void setBundleAPI(BundleApiType api) { bundleAPI_ = api; } |
101 | /// \returns relocation model used by this backend. |
102 | llvm::Reloc::Model getRelocModel() const { return relocModel_; } |
103 | /// Sets relocation model used by this backend. |
104 | void setRelocModel(llvm::Reloc::Model relocModel) { |
105 | relocModel_ = relocModel; |
106 | } |
107 | /// \returns target features used by this backend. |
108 | const llvm::SmallVectorImpl<std::string> &getTargetFeatures() const { |
109 | return targetFeatures_; |
110 | } |
111 | /// Adds target features used by this backend. |
112 | void addTargetFeatures(llvm::ArrayRef<std::string> targetFeatures) { |
113 | targetFeatures_.append(targetFeatures.begin(), targetFeatures.end()); |
114 | } |
115 | /// Sets target features used by this backend. |
116 | void setTargetFeatures(llvm::ArrayRef<std::string> targetFeatures) { |
117 | targetFeatures_.clear(); |
118 | addTargetFeatures(targetFeatures); |
119 | } |
120 | }; |
121 | |
122 | class LLVMBackend : public BackendUsingGlowIR { |
123 | public: |
124 | LLVMBackend(); |
125 | /// @name Backend methods. |
126 | /// This is the implementation of the Backend interface. |
127 | ///@{ |
128 | virtual ~LLVMBackend() override = default; |
129 | |
130 | /// \returns the LLVM target triple for the host. |
131 | static std::string getHostTarget(); |
132 | |
133 | /// \returns the LLVM CPU name for the host. |
134 | static std::string getHostCPU(); |
135 | |
136 | /// \returns the LLVM CPU feature list for the host. |
137 | static llvm::SmallVector<std::string, 0> getHostFeatures(); |
138 | |
139 | /// \returns LLVM backend options. |
140 | const LLVMBackendOptions &getOptions() const { return options_; } |
141 | |
142 | /// \returns LLVM backend options. |
143 | LLVMBackendOptions &getOptions() { return options_; } |
144 | |
145 | /// Sets LLVM backend options. |
146 | void setOptions(const LLVMBackendOptions &options) { options_ = options; } |
147 | |
148 | /// \returns whether the provided \p NI is supported by the backend. |
149 | bool isOpSupported(const NodeInfo &NI) const override; |
150 | |
151 | virtual std::unique_ptr<CompiledFunction> |
152 | compileIR(std::unique_ptr<IRFunction> IR) const override; |
153 | |
154 | virtual std::unique_ptr<CompiledFunction> |
155 | compileIRWithoutConstants(IRFunction *IR) const; |
156 | |
157 | virtual Expected<std::unique_ptr<CompiledFunction>> |
158 | compile(Function *F, const BackendOptions &opts) const override; |
159 | |
160 | virtual void save(Function *F, llvm::StringRef outputDir, |
161 | llvm::StringRef bundleName, |
162 | llvm::StringRef mainEntryName) const override; |
163 | |
164 | virtual void saveFunctions(llvm::ArrayRef<BundleEntry> entries, |
165 | llvm::StringRef outputDir, |
166 | llvm::StringRef bundleName) const override; |
167 | /// @} |
168 | |
169 | /// \returns the size of metrics collected for a single TraceEvent. |
170 | virtual size_t getTraceEventDataSize() const override { |
171 | return sizeof(uint64_t); |
172 | } |
173 | |
174 | /// Method that creates the LLVM IR generator. This gives the possibility to |
175 | /// create a backend that inherits from the CPU backend, while providing |
176 | /// a specific version of the LLVM IR generator derived from LLVMIRGen. |
177 | /// \param IR the IRFunction function to be converted into the LLVM IR. |
178 | /// \param allocationsInfo information about allocation of weights and |
179 | /// activations. |
180 | /// \returns backend-specific LLVMIRGen instance. |
181 | virtual std::unique_ptr<LLVMIRGen> |
182 | createIRGen(const IRFunction *IR, AllocationsInfo &allocationsInfo) const = 0; |
183 | |
184 | /// Method that creates a BundleSaver. This gives the possibility to |
185 | /// create a backend that inherits from the LLVMBackend backend, while |
186 | /// providing a specific version of the BundleSaver derived from BundleSaver. |
187 | /// \param llvmBackend backend to be used to produce in a bundle. |
188 | /// \param outputDir output directory for the bundle. |
189 | /// \param bundleName the name of the bundle. |
190 | /// \returns backend-specific BundleSaver instance. |
191 | virtual std::unique_ptr<BundleSaver> |
192 | createBundleSaver(const LLVMBackend &llvmBackend, llvm::StringRef outputDir, |
193 | llvm::StringRef bundleName) const; |
194 | |
195 | protected: |
196 | /// Method that creates a CompiledFunction. |
197 | /// \param JIT GlowJIT to be used. |
198 | /// \param runtimeBundle bundle to be used for compiling the function. |
199 | /// \returns created CompiledFunction. |
200 | virtual std::unique_ptr<CompiledFunction> |
201 | createCompiledFunction(std::unique_ptr<GlowJIT> JIT, |
202 | runtime::RuntimeBundle &&runtimeBundle) const = 0; |
203 | |
204 | /// \returns libjit bitcode for the current backend. |
205 | virtual llvm::StringRef getLibjitBitcode() const = 0; |
206 | |
207 | /// Emit the jitmain function. |
208 | virtual void emitJitMain(LLVMIRGen &irgen) const; |
209 | |
210 | /// LLVM backend options. |
211 | LLVMBackendOptions options_; |
212 | }; |
213 | |
214 | } // namespace glow |
215 | |
216 | #endif // GLOW_LLVMIRCODEGEN_LLVMBACKEND_H |
217 | |