Halide 16.0.0
Halide compiler and libraries
IR.h
Go to the documentation of this file.
1#ifndef HALIDE_IR_H
2#define HALIDE_IR_H
3
4/** \file
5 * Subtypes for Halide expressions (\ref Halide::Expr) and statements (\ref Halide::Internal::Stmt)
6 */
7
8#include <string>
9#include <vector>
10
11#include "Buffer.h"
12#include "Expr.h"
13#include "FunctionPtr.h"
14#include "ModulusRemainder.h"
15#include "Parameter.h"
16#include "PrefetchDirective.h"
17#include "Reduction.h"
18#include "Type.h"
19
20namespace Halide {
21namespace Internal {
22
23class Function;
24
25/** The actual IR nodes begin here. Remember that all the Expr
26 * nodes also have a public "type" property */
27
28/** Cast a node from one type to another. Can't change vector widths. */
29struct Cast : public ExprNode<Cast> {
31
32 static Expr make(Type t, Expr v);
33
35};
36
37/** Reinterpret value as another type, without affecting any of the bits
38 * (on little-endian systems). */
39struct Reinterpret : public ExprNode<Reinterpret> {
41
42 static Expr make(Type t, Expr v);
43
45};
46
47/** The sum of two expressions */
48struct Add : public ExprNode<Add> {
50
51 static Expr make(Expr a, Expr b);
52
54};
55
56/** The difference of two expressions */
57struct Sub : public ExprNode<Sub> {
59
60 static Expr make(Expr a, Expr b);
61
63};
64
65/** The product of two expressions */
66struct Mul : public ExprNode<Mul> {
68
69 static Expr make(Expr a, Expr b);
70
72};
73
74/** The ratio of two expressions */
75struct Div : public ExprNode<Div> {
77
78 static Expr make(Expr a, Expr b);
79
81};
82
83/** The remainder of a / b. Mostly equivalent to '%' in C, except that
84 * the result here is always positive. For floats, this is equivalent
85 * to calling fmod. */
86struct Mod : public ExprNode<Mod> {
88
89 static Expr make(Expr a, Expr b);
90
92};
93
94/** The lesser of two values. */
95struct Min : public ExprNode<Min> {
97
98 static Expr make(Expr a, Expr b);
99
101};
102
103/** The greater of two values */
104struct Max : public ExprNode<Max> {
106
107 static Expr make(Expr a, Expr b);
108
110};
111
112/** Is the first expression equal to the second */
113struct EQ : public ExprNode<EQ> {
115
116 static Expr make(Expr a, Expr b);
117
119};
120
121/** Is the first expression not equal to the second */
122struct NE : public ExprNode<NE> {
124
125 static Expr make(Expr a, Expr b);
126
128};
129
130/** Is the first expression less than the second. */
131struct LT : public ExprNode<LT> {
133
134 static Expr make(Expr a, Expr b);
135
137};
138
139/** Is the first expression less than or equal to the second. */
140struct LE : public ExprNode<LE> {
142
143 static Expr make(Expr a, Expr b);
144
146};
147
148/** Is the first expression greater than the second. */
149struct GT : public ExprNode<GT> {
151
152 static Expr make(Expr a, Expr b);
153
155};
156
157/** Is the first expression greater than or equal to the second. */
158struct GE : public ExprNode<GE> {
160
161 static Expr make(Expr a, Expr b);
162
164};
165
166/** Logical and - are both expressions true */
167struct And : public ExprNode<And> {
169
170 static Expr make(Expr a, Expr b);
171
173};
174
175/** Logical or - is at least one of the expression true */
176struct Or : public ExprNode<Or> {
178
179 static Expr make(Expr a, Expr b);
180
182};
183
184/** Logical not - true if the expression false */
185struct Not : public ExprNode<Not> {
187
188 static Expr make(Expr a);
189
191};
192
193/** A ternary operator. Evalutes 'true_value' and 'false_value',
194 * then selects between them based on 'condition'. Equivalent to
195 * the ternary operator in C. */
196struct Select : public ExprNode<Select> {
198
200
202};
203
204/** Load a value from a named symbol if predicate is true. The buffer
205 * is treated as an array of the 'type' of this Load node. That is,
206 * the buffer has no inherent type. The name may be the name of an
207 * enclosing allocation, an input or output buffer, or any other
208 * symbol of type Handle(). */
209struct Load : public ExprNode<Load> {
210 std::string name;
211
213
214 // If it's a load from an image argument or compiled-in constant
215 // image, this will point to that
217
218 // If it's a load from an image parameter, this points to that
220
221 // The alignment of the index. If the index is a vector, this is
222 // the alignment of the first lane.
224
225 static Expr make(Type type, const std::string &name,
230
232};
233
234/** A linear ramp vector node. This is vector with 'lanes' elements,
235 * where element i is 'base' + i*'stride'. This is a convenient way to
236 * pass around vectors without busting them up into individual
237 * elements. E.g. a dense vector load from a buffer can use a ramp
238 * node with stride 1 as the index. */
239struct Ramp : public ExprNode<Ramp> {
241 int lanes;
242
244
246};
247
248/** A vector with 'lanes' elements, in which every element is
249 * 'value'. This is a special case of the ramp node above, in which
250 * the stride is zero. */
251struct Broadcast : public ExprNode<Broadcast> {
253 int lanes;
254
255 static Expr make(Expr value, int lanes);
256
258};
259
260/** A let expression, like you might find in a functional
261 * language. Within the expression \ref Let::body, instances of the Var
262 * node \ref Let::name refer to \ref Let::value. */
263struct Let : public ExprNode<Let> {
264 std::string name;
266
267 static Expr make(const std::string &name, Expr value, Expr body);
268
270};
271
272/** The statement form of a let node. Within the statement 'body',
273 * instances of the Var named 'name' refer to 'value' */
274struct LetStmt : public StmtNode<LetStmt> {
275 std::string name;
278
279 static Stmt make(const std::string &name, Expr value, Stmt body);
280
282};
283
284/** If the 'condition' is false, then evaluate and return the message,
285 * which should be a call to an error function. */
286struct AssertStmt : public StmtNode<AssertStmt> {
287 // if condition then val else error out with message
290
292
294};
295
296/** This node is a helpful annotation to do with permissions. If 'is_produce' is
297 * set to true, this represents a producer node which may also contain updates;
298 * otherwise, this represents a consumer node. If the producer node contains
299 * updates, the body of the node will be a block of 'produce' and 'update'
300 * in that order. In a producer node, the access is read-write only (or write
301 * only if it doesn't have updates). In a consumer node, the access is read-only.
302 * None of this is actually enforced, the node is purely for informative purposes
303 * to help out our analysis during lowering. For every unique ProducerConsumer,
304 * there is an associated Realize node with the same name that creates the buffer
305 * being read from or written to in the body of the ProducerConsumer.
306 */
307struct ProducerConsumer : public StmtNode<ProducerConsumer> {
308 std::string name;
311
312 static Stmt make(const std::string &name, bool is_producer, Stmt body);
313
314 static Stmt make_produce(const std::string &name, Stmt body);
315 static Stmt make_consume(const std::string &name, Stmt body);
316
318};
319
320/** Store a 'value' to the buffer called 'name' at a given 'index' if
321 * 'predicate' is true. The buffer is interpreted as an array of the
322 * same type as 'value'. The name may be the name of an enclosing
323 * Allocate node, an output buffer, or any other symbol of type
324 * Handle(). */
325struct Store : public StmtNode<Store> {
326 std::string name;
328 // If it's a store to an output buffer, then this parameter points to it.
330
331 // The alignment of the index. If the index is a vector, this is
332 // the alignment of the first lane.
334
335 static Stmt make(const std::string &name, Expr value, Expr index,
337
339};
340
341/** This defines the value of a function at a multi-dimensional
342 * location. You should think of it as a store to a multi-dimensional
343 * array. It gets lowered to a conventional Store node. The name must
344 * correspond to an output buffer or the name of an enclosing Realize
345 * node. */
346struct Provide : public StmtNode<Provide> {
347 std::string name;
348 std::vector<Expr> values;
349 std::vector<Expr> args;
351
352 static Stmt make(const std::string &name, const std::vector<Expr> &values, const std::vector<Expr> &args, const Expr &predicate);
353
355};
356
357/** Allocate a scratch area called with the given name, type, and
358 * size. The buffer lives for at most the duration of the body
359 * statement, within which it may or may not be freed explicitly with
360 * a Free node with a matching name. Allocation only occurs if the
361 * condition evaluates to true. Within the body of the allocation,
362 * defines a symbol with the given name and the type Handle(). */
363struct Allocate : public StmtNode<Allocate> {
364 std::string name;
367 std::vector<Expr> extents;
368
369 // A boolean condition that determines if the allocation needs to be made at all.
371
372 // These override the code generator dependent malloc and free
373 // equivalents if provided. If the new_expr succeeds, that is it
374 // returns non-nullptr, the function named be free_function is
375 // guaranteed to be called. The free function signature must match
376 // that of the code generator dependent free (typically
377 // halide_free). If free_function is left empty, code generator
378 // default will be called.
380 std::string free_function;
381
382 // Extra padding elements to allow for overreads. Elements in the padding
383 // have undetermined values, but are guaranteed safe to load.
385
387
388 static Stmt make(const std::string &name, Type type, MemoryType memory_type,
389 const std::vector<Expr> &extents,
391 Expr new_expr = Expr(), const std::string &free_function = std::string(), int padding = 0);
392
393 /** A routine to check if the extents are all constants, and if so verify
394 * the total size is less than 2^31 - 1. If the result is constant, but
395 * overflows, this routine asserts. This returns 0 if the extents are
396 * not all constants; otherwise, it returns the total constant allocation
397 * size. Does not include any padding bytes. */
398 static int32_t constant_allocation_size(const std::vector<Expr> &extents, const std::string &name);
400
402};
403
404/** Free the resources associated with the given buffer. */
405struct Free : public StmtNode<Free> {
406 std::string name;
407
408 static Stmt make(const std::string &name);
409
411};
412
413/** Allocate a multi-dimensional buffer of the given type and
414 * size. Create some scratch memory that will back the function 'name'
415 * over the range specified in 'bounds'. The bounds are a vector of
416 * (min, extent) pairs for each dimension. Allocation only occurs if
417 * the condition evaluates to true.
418 */
419struct Realize : public StmtNode<Realize> {
420 std::string name;
421 std::vector<Type> types;
426
427 static Stmt make(const std::string &name, const std::vector<Type> &types, MemoryType memory_type, const Region &bounds, Expr condition, Stmt body);
428
430};
431
432/** A sequence of statements to be executed in-order. 'first' is never
433 a Block, so this can be treated as a linked list. */
434struct Block : public StmtNode<Block> {
436
438
439 /** Construct zero or more Blocks to invoke a list of statements in order.
440 * This method may not return a Block statement if stmts.size() <= 1. */
441 static Stmt make(const std::vector<Stmt> &stmts);
442
444};
445
446/** A pair of statements executed concurrently. Both statements are
447 * joined before the Stmt ends. This is the parallel equivalent to
448 * Block. */
449struct Fork : public StmtNode<Fork> {
451
453
455};
456
457/** An if-then-else block. 'else' may be undefined. */
458struct IfThenElse : public StmtNode<IfThenElse> {
461
463
465};
466
467/** Evaluate and discard an expression, presumably because it has some side-effect. */
468struct Evaluate : public StmtNode<Evaluate> {
470
471 static Stmt make(Expr v);
472
474};
475
476/** A function call. This can represent a call to some extern function
477 * (like sin), but it's also our multi-dimensional version of a Load,
478 * so it can be a load from an input image, or a call to another
479 * halide function. These two types of call nodes don't survive all
480 * the way down to code generation - the lowering process converts
481 * them to Load nodes. */
482struct Call : public ExprNode<Call> {
483 std::string name;
484 std::vector<Expr> args;
485 typedef enum { Image, ///< A load from an input image
486 Extern, ///< A call to an external C-ABI function, possibly with side-effects
487 ExternCPlusPlus, ///< A call to an external C-ABI function, possibly with side-effects
488 PureExtern, ///< A call to a guaranteed-side-effect-free external function
489 Halide, ///< A call to a Func
490 Intrinsic, ///< A possibly-side-effecty compiler intrinsic, which has special handling during codegen
491 PureIntrinsic ///< A side-effect-free version of the above.
494
495 // Halide uses calls internally to represent certain operations
496 // (instead of IR nodes). These are matched by name. Note that
497 // these are deliberately char* (rather than std::string) so that
498 // they can be referenced at static-initialization time without
499 // risking ambiguous initalization order; we use a typedef to simplify
500 // declaration.
501 typedef const char *const ConstString;
502
503 // enums for various well-known intrinsics. (It is not *required* that all
504 // intrinsics have an enum entry here, but as a matter of style, it is recommended.)
505 // Note that these are only used in the API; inside the node, they are translated
506 // into a name. (To recover the name, call get_intrinsic_name().)
507 //
508 // Please keep this list sorted alphabetically; the specific enum values
509 // are *not* guaranteed to be stable across time.
520
521 // Bundle multiple exprs together temporarily for analysis (e.g. CSE)
525
526 // Concatenate bits of the args, with least significant bits as the
527 // first arg (i.e. little-endian)
535
536 // Extract some contiguous slice of bits from the argument starting at
537 // the nth bit, counting from the least significant bit, with the number
538 // of bits determined by the return type.
571
572 // Round a floating point value to nearest integer, with ties going to even
574
588
589 // Compute (arg[0] + arg[1]) / 2, assuming arg[0] < arg[1].
596
597 // One-sided variants of widening_add, widening_mul, and widening_sub.
598 // arg[0] + widen(arg[1])
600 // arg[0] * widen(arg[1])
602 // arg[0] - widen(arg[1])
604
610
611 IntrinsicOpCount // Sentinel: keep last.
612 };
613
614 static const char *get_intrinsic_name(IntrinsicOp op);
615
616 // We also declare some symbolic names for some of the runtime
617 // functions that we want to construct Call nodes to here to avoid
618 // magic string constants and the potential risk of typos.
640
641 // If it's a call to another halide function, this call node holds
642 // a possibly-weak reference to that function.
644
645 // If that function has multiple values, which value does this
646 // call node refer to?
648
649 // If it's a call to an image, this call nodes hold a
650 // pointer to that image's buffer
652
653 // If it's a call to an image parameter, this call node holds a
654 // pointer to that
656
657 static Expr make(Type type, IntrinsicOp op, const std::vector<Expr> &args, CallType call_type,
660
661 static Expr make(Type type, const std::string &name, const std::vector<Expr> &args, CallType call_type,
664
665 /** Convenience constructor for calls to other halide functions */
666 static Expr make(const Function &func, const std::vector<Expr> &args, int idx = 0);
667
668 /** Convenience constructor for loads from concrete images */
669 static Expr make(const Buffer<> &image, const std::vector<Expr> &args) {
670 return make(image.type(), image.name(), args, Image, FunctionPtr(), 0, image, Parameter());
671 }
672
673 /** Convenience constructor for loads from images parameters */
674 static Expr make(const Parameter &param, const std::vector<Expr> &args) {
675 return make(param.type(), param.name(), args, Image, FunctionPtr(), 0, Buffer<>(), param);
676 }
677
678 /** Check if a call node is pure within a pipeline, meaning that
679 * the same args always give the same result, and the calls can be
680 * reordered, duplicated, unified, etc without changing the
681 * meaning of anything. Not transitive - doesn't guarantee the
682 * args themselves are pure. An example of a pure Call node is
683 * sqrt. If in doubt, don't mark a Call node as pure. */
684 bool is_pure() const {
685 return (call_type == PureExtern ||
686 call_type == Image ||
688 }
689
690 bool is_intrinsic() const {
691 return (call_type == Intrinsic ||
693 }
694
695 bool is_intrinsic(IntrinsicOp op) const {
696 return is_intrinsic() && this->name == get_intrinsic_name(op);
697 }
698
699 bool is_intrinsic(std::initializer_list<IntrinsicOp> intrinsics) const {
700 for (IntrinsicOp i : intrinsics) {
701 if (is_intrinsic(i)) {
702 return true;
703 }
704 }
705 return false;
706 }
707
708 bool is_tag() const {
710 }
711
712 /** Returns a pointer to a call node if the expression is a call to
713 * one of the requested intrinsics. */
714 static const Call *as_intrinsic(const Expr &e, std::initializer_list<IntrinsicOp> intrinsics) {
715 if (const Call *c = e.as<Call>()) {
716 for (IntrinsicOp i : intrinsics) {
717 if (c->is_intrinsic(i)) {
718 return c;
719 }
720 }
721 }
722 return nullptr;
723 }
724
725 static const Call *as_tag(const Expr &e) {
727 }
728
729 bool is_extern() const {
730 return (call_type == Extern ||
733 }
734
736};
737
738/** A named variable. Might be a loop variable, function argument,
739 * parameter, reduction variable, or something defined by a Let or
740 * LetStmt node. */
741struct Variable : public ExprNode<Variable> {
742 std::string name;
743
744 /** References to scalar parameters, or to the dimensions of buffer
745 * parameters hang onto those expressions. */
747
748 /** References to properties of literal image parameters. */
750
751 /** Reduction variables hang onto their domains */
753
754 static Expr make(Type type, const std::string &name) {
756 }
757
758 static Expr make(Type type, const std::string &name, Parameter param) {
759 return make(type, name, Buffer<>(), std::move(param), ReductionDomain());
760 }
761
762 static Expr make(Type type, const std::string &name, const Buffer<> &image) {
764 }
765
766 static Expr make(Type type, const std::string &name, ReductionDomain reduction_domain) {
767 return make(type, name, Buffer<>(), Parameter(), std::move(reduction_domain));
768 }
769
770 static Expr make(Type type, const std::string &name, Buffer<> image,
772
774};
775
776/** A for loop. Execute the 'body' statement for all values of the
777 * variable 'name' from 'min' to 'min + extent'. There are four
778 * types of For nodes. A 'Serial' for loop is a conventional
779 * one. In a 'Parallel' for loop, each iteration of the loop
780 * happens in parallel or in some unspecified order. In a
781 * 'Vectorized' for loop, each iteration maps to one SIMD lane,
782 * and the whole loop is executed in one shot. For this case,
783 * 'extent' must be some small integer constant (probably 4, 8, or
784 * 16). An 'Unrolled' for loop compiles to a completely unrolled
785 * version of the loop. Each iteration becomes its own
786 * statement. Again in this case, 'extent' should be a small
787 * integer constant. */
788struct For : public StmtNode<For> {
789 std::string name;
794
796
799 }
800 bool is_parallel() const {
802 }
803
805};
806
807struct Acquire : public StmtNode<Acquire> {
811
813
815};
816
817/** Construct a new vector by taking elements from another sequence of
818 * vectors. */
819struct Shuffle : public ExprNode<Shuffle> {
820 std::vector<Expr> vectors;
821
822 /** Indices indicating which vector element to place into the
823 * result. The elements are numbered by their position in the
824 * concatenation of the vector arguments. */
825 std::vector<int> indices;
826
827 static Expr make(const std::vector<Expr> &vectors,
828 const std::vector<int> &indices);
829
830 /** Convenience constructor for making a shuffle representing an
831 * interleaving of vectors of the same length. */
832 static Expr make_interleave(const std::vector<Expr> &vectors);
833
834 /** Convenience constructor for making a shuffle representing a
835 * concatenation of the vectors. */
836 static Expr make_concat(const std::vector<Expr> &vectors);
837
838 /** Convenience constructor for making a shuffle representing a
839 * broadcast of a vector. */
840 static Expr make_broadcast(Expr vector, int factor);
841
842 /** Convenience constructor for making a shuffle representing a
843 * contiguous subset of a vector. */
844 static Expr make_slice(Expr vector, int begin, int stride, int size);
845
846 /** Convenience constructor for making a shuffle representing
847 * extracting a single element. */
848 static Expr make_extract_element(Expr vector, int i);
849
850 /** Check if this shuffle is an interleaving of the vector
851 * arguments. */
852 bool is_interleave() const;
853
854 /** Check if this shuffle can be represented as a broadcast.
855 * For example:
856 * A uint8 shuffle of with 4*n lanes and indices:
857 * 0, 1, 2, 3, 0, 1, 2, 3, ....., 0, 1, 2, 3
858 * can be represented as a uint32 broadcast with n lanes (factor = 4). */
859 bool is_broadcast() const;
860 int broadcast_factor() const;
861
862 /** Check if this shuffle is a concatenation of the vector
863 * arguments. */
864 bool is_concat() const;
865
866 /** Check if this shuffle is a contiguous strict subset of the
867 * vector arguments, and if so, the offset and stride of the
868 * slice. */
869 ///@{
870 bool is_slice() const;
871 int slice_begin() const {
872 return indices[0];
873 }
874 int slice_stride() const {
875 return indices.size() >= 2 ? indices[1] - indices[0] : 1;
876 }
877 ///@}
878
879 /** Check if this shuffle is extracting a scalar from the vector
880 * arguments. */
881 bool is_extract_element() const;
882
884};
885
886/** Represent a multi-dimensional region of a Func or an ImageParam that
887 * needs to be prefetched. */
888struct Prefetch : public StmtNode<Prefetch> {
889 std::string name;
890 std::vector<Type> types;
894
896
897 static Stmt make(const std::string &name, const std::vector<Type> &types,
898 const Region &bounds,
901
903};
904
905/** Lock all the Store nodes in the body statement.
906 * Typically the lock is implemented by an atomic operation
907 * (e.g. atomic add or atomic compare-and-swap).
908 * However, if necessary, the node can access a mutex buffer through
909 * mutex_name and mutex_args, by lowering this node into
910 * calls to acquire and release the lock. */
911struct Atomic : public StmtNode<Atomic> {
912 std::string producer_name;
913 std::string mutex_name; // empty string if not using mutex
915
916 static Stmt make(const std::string &producer_name,
917 const std::string &mutex_name,
918 Stmt body);
919
921};
922
923/** Horizontally reduce a vector to a scalar or narrower vector using
924 * the given commutative and associative binary operator. The reduction
925 * factor is dictated by the number of lanes in the input and output
926 * types. Groups of adjacent lanes are combined. The number of lanes
927 * in the input type must be a divisor of the number of lanes of the
928 * output type. */
929struct VectorReduce : public ExprNode<VectorReduce> {
930 // 99.9% of the time people will use this for horizontal addition,
931 // but these are all of our commutative and associative primitive
932 // operators.
933 typedef enum {
941 } Operator;
942
945
946 static Expr make(Operator op, Expr vec, int lanes);
947
949};
950
951} // namespace Internal
952} // namespace Halide
953
954#endif
Base classes for Halide expressions (Halide::Expr) and statements (Halide::Internal::Stmt)
Routines for statically determining what expressions are divisible by.
Defines the internal representation of parameters to halide piplines.
Defines the PrefetchDirective struct.
Defines internal classes related to Reduction Domains.
Defines halide types.
#define HALIDE_EXPORT
Definition: Util.h:37
Type type() const
Definition: Buffer.h:533
const std::string & name() const
Definition: Buffer.h:367
A reference-counted handle to Halide's internal representation of a function.
Definition: Function.h:39
A reference-counted handle to a parameter to a halide pipeline.
Definition: Parameter.h:28
const std::string & name() const
Get the name of this parameter.
Type type() const
Get the type of this parameter.
A reference-counted handle on a reduction domain, which is just a vector of ReductionVariable.
Definition: Reduction.h:33
ForType
An enum describing a type of loop traversal.
Definition: Expr.h:400
bool is_unordered_parallel(ForType for_type)
Check if for_type executes for loop iterations in parallel and unordered.
bool is_parallel(ForType for_type)
Returns true if for_type executes for loop iterations in parallel.
IRNodeType
All our IR node types get unique IDs for the purposes of RTTI.
Definition: Expr.h:25
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
@ Internal
Not visible externally, similar to 'static' linkage in C.
DeviceAPI
An enum describing a type of device API.
Definition: DeviceAPI.h:15
std::vector< Range > Region
A multi-dimensional box.
Definition: Expr.h:344
MemoryType
An enum describing different address spaces to be used with Func::store_in.
Definition: Expr.h:347
signed __INT32_TYPE__ int32_t
A fragment of Halide syntax.
Definition: Expr.h:257
static const IRNodeType _node_type
Definition: IR.h:814
static Stmt make(Expr semaphore, Expr count, Stmt body)
The sum of two expressions.
Definition: IR.h:48
static Expr make(Expr a, Expr b)
static const IRNodeType _node_type
Definition: IR.h:53
Allocate a scratch area called with the given name, type, and size.
Definition: IR.h:363
std::string name
Definition: IR.h:364
std::vector< Expr > extents
Definition: IR.h:367
static int32_t constant_allocation_size(const std::vector< Expr > &extents, const std::string &name)
A routine to check if the extents are all constants, and if so verify the total size is less than 2^3...
static const IRNodeType _node_type
Definition: IR.h:401
int32_t constant_allocation_size() const
MemoryType memory_type
Definition: IR.h:366
std::string free_function
Definition: IR.h:380
static Stmt make(const std::string &name, Type type, MemoryType memory_type, const std::vector< Expr > &extents, Expr condition, Stmt body, Expr new_expr=Expr(), const std::string &free_function=std::string(), int padding=0)
Logical and - are both expressions true.
Definition: IR.h:167
static const IRNodeType _node_type
Definition: IR.h:172
static Expr make(Expr a, Expr b)
If the 'condition' is false, then evaluate and return the message, which should be a call to an error...
Definition: IR.h:286
static const IRNodeType _node_type
Definition: IR.h:293
static Stmt make(Expr condition, Expr message)
Lock all the Store nodes in the body statement.
Definition: IR.h:911
static const IRNodeType _node_type
Definition: IR.h:920
static Stmt make(const std::string &producer_name, const std::string &mutex_name, Stmt body)
std::string mutex_name
Definition: IR.h:913
std::string producer_name
Definition: IR.h:912
A sequence of statements to be executed in-order.
Definition: IR.h:434
static Stmt make(const std::vector< Stmt > &stmts)
Construct zero or more Blocks to invoke a list of statements in order.
static Stmt make(Stmt first, Stmt rest)
static const IRNodeType _node_type
Definition: IR.h:443
A vector with 'lanes' elements, in which every element is 'value'.
Definition: IR.h:251
static Expr make(Expr value, int lanes)
static const IRNodeType _node_type
Definition: IR.h:257
A function call.
Definition: IR.h:482
static Expr make(Type type, const std::string &name, const std::vector< Expr > &args, CallType call_type, FunctionPtr func=FunctionPtr(), int value_index=0, Buffer<> image=Buffer<>(), Parameter param=Parameter())
static HALIDE_EXPORT ConstString buffer_get_max
Definition: IR.h:624
static const Call * as_tag(const Expr &e)
Definition: IR.h:725
static Expr make(const Function &func, const std::vector< Expr > &args, int idx=0)
Convenience constructor for calls to other halide functions.
static HALIDE_EXPORT ConstString buffer_get_host_dirty
Definition: IR.h:629
static HALIDE_EXPORT ConstString buffer_set_bounds
Definition: IR.h:638
const char *const ConstString
Definition: IR.h:501
bool is_tag() const
Definition: IR.h:708
static const Call * as_intrinsic(const Expr &e, std::initializer_list< IntrinsicOp > intrinsics)
Returns a pointer to a call node if the expression is a call to one of the requested intrinsics.
Definition: IR.h:714
@ call_cached_indirect_function
Definition: IR.h:523
@ signed_integer_overflow
Definition: IR.h:586
@ unsafe_promise_clamped
Definition: IR.h:595
@ add_image_checks_marker
Definition: IR.h:513
@ rounding_mul_shift_right
Definition: IR.h:576
@ load_typed_struct_member
Definition: IR.h:556
@ size_of_halide_buffer_t
Definition: IR.h:587
bool is_extern() const
Definition: IR.h:729
@ Extern
A call to an external C-ABI function, possibly with side-effects.
Definition: IR.h:486
@ ExternCPlusPlus
A call to an external C-ABI function, possibly with side-effects.
Definition: IR.h:487
@ Image
A load from an input image.
Definition: IR.h:485
@ Halide
A call to a Func.
Definition: IR.h:489
@ Intrinsic
A possibly-side-effecty compiler intrinsic, which has special handling during codegen.
Definition: IR.h:490
@ PureExtern
A call to a guaranteed-side-effect-free external function.
Definition: IR.h:488
@ PureIntrinsic
A side-effect-free version of the above.
Definition: IR.h:491
std::string name
Definition: IR.h:483
static HALIDE_EXPORT ConstString buffer_get_min
Definition: IR.h:621
bool is_intrinsic() const
Definition: IR.h:690
static HALIDE_EXPORT ConstString buffer_get_device_interface
Definition: IR.h:627
static HALIDE_EXPORT ConstString buffer_get_dimensions
Definition: IR.h:620
static HALIDE_EXPORT ConstString buffer_get_device_dirty
Definition: IR.h:630
static HALIDE_EXPORT ConstString buffer_crop
Definition: IR.h:637
FunctionPtr func
Definition: IR.h:643
CallType call_type
Definition: IR.h:493
static HALIDE_EXPORT ConstString buffer_get_host
Definition: IR.h:625
static Expr make(const Buffer<> &image, const std::vector< Expr > &args)
Convenience constructor for loads from concrete images.
Definition: IR.h:669
static HALIDE_EXPORT ConstString buffer_get_device
Definition: IR.h:626
static HALIDE_EXPORT ConstString buffer_init
Definition: IR.h:635
bool is_pure() const
Check if a call node is pure within a pipeline, meaning that the same args always give the same resul...
Definition: IR.h:684
static HALIDE_EXPORT ConstString buffer_get_stride
Definition: IR.h:623
static HALIDE_EXPORT ConstString buffer_get_extent
Definition: IR.h:622
bool is_intrinsic(std::initializer_list< IntrinsicOp > intrinsics) const
Definition: IR.h:699
static const char * get_intrinsic_name(IntrinsicOp op)
bool is_intrinsic(IntrinsicOp op) const
Definition: IR.h:695
static Expr make(const Parameter &param, const std::vector< Expr > &args)
Convenience constructor for loads from images parameters.
Definition: IR.h:674
static const IRNodeType _node_type
Definition: IR.h:735
static HALIDE_EXPORT ConstString trace
Definition: IR.h:639
std::vector< Expr > args
Definition: IR.h:484
static HALIDE_EXPORT ConstString buffer_get_shape
Definition: IR.h:628
static Expr make(Type type, IntrinsicOp op, const std::vector< Expr > &args, CallType call_type, FunctionPtr func=FunctionPtr(), int value_index=0, const Buffer<> &image=Buffer<>(), Parameter param=Parameter())
Parameter param
Definition: IR.h:655
static HALIDE_EXPORT ConstString buffer_is_bounds_query
Definition: IR.h:634
static HALIDE_EXPORT ConstString buffer_get_type
Definition: IR.h:631
static HALIDE_EXPORT ConstString buffer_set_device_dirty
Definition: IR.h:633
static HALIDE_EXPORT ConstString buffer_set_host_dirty
Definition: IR.h:632
static HALIDE_EXPORT ConstString buffer_init_from_buffer
Definition: IR.h:636
The actual IR nodes begin here.
Definition: IR.h:29
static const IRNodeType _node_type
Definition: IR.h:34
static Expr make(Type t, Expr v)
The ratio of two expressions.
Definition: IR.h:75
static const IRNodeType _node_type
Definition: IR.h:80
static Expr make(Expr a, Expr b)
Is the first expression equal to the second.
Definition: IR.h:113
static const IRNodeType _node_type
Definition: IR.h:118
static Expr make(Expr a, Expr b)
Evaluate and discard an expression, presumably because it has some side-effect.
Definition: IR.h:468
static Stmt make(Expr v)
static const IRNodeType _node_type
Definition: IR.h:473
We use the "curiously recurring template pattern" to avoid duplicated code in the IR Nodes.
Definition: Expr.h:157
A for loop.
Definition: IR.h:788
std::string name
Definition: IR.h:789
DeviceAPI device_api
Definition: IR.h:792
ForType for_type
Definition: IR.h:791
bool is_parallel() const
Definition: IR.h:800
bool is_unordered_parallel() const
Definition: IR.h:797
static const IRNodeType _node_type
Definition: IR.h:804
static Stmt make(const std::string &name, Expr min, Expr extent, ForType for_type, DeviceAPI device_api, Stmt body)
A pair of statements executed concurrently.
Definition: IR.h:449
static Stmt make(Stmt first, Stmt rest)
static const IRNodeType _node_type
Definition: IR.h:454
Free the resources associated with the given buffer.
Definition: IR.h:405
static const IRNodeType _node_type
Definition: IR.h:410
static Stmt make(const std::string &name)
std::string name
Definition: IR.h:406
A possibly-weak pointer to a Halide function.
Definition: FunctionPtr.h:27
Is the first expression greater than or equal to the second.
Definition: IR.h:158
static const IRNodeType _node_type
Definition: IR.h:163
static Expr make(Expr a, Expr b)
Is the first expression greater than the second.
Definition: IR.h:149
static const IRNodeType _node_type
Definition: IR.h:154
static Expr make(Expr a, Expr b)
const T * as() const
Downcast this ir node to its actual type (e.g.
Definition: Expr.h:204
An if-then-else block.
Definition: IR.h:458
static const IRNodeType _node_type
Definition: IR.h:464
static Stmt make(Expr condition, Stmt then_case, Stmt else_case=Stmt())
Is the first expression less than or equal to the second.
Definition: IR.h:140
static Expr make(Expr a, Expr b)
static const IRNodeType _node_type
Definition: IR.h:145
Is the first expression less than the second.
Definition: IR.h:131
static Expr make(Expr a, Expr b)
static const IRNodeType _node_type
Definition: IR.h:136
A let expression, like you might find in a functional language.
Definition: IR.h:263
std::string name
Definition: IR.h:264
static Expr make(const std::string &name, Expr value, Expr body)
static const IRNodeType _node_type
Definition: IR.h:269
The statement form of a let node.
Definition: IR.h:274
static Stmt make(const std::string &name, Expr value, Stmt body)
std::string name
Definition: IR.h:275
static const IRNodeType _node_type
Definition: IR.h:281
Load a value from a named symbol if predicate is true.
Definition: IR.h:209
std::string name
Definition: IR.h:210
static Expr make(Type type, const std::string &name, Expr index, Buffer<> image, Parameter param, Expr predicate, ModulusRemainder alignment)
Parameter param
Definition: IR.h:219
static const IRNodeType _node_type
Definition: IR.h:231
ModulusRemainder alignment
Definition: IR.h:223
The greater of two values.
Definition: IR.h:104
static const IRNodeType _node_type
Definition: IR.h:109
static Expr make(Expr a, Expr b)
The lesser of two values.
Definition: IR.h:95
static const IRNodeType _node_type
Definition: IR.h:100
static Expr make(Expr a, Expr b)
The remainder of a / b.
Definition: IR.h:86
static const IRNodeType _node_type
Definition: IR.h:91
static Expr make(Expr a, Expr b)
The result of modulus_remainder analysis.
The product of two expressions.
Definition: IR.h:66
static const IRNodeType _node_type
Definition: IR.h:71
static Expr make(Expr a, Expr b)
Is the first expression not equal to the second.
Definition: IR.h:122
static const IRNodeType _node_type
Definition: IR.h:127
static Expr make(Expr a, Expr b)
Logical not - true if the expression false.
Definition: IR.h:185
static Expr make(Expr a)
static const IRNodeType _node_type
Definition: IR.h:190
Logical or - is at least one of the expression true.
Definition: IR.h:176
static Expr make(Expr a, Expr b)
static const IRNodeType _node_type
Definition: IR.h:181
Represent a multi-dimensional region of a Func or an ImageParam that needs to be prefetched.
Definition: IR.h:888
static Stmt make(const std::string &name, const std::vector< Type > &types, const Region &bounds, const PrefetchDirective &prefetch, Expr condition, Stmt body)
static const IRNodeType _node_type
Definition: IR.h:902
PrefetchDirective prefetch
Definition: IR.h:892
std::vector< Type > types
Definition: IR.h:890
std::string name
Definition: IR.h:889
This node is a helpful annotation to do with permissions.
Definition: IR.h:307
static const IRNodeType _node_type
Definition: IR.h:317
static Stmt make_consume(const std::string &name, Stmt body)
static Stmt make_produce(const std::string &name, Stmt body)
static Stmt make(const std::string &name, bool is_producer, Stmt body)
This defines the value of a function at a multi-dimensional location.
Definition: IR.h:346
static const IRNodeType _node_type
Definition: IR.h:354
std::string name
Definition: IR.h:347
std::vector< Expr > values
Definition: IR.h:348
std::vector< Expr > args
Definition: IR.h:349
static Stmt make(const std::string &name, const std::vector< Expr > &values, const std::vector< Expr > &args, const Expr &predicate)
A linear ramp vector node.
Definition: IR.h:239
static const IRNodeType _node_type
Definition: IR.h:245
static Expr make(Expr base, Expr stride, int lanes)
Allocate a multi-dimensional buffer of the given type and size.
Definition: IR.h:419
static Stmt make(const std::string &name, const std::vector< Type > &types, MemoryType memory_type, const Region &bounds, Expr condition, Stmt body)
MemoryType memory_type
Definition: IR.h:422
std::vector< Type > types
Definition: IR.h:421
static const IRNodeType _node_type
Definition: IR.h:429
std::string name
Definition: IR.h:420
Reinterpret value as another type, without affecting any of the bits (on little-endian systems).
Definition: IR.h:39
static const IRNodeType _node_type
Definition: IR.h:44
static Expr make(Type t, Expr v)
A ternary operator.
Definition: IR.h:196
static Expr make(Expr condition, Expr true_value, Expr false_value)
static const IRNodeType _node_type
Definition: IR.h:201
Construct a new vector by taking elements from another sequence of vectors.
Definition: IR.h:819
static Expr make_slice(Expr vector, int begin, int stride, int size)
Convenience constructor for making a shuffle representing a contiguous subset of a vector.
bool is_interleave() const
Check if this shuffle is an interleaving of the vector arguments.
static Expr make_extract_element(Expr vector, int i)
Convenience constructor for making a shuffle representing extracting a single element.
bool is_extract_element() const
Check if this shuffle is extracting a scalar from the vector arguments.
bool is_broadcast() const
Check if this shuffle can be represented as a broadcast.
static Expr make_concat(const std::vector< Expr > &vectors)
Convenience constructor for making a shuffle representing a concatenation of the vectors.
static Expr make(const std::vector< Expr > &vectors, const std::vector< int > &indices)
static const IRNodeType _node_type
Definition: IR.h:883
static Expr make_broadcast(Expr vector, int factor)
Convenience constructor for making a shuffle representing a broadcast of a vector.
std::vector< Expr > vectors
Definition: IR.h:820
bool is_concat() const
Check if this shuffle is a concatenation of the vector arguments.
bool is_slice() const
Check if this shuffle is a contiguous strict subset of the vector arguments, and if so,...
std::vector< int > indices
Indices indicating which vector element to place into the result.
Definition: IR.h:825
int slice_stride() const
Check if this shuffle is a contiguous strict subset of the vector arguments, and if so,...
Definition: IR.h:874
static Expr make_interleave(const std::vector< Expr > &vectors)
Convenience constructor for making a shuffle representing an interleaving of vectors of the same leng...
int slice_begin() const
Check if this shuffle is a contiguous strict subset of the vector arguments, and if so,...
Definition: IR.h:871
A reference-counted handle to a statement node.
Definition: Expr.h:418
Store a 'value' to the buffer called 'name' at a given 'index' if 'predicate' is true.
Definition: IR.h:325
std::string name
Definition: IR.h:326
static const IRNodeType _node_type
Definition: IR.h:338
Parameter param
Definition: IR.h:329
ModulusRemainder alignment
Definition: IR.h:333
static Stmt make(const std::string &name, Expr value, Expr index, Parameter param, Expr predicate, ModulusRemainder alignment)
The difference of two expressions.
Definition: IR.h:57
static const IRNodeType _node_type
Definition: IR.h:62
static Expr make(Expr a, Expr b)
A named variable.
Definition: IR.h:741
static Expr make(Type type, const std::string &name, const Buffer<> &image)
Definition: IR.h:762
static Expr make(Type type, const std::string &name, Parameter param)
Definition: IR.h:758
static Expr make(Type type, const std::string &name, Buffer<> image, Parameter param, ReductionDomain reduction_domain)
Buffer image
References to properties of literal image parameters.
Definition: IR.h:749
ReductionDomain reduction_domain
Reduction variables hang onto their domains.
Definition: IR.h:752
static Expr make(Type type, const std::string &name)
Definition: IR.h:754
Parameter param
References to scalar parameters, or to the dimensions of buffer parameters hang onto those expression...
Definition: IR.h:746
static Expr make(Type type, const std::string &name, ReductionDomain reduction_domain)
Definition: IR.h:766
std::string name
Definition: IR.h:742
static const IRNodeType _node_type
Definition: IR.h:773
Horizontally reduce a vector to a scalar or narrower vector using the given commutative and associati...
Definition: IR.h:929
static const IRNodeType _node_type
Definition: IR.h:948
static Expr make(Operator op, Expr vec, int lanes)
Types in the halide type system.
Definition: Type.h:276