Halide  12.0.1
Halide compiler and libraries
CodeGen_Internal.h
Go to the documentation of this file.
1 #ifndef HALIDE_CODEGEN_INTERNAL_H
2 #define HALIDE_CODEGEN_INTERNAL_H
3 
4 /** \file
5  *
6  * Defines functionality that's useful to multiple target-specific
7  * CodeGen paths, but shouldn't live in CodeGen_LLVM.h (because that's the
8  * front-end-facing interface to CodeGen).
9  */
10 
11 #include <memory>
12 #include <string>
13 
14 #include "Closure.h"
15 #include "Expr.h"
16 #include "Scope.h"
17 
18 namespace llvm {
19 class ConstantFolder;
20 class ElementCount;
21 class Function;
22 class IRBuilderDefaultInserter;
23 class LLVMContext;
24 class Module;
25 class StructType;
26 class TargetMachine;
27 class TargetOptions;
28 class Type;
29 class Value;
30 template<typename, typename>
31 class IRBuilder;
32 } // namespace llvm
33 
34 namespace Halide {
35 
36 struct Target;
37 
38 namespace Internal {
39 
40 /** The llvm type of a struct containing all of the externally referenced state of a Closure. */
41 llvm::StructType *build_closure_type(const Closure &closure, llvm::StructType *halide_buffer_t_type, llvm::LLVMContext *context);
42 
43 /** Emit code that builds a struct containing all the externally
44  * referenced state. Requires you to pass it a type and struct to fill in,
45  * a scope to retrieve the llvm values from and a builder to place
46  * the packing code. */
47 void pack_closure(llvm::StructType *type,
48  llvm::Value *dst,
49  const Closure &closure,
50  const Scope<llvm::Value *> &src,
51  llvm::StructType *halide_buffer_t_type,
53 
54 /** Emit code that unpacks a struct containing all the externally
55  * referenced state into a symbol table. Requires you to pass it a
56  * state struct type and value, a scope to fill, and a builder to place the
57  * unpacking code. */
58 void unpack_closure(const Closure &closure,
60  llvm::StructType *type,
61  llvm::Value *src,
63 
64 /** Get the llvm type equivalent to a given halide type */
65 llvm::Type *llvm_type_of(llvm::LLVMContext *context, Halide::Type t);
66 
67 /** Get the number of elements in an llvm vector type, or return 1 if
68  * it's not a vector type. */
69 int get_vector_num_elements(llvm::Type *);
70 
71 /** Get the scalar type of an llvm vector type. Returns the argument
72  * if it's not a vector type. */
73 llvm::Type *get_vector_element_type(llvm::Type *);
74 
75 llvm::ElementCount element_count(int e);
76 
77 llvm::Type *get_vector_type(llvm::Type *, int);
78 
79 /** Which built-in functions require a user-context first argument? */
80 bool function_takes_user_context(const std::string &name);
81 
82 /** Given a size (in bytes), return True if the allocation size can fit
83  * on the stack; otherwise, return False. This routine asserts if size is
84  * non-positive. */
86 
87 /** Does a {div/mod}_round_to_zero using binary long division for int/uint.
88  * max_abs is the maximum absolute value of (a/b).
89  * Returns the pair {div_round_to_zero, mod_round_to_zero}. */
90 std::pair<Expr, Expr> long_div_mod_round_to_zero(const Expr &a, const Expr &b,
91  const uint64_t *max_abs = nullptr);
92 
93 /** Given a Halide Euclidean division/mod operation, do constant optimizations
94  * and possibly call lower_euclidean_div/lower_euclidean_mod if necessary.
95  * Can introduce mulhi_shr and sorted_avg intrinsics as well as those from the
96  * lower_euclidean_ operation -- div_round_to_zero or mod_round_to_zero. */
97 ///@{
98 Expr lower_int_uint_div(const Expr &a, const Expr &b);
99 Expr lower_int_uint_mod(const Expr &a, const Expr &b);
100 ///@}
101 
102 /** Given a Halide Euclidean division/mod operation, define it in terms of
103  * div_round_to_zero or mod_round_to_zero. */
104 ///@{
107 ///@}
108 
109 /** Given a Halide shift operation with a signed shift amount (may be negative), define
110  * an equivalent expression using only shifts by unsigned amounts. */
111 ///@{
112 Expr lower_signed_shift_left(const Expr &a, const Expr &b);
114 ///@}
115 
116 /** Reduce a mux intrinsic to a select tree */
118 
119 /** Given an llvm::Module, set llvm:TargetOptions, cpu and attr information */
120 void get_target_options(const llvm::Module &module, llvm::TargetOptions &options, std::string &mcpu, std::string &mattrs);
121 
122 /** Given two llvm::Modules, clone target options from one to the other */
123 void clone_target_options(const llvm::Module &from, llvm::Module &to);
124 
125 /** Given an llvm::Module, get or create an llvm:TargetMachine */
126 std::unique_ptr<llvm::TargetMachine> make_target_machine(const llvm::Module &module);
127 
128 /** Set the appropriate llvm Function attributes given a Target. */
129 void set_function_attributes_for_target(llvm::Function *, const Target &);
130 
131 /** Save a copy of the llvm IR currently represented by the module as
132  * data in the __LLVM,__bitcode section. Emulates clang's
133  * -fembed-bitcode flag and is useful to satisfy Apple's bitcode
134  * inclusion requirements. */
135 void embed_bitcode(llvm::Module *M, const std::string &halide_command);
136 
137 } // namespace Internal
138 } // namespace Halide
139 
140 #endif
Provides Closure class.
Base classes for Halide expressions (Halide::Expr) and statements (Halide::Internal::Stmt)
Defines the Scope class, which is used for keeping track of names in a scope while traversing IR.
A helper class to manage closures.
Definition: Closure.h:28
void set_function_attributes_for_target(llvm::Function *, const Target &)
Set the appropriate llvm Function attributes given a Target.
void unpack_closure(const Closure &closure, Scope< llvm::Value * > &dst, llvm::StructType *type, llvm::Value *src, llvm::IRBuilder< llvm::ConstantFolder, llvm::IRBuilderDefaultInserter > *builder)
Emit code that unpacks a struct containing all the externally referenced state into a symbol table.
std::pair< Expr, Expr > long_div_mod_round_to_zero(const Expr &a, const Expr &b, const uint64_t *max_abs=nullptr)
Does a {div/mod}_round_to_zero using binary long division for int/uint.
void clone_target_options(const llvm::Module &from, llvm::Module &to)
Given two llvm::Modules, clone target options from one to the other.
llvm::Type * get_vector_element_type(llvm::Type *)
Get the scalar type of an llvm vector type.
llvm::StructType * build_closure_type(const Closure &closure, llvm::StructType *halide_buffer_t_type, llvm::LLVMContext *context)
The llvm type of a struct containing all of the externally referenced state of a Closure.
Expr lower_signed_shift_right(const Expr &a, const Expr &b)
Given a Halide shift operation with a signed shift amount (may be negative), define an equivalent exp...
llvm::Type * get_vector_type(llvm::Type *, int)
void embed_bitcode(llvm::Module *M, const std::string &halide_command)
Save a copy of the llvm IR currently represented by the module as data in the __LLVM,...
Expr lower_int_uint_div(const Expr &a, const Expr &b)
Given a Halide Euclidean division/mod operation, do constant optimizations and possibly call lower_eu...
Expr lower_int_uint_mod(const Expr &a, const Expr &b)
Given a Halide Euclidean division/mod operation, do constant optimizations and possibly call lower_eu...
bool can_allocation_fit_on_stack(int64_t size)
Given a size (in bytes), return True if the allocation size can fit on the stack; otherwise,...
llvm::Type * llvm_type_of(llvm::LLVMContext *context, Halide::Type t)
Get the llvm type equivalent to a given halide type.
llvm::ElementCount element_count(int e)
Expr lower_mux(const Call *mux)
Reduce a mux intrinsic to a select tree.
void get_target_options(const llvm::Module &module, llvm::TargetOptions &options, std::string &mcpu, std::string &mattrs)
Given an llvm::Module, set llvm:TargetOptions, cpu and attr information.
void pack_closure(llvm::StructType *type, llvm::Value *dst, const Closure &closure, const Scope< llvm::Value * > &src, llvm::StructType *halide_buffer_t_type, llvm::IRBuilder< llvm::ConstantFolder, llvm::IRBuilderDefaultInserter > *builder)
Emit code that builds a struct containing all the externally referenced state.
Expr lower_signed_shift_left(const Expr &a, const Expr &b)
Given a Halide shift operation with a signed shift amount (may be negative), define an equivalent exp...
Expr lower_euclidean_div(Expr a, Expr b)
Given a Halide Euclidean division/mod operation, define it in terms of div_round_to_zero or mod_round...
int get_vector_num_elements(llvm::Type *)
Get the number of elements in an llvm vector type, or return 1 if it's not a vector type.
bool function_takes_user_context(const std::string &name)
Which built-in functions require a user-context first argument?
Expr lower_euclidean_mod(Expr a, Expr b)
Given a Halide Euclidean division/mod operation, define it in terms of div_round_to_zero or mod_round...
std::unique_ptr< llvm::TargetMachine > make_target_machine(const llvm::Module &module)
Given an llvm::Module, get or create an llvm:TargetMachine.
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
Expr mux(const Expr &id, const std::initializer_list< Expr > &values)
Oftentimes we want to pack a list of expressions with the same type into a channel dimension,...
char * dst
Definition: printer.h:32
unsigned __INT64_TYPE__ uint64_t
signed __INT64_TYPE__ int64_t
A fragment of Halide syntax.
Definition: Expr.h:256
A function call.
Definition: IR.h:464
A struct representing a target machine and os to generate code for.
Definition: Target.h:19
Types in the halide type system.
Definition: Type.h:269