1 #ifndef HALIDE_IR_VISITOR_H 2 #define HALIDE_IR_VISITOR_H 98 std::set<IRHandle> visited;
118 void visit(
const EQ *)
override;
119 void visit(
const NE *)
override;
120 void visit(
const LT *)
override;
121 void visit(
const LE *)
override;
122 void visit(
const GT *)
override;
123 void visit(
const GE *)
override;
125 void visit(
const Or *)
override;
160 template<
typename T,
typename ExprRet,
typename StmtRet>
163 template<
typename... Args>
164 ExprRet dispatch_expr(
const BaseExprNode *node, Args &&...args) {
165 if (node ==
nullptr) {
170 return ((T *)
this)->visit((
const IntImm *)node, std::forward<Args>(args)...);
172 return ((T *)
this)->visit((
const UIntImm *)node, std::forward<Args>(args)...);
174 return ((T *)
this)->visit((
const FloatImm *)node, std::forward<Args>(args)...);
176 return ((T *)
this)->visit((
const StringImm *)node, std::forward<Args>(args)...);
178 return ((T *)
this)->visit((
const Broadcast *)node, std::forward<Args>(args)...);
180 return ((T *)
this)->visit((
const Cast *)node, std::forward<Args>(args)...);
182 return ((T *)
this)->visit((
const Reinterpret *)node, std::forward<Args>(args)...);
184 return ((T *)
this)->visit((
const Variable *)node, std::forward<Args>(args)...);
186 return ((T *)
this)->visit((
const Add *)node, std::forward<Args>(args)...);
188 return ((T *)
this)->visit((
const Sub *)node, std::forward<Args>(args)...);
190 return ((T *)
this)->visit((
const Mod *)node, std::forward<Args>(args)...);
192 return ((T *)
this)->visit((
const Mul *)node, std::forward<Args>(args)...);
194 return ((T *)
this)->visit((
const Div *)node, std::forward<Args>(args)...);
196 return ((T *)
this)->visit((
const Min *)node, std::forward<Args>(args)...);
198 return ((T *)
this)->visit((
const Max *)node, std::forward<Args>(args)...);
200 return ((T *)
this)->visit((
const EQ *)node, std::forward<Args>(args)...);
202 return ((T *)
this)->visit((
const NE *)node, std::forward<Args>(args)...);
204 return ((T *)
this)->visit((
const LT *)node, std::forward<Args>(args)...);
206 return ((T *)
this)->visit((
const LE *)node, std::forward<Args>(args)...);
208 return ((T *)
this)->visit((
const GT *)node, std::forward<Args>(args)...);
210 return ((T *)
this)->visit((
const GE *)node, std::forward<Args>(args)...);
212 return ((T *)
this)->visit((
const And *)node, std::forward<Args>(args)...);
214 return ((T *)
this)->visit((
const Or *)node, std::forward<Args>(args)...);
216 return ((T *)
this)->visit((
const Not *)node, std::forward<Args>(args)...);
218 return ((T *)
this)->visit((
const Select *)node, std::forward<Args>(args)...);
220 return ((T *)
this)->visit((
const Load *)node, std::forward<Args>(args)...);
222 return ((T *)
this)->visit((
const Ramp *)node, std::forward<Args>(args)...);
224 return ((T *)
this)->visit((
const Call *)node, std::forward<Args>(args)...);
226 return ((T *)
this)->visit((
const Let *)node, std::forward<Args>(args)...);
228 return ((T *)
this)->visit((
const Shuffle *)node, std::forward<Args>(args)...);
230 return ((T *)
this)->visit((
const VectorReduce *)node, std::forward<Args>(args)...);
256 template<
typename... Args>
257 StmtRet dispatch_stmt(
const BaseStmtNode *node, Args &&...args) {
258 if (node ==
nullptr) {
296 return ((T *)
this)->visit((
const LetStmt *)node, std::forward<Args>(args)...);
298 return ((T *)
this)->visit((
const AssertStmt *)node, std::forward<Args>(args)...);
300 return ((T *)
this)->visit((
const ProducerConsumer *)node, std::forward<Args>(args)...);
302 return ((T *)
this)->visit((
const For *)node, std::forward<Args>(args)...);
304 return ((T *)
this)->visit((
const Acquire *)node, std::forward<Args>(args)...);
306 return ((T *)
this)->visit((
const Store *)node, std::forward<Args>(args)...);
308 return ((T *)
this)->visit((
const Provide *)node, std::forward<Args>(args)...);
310 return ((T *)
this)->visit((
const Allocate *)node, std::forward<Args>(args)...);
312 return ((T *)
this)->visit((
const Free *)node, std::forward<Args>(args)...);
314 return ((T *)
this)->visit((
const Realize *)node, std::forward<Args>(args)...);
316 return ((T *)
this)->visit((
const Block *)node, std::forward<Args>(args)...);
318 return ((T *)
this)->visit((
const Fork *)node, std::forward<Args>(args)...);
320 return ((T *)
this)->visit((
const IfThenElse *)node, std::forward<Args>(args)...);
322 return ((T *)
this)->visit((
const Evaluate *)node, std::forward<Args>(args)...);
324 return ((T *)
this)->visit((
const Prefetch *)node, std::forward<Args>(args)...);
326 return ((T *)
this)->visit((
const Atomic *)node, std::forward<Args>(args)...);
328 return ((T *)
this)->visit((
const HoistedStorage *)node, std::forward<Args>(args)...);
334 template<
typename... Args>
336 return dispatch_stmt(s.
get(), std::forward<Args>(args)...);
339 template<
typename... Args>
341 return dispatch_stmt(s.get(), std::forward<Args>(args)...);
344 template<
typename... Args>
346 return dispatch_expr(e.
get(), std::forward<Args>(args)...);
349 template<
typename... Args>
351 return dispatch_expr(e.get(), std::forward<Args>(args)...);
Unsigned integer constants.
The actual IR nodes begin here.
A base class for algorithms that need to recursively walk over the IR.
A fragment of Halide syntax.
Is the first expression greater than the second.
HALIDE_ALWAYS_INLINE StmtRet dispatch(Stmt &&s, Args &&...args)
A reference-counted handle to a statement node.
IR nodes are split into expressions and statements.
Load a value from a named symbol if predicate is true.
The difference of two expressions.
We use the "curiously recurring template pattern" to avoid duplicated code in the IR Nodes...
A vector with 'lanes' elements, in which every element is 'value'.
Logical and - are both expressions true.
Logical not - true if the expression false.
Horizontally reduce a vector to a scalar or narrower vector using the given commutative and associati...
Is the first expression less than the second.
The product of two expressions.
Lock all the Store nodes in the body statement.
Floating point constants.
A base class for algorithms that walk recursively over the IR without visiting the same node twice...
The sum of two expressions.
A linear ramp vector node.
Allocate a multi-dimensional buffer of the given type and size.
This file defines the class FunctionDAG, which is our representation of a Halide pipeline, and contains methods to using Halide's bounds tools to query properties of it.
Store a 'value' to the buffer called 'name' at a given 'index' if 'predicate' is true.
Allocate a scratch area called with the given name, type, and size.
A base class for expression nodes.
Is the first expression greater than or equal to the second.
virtual void include(const Expr &)
By default these methods add the node to the visited set, and return whether or not it was already th...
This defines the value of a function at a multi-dimensional location.
Represent a multi-dimensional region of a Func or an ImageParam that needs to be prefetched.
The ratio of two expressions.
IRNodeType node_type
Each IR node subclass has a unique identifier.
void visit(const IntImm *) override
These methods should call 'include' on the children to only visit them if they haven't been visited a...
Is the first expression less than or equal to the second.
Is the first expression not equal to the second.
If the 'condition' is false, then evaluate and return the message, which should be a call to an error...
Not visible externally, similar to 'static' linkage in C.
virtual ~IRVisitor()=default
HALIDE_ALWAYS_INLINE ExprRet dispatch(const Expr &e, Args &&...args)
Is the first expression equal to the second.
Represents a location where storage will be hoisted to for a Func / Realize node with a given name...
The greater of two values.
A pair of statements executed concurrently.
#define HALIDE_ALWAYS_INLINE
A visitor/mutator capable of passing arbitrary arguments to the visit methods using CRTP and returnin...
A let expression, like you might find in a functional language.
Free the resources associated with the given buffer.
Subtypes for Halide expressions (Halide::Expr) and statements (Halide::Internal::Stmt) ...
HALIDE_ALWAYS_INLINE const BaseStmtNode * get() const
Override get() to return a BaseStmtNode * instead of an IRNode *.
HALIDE_ALWAYS_INLINE StmtRet dispatch(const Stmt &s, Args &&...args)
A sequence of statements to be executed in-order.
HALIDE_ALWAYS_INLINE ExprRet dispatch(Expr &&e, Args &&...args)
HALIDE_ALWAYS_INLINE const Internal::BaseExprNode * get() const
Override get() to return a BaseExprNode * instead of an IRNode *.
The lesser of two values.
Reinterpret value as another type, without affecting any of the bits (on little-endian systems)...
The statement form of a let node.
Logical or - is at least one of the expression true.
This node is a helpful annotation to do with permissions.
Evaluate and discard an expression, presumably because it has some side-effect.
Construct a new vector by taking elements from another sequence of vectors.
virtual void visit(const IntImm *)