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_LLVMIRGEN_H |
17 | #define GLOW_LLVMIRCODEGEN_LLVMIRGEN_H |
18 | |
19 | #include "glow/Base/Tensor.h" |
20 | #include "glow/IR/IR.h" |
21 | |
22 | #include "llvm/ADT/ArrayRef.h" |
23 | #include "llvm/ADT/DenseSet.h" |
24 | #include "llvm/IR/DIBuilder.h" |
25 | #include "llvm/IR/DerivedTypes.h" |
26 | #include "llvm/IR/IRBuilder.h" |
27 | #include "llvm/IR/Module.h" |
28 | #include "llvm/Support/MemoryBuffer.h" |
29 | #include "llvm/Target/TargetMachine.h" |
30 | #include "llvm/Transforms/IPO.h" |
31 | #include "llvm/Transforms/IPO/PassManagerBuilder.h" |
32 | |
33 | namespace glow { |
34 | |
35 | class PlaceholderBindings; |
36 | class IRFunction; |
37 | class Value; |
38 | class Tensor; |
39 | class Constant; |
40 | class Instruction; |
41 | class WeightVar; |
42 | class AllocationsInfo; |
43 | class LLVMBackendOptions; |
44 | |
45 | /// Different kinds of memory areas used by the emitted LLVM function. |
46 | /// The order is important. It should match the order of base addresses |
47 | /// arguments passed to "main". |
48 | enum MemoryAreaKind { |
49 | ConstWeightsMemoryArea, |
50 | MutableWeightsMemoryArea, |
51 | ActivationsMemoryArea, |
52 | LastMemoryArea |
53 | }; |
54 | |
55 | /// A POD struct that stores information related to debug info. |
56 | struct DebugInfo { |
57 | /// Source file for the main function. |
58 | llvm::DIFile *mainFile_{nullptr}; |
59 | /// Debug info for the main function. |
60 | llvm::DISubprogram *mainF_{nullptr}; |
61 | /// Line number for the first instruction in the textual representation of |
62 | /// the Glow IR. |
63 | size_t mainFileFirstInstrLineNo_{0}; |
64 | /// Debug info for the current compilation unit. |
65 | llvm::DICompileUnit *compilationUnit_{nullptr}; |
66 | /// Mapping from LLVM types to DebugInfo types. |
67 | llvm::DenseMap<llvm::Type *, llvm::DIType *> DITypes_; |
68 | /// Names of global variables to hold the bases address of different memory |
69 | /// areas, e.g. activations, constant or mutable weights. |
70 | llvm::SmallVector<llvm::StringRef, LastMemoryArea - 1> |
71 | baseAddressesVariablesNames_; |
72 | /// Maps memory area kinds to the global variables holding the base address of |
73 | /// the corresponding memory area, e.g. activations, constant or mutable |
74 | /// weights area. Used only when producing a debug information. These |
75 | /// variables are required to properly show in the debugger weights and |
76 | /// activations variables, which are expressed in DWARF using a relative |
77 | /// addressing mode with the base addresses stored in these base addresses |
78 | /// variables. |
79 | llvm::SmallVector<llvm::GlobalVariable *, LastMemoryArea - 1> |
80 | baseAddressesVariables_; |
81 | }; |
82 | |
83 | /// Different kinds of bundle APIs. |
84 | enum BundleApiType { |
85 | /// Dynamic bundle API with the following features: |
86 | /// - the weights are exported in a binary file which are assumed |
87 | /// to be loaded dynamically at run-time. |
88 | /// - the memory layout information (bundle configuration) is only |
89 | /// available at run-time and therefore allows ONLY dynamic memory |
90 | /// allocaton. |
91 | Dynamic, |
92 | /// Static bundle API (default) with the following features: |
93 | /// - the weights are exported in a binary file but and also in a |
94 | /// text file (C array format) suitable to include at compile-time. |
95 | /// - the memory layout information (bundle configuration) is available |
96 | /// at compile-time through macros printed in the header file and thus |
97 | /// allows also static memory allocation. |
98 | /// - this API is suitable for low end devices with no file system or OS |
99 | /// (bare-metal). |
100 | Static, |
101 | }; |
102 | |
103 | /// This is a class containing a common logic for the generation of the LLVM IR |
104 | /// from an IRFunction. The primary clients of this class are JITs and bundlers. |
105 | class LLVMIRGen { |
106 | protected: |
107 | /// Implementation of emitDataParallelKernel where we bound the number of |
108 | /// inputs to 64. |
109 | /// \param builder IRBuilder to be used for the LLVM IR code emission. |
110 | /// \param bundle set of instructions to be emitted as a data-parallel kernel. |
111 | /// \param argType types of arguments for the data-parallel kernel. |
112 | /// \param bufferToArgNum mapping from a buffer to its argument number in the |
113 | /// data-parallel kernel. |
114 | /// \param buffers buffers used by the data-parallel kernel. |
115 | virtual void |
116 | emitDataParallelKernelImpl(llvm::IRBuilder<> &builder, |
117 | llvm::ArrayRef<const Instruction *> bundle, |
118 | llvm::ArrayRef<llvm::Type *> argTypes, |
119 | llvm::DenseMap<Value *, int> &bufferToArgNum, |
120 | llvm::ArrayRef<llvm::Value *> buffers); |
121 | |
122 | /// The IR to generate code for. |
123 | const IRFunction *F_; |
124 | /// LLVM IR function corresponding to F_. |
125 | llvm::Function *llvmF_; |
126 | /// Set of emitted LLVM functions for IR functions. |
127 | llvm::SmallVector<llvm::Function *, 4> emittedLLVMFunctions_; |
128 | /// The LLVM context. |
129 | std::unique_ptr<llvm::LLVMContext> ctx_; |
130 | /// The LLVM IR module. |
131 | std::unique_ptr<llvm::Module> llmodule_{nullptr}; |
132 | /// The target machine. |
133 | std::unique_ptr<llvm::TargetMachine> TM_; |
134 | /// Information about allocations. |
135 | AllocationsInfo &allocationsInfo_; |
136 | /// Name of the bundle. |
137 | std::string bundleName_; |
138 | /// Name of the main entry. |
139 | std::string mainEntryName_; |
140 | /// Base name of the saved bundle file, without extension. |
141 | std::string savedBundleName_; |
142 | /// Instruction number for the module. |
143 | std::unique_ptr<InstructionNumbering> instrNumbering_; |
144 | /// Value holding the base address of the activations memory area. |
145 | llvm::Value *baseActivationsAddr_{nullptr}; |
146 | /// Value holding the base address of the constant WeightVars memory area. |
147 | llvm::Value *baseConstantWeightVarsAddr_{nullptr}; |
148 | /// Value holding the base address of mutable WeightVars memory area. |
149 | llvm::Value *baseMutableWeightVarsAddr_{nullptr}; |
150 | /// Value holding the address of the offsets array. |
151 | llvm::Value *offsetsArray_{nullptr}; |
152 | /// Maps constant arrays to the constant expressions representing size_t |
153 | /// pointers to these arrays. This is done to ensure the proper uniqueness |
154 | /// semantics of such pointers just like it is done for llvm::Constants. |
155 | llvm::DenseMap<llvm::Constant *, llvm::Value *> constArrayPtrs_; |
156 | /// The IRBuilder used for the code generation. |
157 | std::unique_ptr<llvm::IRBuilder<>> builder_; |
158 | /// Output directory for bundles, debug info files, etc. |
159 | llvm::StringRef outputDir_; |
160 | /// Debug info emission support. |
161 | DebugInfo dbgInfo_; |
162 | /// Debug info builder. |
163 | std::unique_ptr<llvm::DIBuilder> DIBuilder_; |
164 | |
165 | /// A set that contains all of the argument that we request from the |
166 | /// specializer not to specialize. |
167 | llvm::DenseSet<llvm::Value *> dontSpecializeArgsSet_; |
168 | |
169 | /// Bitcode of the libjit. Contains the starting address and the length of |
170 | /// the bitcode. |
171 | llvm::StringRef libjitBC_; |
172 | |
173 | /// Array with raw objects which can be optionally used by the code generator |
174 | /// to archive additional object code into the bundle. |
175 | llvm::ArrayRef<llvm::MemoryBufferRef> objectRegistry_; |
176 | |
177 | /// Array with the names of the additional objects which will be archived |
178 | /// into the bundle. The objects must be registered in \ref objectRegistry_. |
179 | std::vector<std::string> bundleObjects_; |
180 | |
181 | /// Whether to print the IR instrumentation callback API. |
182 | bool printInstrumentIR_{false}; |
183 | |
184 | /// Generates LLVM IR that computes the address of \p val using \p builder. |
185 | /// The address type is specified by \p ptrTy. |
186 | virtual llvm::Value *emitValueAddress(llvm::IRBuilder<> &builder, |
187 | const glow::Value *val); |
188 | /// Emit the address of the buffer \p v inside a data-parallel kernel \p |
189 | /// kernel using the mapping provided by \p bufferToArgNum. |
190 | llvm::Value *emitBufferAddress(llvm::IRBuilder<> &builder, Value *val, |
191 | llvm::Function *kernel, |
192 | llvm::DenseMap<Value *, int> &bufferToArgNum); |
193 | /// Generates LLVM IR that computes the size of the tensor of \p val using |
194 | /// \p builder. The size type is native to the machine (size_t). |
195 | virtual llvm::Value *emitValueSize(llvm::IRBuilder<> &builder, |
196 | const glow::Value *val); |
197 | /// Generates LLVM IR that materializes the constant \p val. |
198 | llvm::Value *emitConstF32(llvm::IRBuilder<> &builder, float val); |
199 | /// Generates LLVM IR that materializes the constant \p val. |
200 | llvm::Value *emitConstI32(llvm::IRBuilder<> &builder, int32_t val); |
201 | /// Generates LLVM IR that materializes the constant \p val. |
202 | llvm::Value *emitConstI16(llvm::IRBuilder<> &builder, int16_t val); |
203 | /// Generates LLVM IR that materializes the constant \p val. |
204 | llvm::Value *emitConstI8(llvm::IRBuilder<> &builder, int8_t val); |
205 | /// Generates LLVM IR that materializes the constant \p val. |
206 | llvm::Value *emitConstI1(llvm::IRBuilder<> &builder, bool val); |
207 | /// Generates LLVM IR that materializes the constant \p val. |
208 | llvm::Value *emitConstSizeT(llvm::IRBuilder<> &builder, size_t val); |
209 | /// Generates LLVM IR that materializes the constant \p val. |
210 | llvm::Value *emitConstDimT(llvm::IRBuilder<> &builder, dim_t val); |
211 | /// Generates LLVM IR that materializes the constant \p val as a constant of |
212 | /// the type specified by \p kind. |
213 | llvm::Value *emitConst(llvm::IRBuilder<> &builder, float val, |
214 | glow::ElemKind kind); |
215 | /// Generates LLVM IR that materializes the constant array \p vals. Note that |
216 | /// it will cast non-size_t types T into size_t. |
217 | template <typename T> |
218 | llvm::Value *emitConstSizeTArray(llvm::IRBuilder<> &builder, |
219 | llvm::ArrayRef<T> vals); |
220 | |
221 | /// Generates LLVM IR that materializes the constant array \p vals. Note that |
222 | /// it will cast non-dim_t types T into dim_t. |
223 | template <typename T> |
224 | llvm::Value *emitConstDimTArray(llvm::IRBuilder<> &builder, |
225 | llvm::ArrayRef<T> vals); |
226 | |
227 | /// Generates LLVM IR that materializes the constant array \p vals. Note that |
228 | /// int32 data type is accepted. |
229 | llvm::Value *emitConstI32Array(llvm::IRBuilder<> &builder, |
230 | llvm::ArrayRef<int32_t> vals); |
231 | |
232 | /// Generates LLVM IR that materializes the constant array \p vals. Note that |
233 | /// float data type is accepted. |
234 | llvm::Value *emitConstFloatArray(llvm::IRBuilder<> &builder, |
235 | llvm::ArrayRef<float> vals); |
236 | |
237 | /// Generates LLVM IR that materializes the constant array \p vals. Elements |
238 | /// of vals have the type \p elemTy. |
239 | llvm::Value *emitConstArray(llvm::IRBuilder<> &builder, |
240 | llvm::ArrayRef<llvm::Constant *> vals, |
241 | llvm::Type *elemTy); |
242 | |
243 | /// Generates LLVM IR to store all the LLVM IR values \p vals consecutively |
244 | /// starting with the base pointer given by \p basePtr and the relative base |
245 | /// index \p baseIdx. The LLVM IR values \p vals must have same type T and the |
246 | /// type of the base pointer must be T*. |
247 | void emitArrayStore(llvm::IRBuilder<> &builder, |
248 | llvm::ArrayRef<llvm::Value *> vals, llvm::Value *basePtr, |
249 | unsigned baseIdx = 0); |
250 | |
251 | /// Generates LLVM IR that computes the dimensions of \p val using \p builder. |
252 | /// The result type is "size_t*". |
253 | virtual llvm::Value *emitValueDims(llvm::IRBuilder<> &builder, |
254 | const glow::Value *val); |
255 | |
256 | /// Generates LLVM IR that materializes the float activation parameters for |
257 | /// the instruction \p I. |
258 | template <class InstructionTy> |
259 | llvm::Value *emitConstFloatActivationArgs(llvm::IRBuilder<> &builder, |
260 | const InstructionTy *I); |
261 | |
262 | /// Generates LLVM IR that materializes the quantized activation parameters |
263 | /// for the instruction \p I. |
264 | template <class InstructionTy> |
265 | llvm::Value *emitConstQuantActivationArgs(llvm::IRBuilder<> &builder, |
266 | const InstructionTy *I); |
267 | |
268 | /// Load base addresses of different memory areas (activations, const |
269 | /// weightvars, mutable weight vars) so that they can be reused inside the |
270 | /// body of the function. |
271 | virtual void loadBaseAddresses(llvm::IRBuilder<> &builder); |
272 | /// Create a function representing a stacked kernel for instructions provided |
273 | /// in \p stackedInstrs. |
274 | virtual void |
275 | emitDataParallelKernel(llvm::IRBuilder<> &builder, |
276 | llvm::ArrayRef<const Instruction *> stackedInstrs); |
277 | /// Emit IR for the data parallel instruction \p I which is invoked inside the |
278 | /// stacked \p kernel. The current loop count is described by \p loopCount. |
279 | /// The \p bufferToArgNum map can be used to find the required buffers, which |
280 | /// are provided as arguments to the stacked \p kernel. |
281 | /// Derived classes may want to override this function to implement a |
282 | /// backend-specific LLVM IR generation logic for some intructions. |
283 | virtual void generateLLVMIRForDataParallelInstr( |
284 | llvm::IRBuilder<> &builder, const glow::Instruction *I, |
285 | llvm::Function *kernel, llvm::DenseMap<Value *, int> &bufferToArgNum, |
286 | llvm::Value *loopCount); |
287 | /// \returns the llvm type of the glow vale \p val. |
288 | llvm::Type *getElementType(llvm::IRBuilder<> &builder, const Value *val); |
289 | /// Create a debug information for a given LLVM type \p ty. |
290 | llvm::DIType *getDebugType(llvm::IRBuilder<> &builder, llvm::Type *ty); |
291 | /// Init the generation of debug information. |
292 | virtual void initDebugInfo(); |
293 | /// Generate debug information for the current function. |
294 | virtual void generateFunctionDebugInfo(); |
295 | /// Generate debug information for the whole module. |
296 | virtual void generateModuleDebugInfo(); |
297 | /// Set the debug location for the \p builder, so that it corresponds to the |
298 | /// instruction \p I in the textual representation of the Glow IR. |
299 | void setCurrentDebugLocation(llvm::IRBuilder<> &builder, |
300 | const glow::Instruction *I); |
301 | /// Get or create a debug information for a given LLVM function. |
302 | llvm::DISubprogram *getOrCreateFunctionDebugInfo(llvm::Function *F, |
303 | llvm::DIScope *scope, |
304 | llvm::DIFile *file, |
305 | unsigned lineNo); |
306 | /// Emit a debug info for the logical global variable representing a weight or |
307 | /// an activation described by \p val. This allows for inspecting the values |
308 | /// of weights and activations when using a debugger. Logical global variables |
309 | /// are not materialized and do not require any additional memory to be |
310 | /// reserved or allocated. Instead, they reside at offsets described by |
311 | /// AllocationsInfo inside the memory blocks dynamically allocated by clients |
312 | /// for weights and activations, but behave like regular global variables from |
313 | /// the debugger's perspective. |
314 | void emitDebugGlobalVariableForValue(const Value *val); |
315 | |
316 | /// Create LLVM IR for the for loop with a loop count specified by the only |
317 | /// parameter of the enclosing function. |
318 | /// \returns a pair of basic blocks. The first BB is the BB of the loop body, |
319 | /// the second BB is the loop exit BB. |
320 | std::pair<llvm::BasicBlock *, llvm::BasicBlock *> |
321 | createLoop(llvm::IRBuilder<> &builder, llvm::LLVMContext &ctx, |
322 | llvm::Value *numElements) const; |
323 | |
324 | /// \returns the backing tensor associated to the IR constant value \p value. |
325 | Tensor getTensorForConstantValue(Value *value); |
326 | |
327 | public: |
328 | /// Destructor |
329 | virtual ~LLVMIRGen() {} |
330 | /// Ctor. |
331 | /// \param M IRFunction to be converted into LLVM IR. |
332 | /// \param allocationsInfo information about allocation of weights and |
333 | /// activations. |
334 | /// \param mainEntryName Name of the main entry. |
335 | /// \param libjitBC bitcode of the backend's libjit library. |
336 | explicit LLVMIRGen(const IRFunction *M, AllocationsInfo &allocationsInfo, |
337 | std::string mainEntryName, llvm::StringRef libjitBC); |
338 | |
339 | /// Ctor. |
340 | /// \param M IRFunction to be converted into LLVM IR. |
341 | /// \param allocationsInfo information about allocation of weights and |
342 | /// activations. |
343 | /// \param mainEntryName Name of the main entry. |
344 | /// \param libjitBC bitcode of the backend's libjit library. |
345 | /// \param objectRegistry array with additional objects for code generation. |
346 | explicit LLVMIRGen(const IRFunction *M, AllocationsInfo &allocationsInfo, |
347 | std::string mainEntryName, llvm::StringRef libjitBC, |
348 | llvm::ArrayRef<llvm::MemoryBufferRef> objectRegistry); |
349 | |
350 | /// Init the TargetMachine using settings provided by \p llvmBackend. |
351 | virtual void initTargetMachine(const LLVMBackendOptions &opts); |
352 | |
353 | /// Init the TargetOptions \p targetOpts in a backend-specific way. Use \p |
354 | /// backendOpts as input if necessary. |
355 | virtual void initTargetOptions(llvm::TargetOptions &targetOpts, |
356 | const LLVMBackendOptions &backendOpts); |
357 | |
358 | /// Emit LLVM-IR for the instruction \p I, using the builder \p builder. |
359 | /// Derived classes may want to override this function to implement a |
360 | /// backend-specific LLVM IR generation logic for some intructions. |
361 | /// \param builder IRBuilder to be used to emit LLVM IR code. |
362 | /// \param I IR instruction which should be compiled into LLVM IR. |
363 | virtual void generateLLVMIRForInstr(llvm::IRBuilder<> &builder, |
364 | const glow::Instruction *I); |
365 | /// Emit LLVM-IR for the whole IRFunction. |
366 | virtual void generateLLVMIRForModule(llvm::IRBuilder<> &builder); |
367 | /// Helper function to create a new CallInst, with the specified \p builder, |
368 | /// \p callee, and \p args. Verifies that the function signature is correct, |
369 | /// and then creates and \returns the CallInst. |
370 | /// \param builder the IR builder to be used for creating the Call |
371 | /// instruction. \param callee the function to be called. \param args |
372 | /// arguments to be passed in this call. If \p checked is set, this helper |
373 | /// emits checks for the int result of the call and returns from the caller if |
374 | /// it is non-zero. If callee does not return an int result, \p checked has no |
375 | /// effect. \returns generated Call instruction |
376 | virtual llvm::CallInst *createCall(llvm::IRBuilder<> &builder, |
377 | llvm::Function *callee, |
378 | llvm::ArrayRef<llvm::Value *> args, |
379 | bool checked = false); |
380 | /// The checked version of createCall. |
381 | virtual llvm::CallInst *createCheckedCall(llvm::IRBuilder<> &builder, |
382 | llvm::Function *callee, |
383 | llvm::ArrayRef<llvm::Value *> args); |
384 | /// The unchecked version of createCall. |
385 | virtual llvm::CallInst * |
386 | createUncheckedCall(llvm::IRBuilder<> &builder, llvm::Function *callee, |
387 | llvm::ArrayRef<llvm::Value *> args); |
388 | /// \returns a libjit API function by name. |
389 | virtual llvm::Function *getFunction(const std::string &name); |
390 | /// \returns a libjit API function by name and tensor element type. |
391 | virtual llvm::Function *getFunction(const std::string &name, |
392 | glow::ElemKind elemTy); |
393 | /// \returns a libjit API function by name and tensor element type. |
394 | virtual llvm::Function * |
395 | getFunction(const std::string &name, |
396 | llvm::ArrayRef<glow::ElemKind> elemTyArray); |
397 | /// \returns current LLVM function. |
398 | virtual llvm::Function *getLLVMFunction(); |
399 | /// Optimize the function \p F and the module that owns it. Use the target |
400 | /// information from the \p TM target machine. |
401 | virtual void optimizeLLVMModule(llvm::Module *M, llvm::TargetMachine &TM); |
402 | /// Performs specialization of operations based on constant parameters. |
403 | virtual void performSpecialization(); |
404 | /// Insert debug traces in appropriate places. |
405 | virtual void performDebugInstrumentation(); |
406 | /// \returns allocations info. |
407 | virtual AllocationsInfo &getAllocationsInfo() { return allocationsInfo_; } |
408 | /// \returns the name of the bundle, to be used for filename when saving. |
409 | llvm::StringRef getBundleName() const; |
410 | /// Set the name of the bundle (name is automatically legalized). |
411 | void setBundleName(const std::string &name); |
412 | /// \returns the base name of the saved bundle file to be used by a |
413 | /// BundleSaver. |
414 | llvm::StringRef getSavedBundleName() const; |
415 | /// Set the base name of the saved bundle file. |
416 | void setSavedBundleName(const std::string &name); |
417 | /// \returns the name of the main entry point. |
418 | /// When JITting, it will be "main". In case of bundling it will be the name |
419 | /// of the bundle. |
420 | std::string getMainEntryName() const; |
421 | /// Set the name of the main entry point (name is automatically legalized). |
422 | void setMainEntryName(std::string name); |
423 | /// Creates an LLVM module, the entry function, etc. |
424 | virtual void initCodeGen(); |
425 | /// Emits the code of the entry function, performs optimizations, etc. |
426 | virtual void performCodeGen(); |
427 | /// Finish the LLVM IR code generation. |
428 | virtual void finishCodeGen(); |
429 | /// \returns the current builder. |
430 | llvm::IRBuilder<> &getBuilder() { return *builder_; } |
431 | /// \returns the target machine description. |
432 | llvm::TargetMachine &getTargetMachine() { return *TM_; } |
433 | /// Takes the target machine for further processing, e.g. by a JIT. |
434 | /// The target machine cannot be used by the LLVMIRGen afterwards. |
435 | std::unique_ptr<llvm::TargetMachine> takeTargetMachine() { |
436 | return std::move(TM_); |
437 | } |
438 | /// \returns the LLVMContext being used. |
439 | llvm::LLVMContext &getLLVMContext() { return *ctx_; } |
440 | /// Takes the LLVM Context for further processing, e.g. by a JIT. |
441 | /// The context cannot be used by the LLVMIRGen afterwards. |
442 | std::unique_ptr<llvm::LLVMContext> takeLLVMContext() { |
443 | return std::move(ctx_); |
444 | } |
445 | /// Borrows the LLVM module for further processing, e.g. by a JIT. |
446 | /// The module cannot be used by the LLVMIRGen afterwards. |
447 | std::unique_ptr<llvm::Module> borrowModule() { return std::move(llmodule_); } |
448 | /// \returns current LLVM module. |
449 | llvm::Module &getModule() const { return *llmodule_; } |
450 | /// \returns the IR function. |
451 | const IRFunction *getIRFunction() { return F_; } |
452 | /// Set IRFunction to be processed next. |
453 | void setIRFunction(const IRFunction *F) { F_ = F; } |
454 | /// Set output directory for bundles, debug info files, etc. |
455 | void setOutputDir(llvm::StringRef outputDir) { outputDir_ = outputDir; } |
456 | /// Get output directory for bundles, debug info files, etc. |
457 | llvm::StringRef getOutputDir() const { return outputDir_; } |
458 | /// Emit the array of constant offsets as provided by the \p allocationsInfo. |
459 | virtual llvm::Value * |
460 | emitConstOffsetsArray(llvm::IRBuilder<> &builder, |
461 | const AllocationsInfo &allocationsInfo); |
462 | /// Generate debug info for a LLVM function \p F. |
463 | virtual void generateFunctionDebugInfo(llvm::Function *F); |
464 | /// Generates LLVM IR that materializes the string literal \p str. |
465 | virtual llvm::Value *emitStringConst(llvm::IRBuilder<> &builder, |
466 | llvm::StringRef str); |
467 | /// Emit symbols to JIT to allow it to use host side file printing. |
468 | void generateJITFileWriter(); |
469 | /// Register \p val as an argument that should not be specialized. |
470 | virtual void markArgAsUnspecialized(llvm::Value *val); |
471 | /// \returns bit-width of the target size_t. |
472 | virtual unsigned getTargetSizeTWidth() const; |
473 | /// \returns the sizeof(size_t) of the actual target-specific size_t type that |
474 | /// was used to compile libjit into LLVM bitcode. |
475 | unsigned getLibjitSizeTWidth() const; |
476 | /// \returns the sizeof(int) of the actual target-specific int type that |
477 | /// was used to compile libjit into LLVM bitcode. |
478 | unsigned getLibjitIntWidth() const; |
479 | /// \returns true if a call is eligible for specialization. |
480 | virtual bool isEligibleForSpecialization(const llvm::CallInst *call); |
481 | /// \returns true if a global symbol \p GV needs to be preserved in the module |
482 | /// and not interalized during optimizations. |
483 | virtual bool preserveSymbol(const llvm::GlobalValue &GV); |
484 | /// \returns inlining mode to be used for a function \p F. |
485 | virtual llvm::Attribute::AttrKind |
486 | getInlinineAttr(const llvm::Function *F) const; |
487 | /// Configures a provided PassManagerBuilder \p PMB in a backend-specific way |
488 | virtual void populatePassManagerBuilderOptions(llvm::PassManagerBuilder &PMB); |
489 | /// Update inline attributes of functions in the module \p M using a |
490 | /// backend-specific logic. |
491 | virtual void updateInlineAttributes(llvm::Module *M); |
492 | /// \returns true if an instruction \p I can be part of a data parallel |
493 | /// kernel. This gives backends a possibility to provide a custom logic to |
494 | /// decide on a per-instruction basis what can be part of data parallel |
495 | /// kernels. Typically an instruction which is isDataParallel() can be part of |
496 | /// a data parallel kernel. But a backend may decide that a specific |
497 | /// instruction \p I cannot be part of data-parallel kernels, because there is |
498 | /// no support for this functionality in this backend yet. |
499 | virtual bool canBePartOfDataParallelKernel(const glow::Instruction *I) const; |
500 | /// \returns a string which is printed at the end of the bundle header file |
501 | /// following the standard content produced by the bundle saver. |
502 | virtual std::string () const; |
503 | /// \returns the object registry for this code generator instance. |
504 | virtual llvm::ArrayRef<llvm::MemoryBufferRef> getObjectRegistry() const; |
505 | /// Set the object registry for this code generator instance. |
506 | virtual void |
507 | setObjectRegistry(llvm::ArrayRef<llvm::MemoryBufferRef> objectRegistry); |
508 | /// \returns the names of the objects which are archived into the bundle. |
509 | virtual std::vector<std::string> getBundleObjects() const; |
510 | /// Add a bundle object \p objectName to be archived to the bundle. The object |
511 | /// must be registered in the \ref objectRegistry_ otherwise error is thrown. |
512 | virtual void addBundleObject(llvm::StringRef objectName); |
513 | }; |
514 | |
515 | template <typename T> |
516 | llvm::Value *LLVMIRGen::emitConstSizeTArray(llvm::IRBuilder<> &builder, |
517 | llvm::ArrayRef<T> vals) { |
518 | assert(std::is_integral<T>() && "Can only convert integral type to size_t." ); |
519 | auto SizeTType = builder.getIntNTy(getLibjitSizeTWidth()); |
520 | std::vector<llvm::Constant *> elems; |
521 | for (auto I : vals) { |
522 | assert(I >= 0 && "Only allow casting positive values into size_t." ); |
523 | assert(I <= std::numeric_limits<size_t>::max() && |
524 | "Do not allow overflow of size_t." ); |
525 | elems.push_back(llvm::ConstantInt::get(SizeTType, (size_t)I)); |
526 | } |
527 | return emitConstArray(builder, elems, SizeTType); |
528 | } |
529 | |
530 | template <typename T> |
531 | llvm::Value *LLVMIRGen::emitConstDimTArray(llvm::IRBuilder<> &builder, |
532 | llvm::ArrayRef<T> vals) { |
533 | assert(std::is_integral<T>() && "Can only convert integral type to dim_t." ); |
534 | auto DimTType = builder.getIntNTy(sizeof(dim_t) * 8); |
535 | std::vector<llvm::Constant *> elems; |
536 | for (auto I : vals) { |
537 | assert(I >= 0 && "Only allow casting positive values into size_t." ); |
538 | assert(I <= std::numeric_limits<dim_t>::max() && |
539 | "Do not allow overflow of size_t." ); |
540 | elems.push_back(llvm::ConstantInt::get(DimTType, (dim_t)I)); |
541 | } |
542 | return emitConstArray(builder, elems, DimTType); |
543 | } |
544 | |
545 | } // namespace glow |
546 | |
547 | #endif // GLOW_LLVMIRCODEGEN_LLVMIRGEN_H |
548 | |