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