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
33namespace glow {
34
35class PlaceholderBindings;
36class IRFunction;
37class Value;
38class Tensor;
39class Constant;
40class Instruction;
41class WeightVar;
42class AllocationsInfo;
43class 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".
48enum MemoryAreaKind {
49 ConstWeightsMemoryArea,
50 MutableWeightsMemoryArea,
51 ActivationsMemoryArea,
52 LastMemoryArea
53};
54
55/// A POD struct that stores information related to debug info.
56struct 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.
84enum 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.
105class LLVMIRGen {
106protected:
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
327public:
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 getBundleHeaderExtra() 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
515template <typename T>
516llvm::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
530template <typename T>
531llvm::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