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
28namespace glow {
29
30class AllocationsInfo;
31class BundleSaver;
32class PlaceholderBindings;
33class LLVMIRGen;
34
35/// LLVM backend options used to configure e.g. the LLVM TargetMachine, ORC JIT
36/// or BundleSaver.
37class 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
59public:
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
122class LLVMBackend : public BackendUsingGlowIR {
123public:
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
195protected:
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