1#ifndef HALIDE_SIMPLIFY_VISITORS_H
2#define HALIDE_SIMPLIFY_VISITORS_H
20#define LOG_EXPR_MUTATIONS 0
21#define LOG_STMT_MUTATIONS 0
28#define EVAL_IN_LAMBDA(x) (([&]() HALIDE_NEVER_INLINE { return (x); })())
137#if (LOG_EXPR_MUTATIONS || LOG_STMT_MUTATIONS)
138 int debug_indent = 0;
141#if LOG_EXPR_MUTATIONS
144 const std::string spaces(debug_indent,
' ');
145 debug(1) << spaces <<
"Simplifying Expr: " << e <<
"\n";
151 << spaces <<
"Before: " << e <<
"\n"
152 << spaces <<
"After: " << new_e <<
"\n";
155 << spaces <<
"Bounds: " << b->bounds <<
" " << b->alignment <<
"\n";
179#if LOG_STMT_MUTATIONS
181 const std::string spaces(debug_indent,
' ');
182 debug(1) << spaces <<
"Simplifying Stmt: " << s <<
"\n";
188 << spaces <<
"Before: " << s <<
"\n"
189 << spaces <<
"After: " << new_s <<
"\n";
275 return va->
name.compare(vb->name) > 0;
332 template<
typename T,
typename Body>
Methods for computing the upper and lower bounds of an expression, and the regions of a function read...
Defines the ConstantInterval class, and operators on it.
#define internal_assert(c)
#define HALIDE_ALWAYS_INLINE
Defines a method to match a fragment of IR against a pattern containing wildcards.
This header file defines operators that let you dump a Halide expression, statement,...
Defines the base class for things that recursively walk over the IR.
Defines the Scope class, which is used for keeping track of names in a scope while traversing IR.
A common pattern when traversing Halide IR is that you need to keep track of stuff when you find a Le...
Stmt visit(const HoistedStorage *op)
Expr visit(const LE *op, ExprInfo *info)
Stmt visit(const ProducerConsumer *op)
HALIDE_ALWAYS_INLINE Expr mutate(const Expr &e, ExprInfo *b)
Scope< ExprInfo > bounds_and_alignment_info
Expr visit(const Variable *op, ExprInfo *info)
IRMatcher::WildConst< 5 > c5
void found_buffer_reference(const std::string &name, size_t dimensions=0)
Stmt visit(const Block *op)
Expr visit(const Load *op, ExprInfo *info)
Expr visit(const Cast *op, ExprInfo *info)
Stmt visit(const AssertStmt *op)
Stmt mutate(const Stmt &s)
Stmt visit(const Evaluate *op)
Expr visit(const Let *op, ExprInfo *info)
Expr visit(const LT *op, ExprInfo *info)
Simplify(bool r, const Scope< Interval > *bi, const Scope< ModulusRemainder > *ai)
Expr visit(const Ramp *op, ExprInfo *info)
Stmt visit(const Prefetch *op)
HALIDE_ALWAYS_INLINE bool no_overflow(Type t)
IRMatcher::WildConst< 1 > c1
Expr visit(const Shuffle *op, ExprInfo *info)
Stmt visit(const IfThenElse *op)
Expr visit(const Mod *op, ExprInfo *info)
IRMatcher::WildConst< 0 > c0
ScopedFact scoped_truth(const Expr &fact)
IRMatcher::WildConst< 3 > c3
Expr visit(const UIntImm *op, ExprInfo *info)
Expr visit(const Add *op, ExprInfo *info)
Expr visit(const Max *op, ExprInfo *info)
HALIDE_ALWAYS_INLINE void clear_expr_info(ExprInfo *b)
Expr visit(const Mul *op, ExprInfo *info)
IRMatcher::WildConst< 2 > c2
Expr visit(const StringImm *op, ExprInfo *info)
Scope< VarInfo > var_info
Expr visit(const VectorReduce *op, ExprInfo *info)
Expr visit(const Min *op, ExprInfo *info)
Expr visit(const Reinterpret *op, ExprInfo *info)
Expr visit(const NE *op, ExprInfo *info)
HALIDE_ALWAYS_INLINE bool may_simplify(const Type &t) const
Stmt visit(const For *op)
Expr visit(const Select *op, ExprInfo *info)
Stmt visit(const Atomic *op)
Expr visit(const Div *op, ExprInfo *info)
Expr visit(const GE *op, ExprInfo *info)
Stmt visit(const Provide *op)
Expr visit(const Not *op, ExprInfo *info)
Body simplify_let(const T *op, ExprInfo *info)
Expr mutate_let_body(const Expr &e, ExprInfo *info)
Expr visit(const Or *op, ExprInfo *info)
Expr visit(const FloatImm *op, ExprInfo *info)
Stmt mutate_let_body(const Stmt &s, ExprInfo *)
Stmt visit(const Acquire *op)
Stmt visit(const Fork *op)
HALIDE_ALWAYS_INLINE bool no_overflow_int(Type t)
std::set< Expr, IRDeepCompare > truths
ScopedFact scoped_falsehood(const Expr &fact)
HALIDE_ALWAYS_INLINE bool should_commute(const Expr &a, const Expr &b)
Expr visit(const Broadcast *op, ExprInfo *info)
Expr visit(const Sub *op, ExprInfo *info)
std::pair< std::vector< Expr >, bool > mutate_with_changes(const std::vector< Expr > &old_exprs)
Stmt visit(const Store *op)
Expr visit(const GT *op, ExprInfo *info)
HALIDE_ALWAYS_INLINE bool no_overflow_scalar_int(Type t)
Stmt visit(const Free *op)
IRMatcher::WildConst< 4 > c4
Expr visit(const Call *op, ExprInfo *info)
Stmt visit(const Allocate *op)
Stmt visit(const Realize *op)
Expr visit(const EQ *op, ExprInfo *info)
Stmt visit(const LetStmt *op)
std::set< Expr, IRDeepCompare > falsehoods
Expr visit(const IntImm *op, ExprInfo *info)
Expr visit(const And *op, ExprInfo *info)
A visitor/mutator capable of passing arbitrary arguments to the visit methods using CRTP and returnin...
HALIDE_ALWAYS_INLINE Stmt dispatch(const Stmt &s, Args &&...args)
For optional debugging during codegen, use the debug class as follows:
std::optional< int64_t > as_const_int(const Expr &e)
If an expression is an IntImm or a Broadcast of an IntImm, return a its value.
std::optional< uint64_t > as_const_uint(const Expr &e)
If an expression is a UIntImm or a Broadcast of a UIntImm, return its value.
T mod_imp(T a, T b)
Implementations of division and mod that are specific to Halide.
HALIDE_MUST_USE_RESULT bool add_with_overflow(int bits, int64_t a, int64_t b, int64_t *result)
Routines to perform arithmetic on signed types without triggering signed overflow.
HALIDE_MUST_USE_RESULT bool sub_with_overflow(int bits, int64_t a, int64_t b, int64_t *result)
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
signed __INT64_TYPE__ int64_t
A fragment of Halide syntax.
HALIDE_ALWAYS_INLINE Type type() const
Get the type of this expression node.
The sum of two expressions.
Allocate a scratch area called with the given name, type, and size.
Logical and - are both expressions true.
If the 'condition' is false, then evaluate and return the message, which should be a call to an error...
Lock all the Store nodes in the body statement.
A sequence of statements to be executed in-order.
A vector with 'lanes' elements, in which every element is 'value'.
The actual IR nodes begin here.
A class to represent ranges of integers.
int64_t min
The lower and upper bound of the interval.
bool is_bounded() const
Does the interval have a finite upper and lower bound.
static ConstantInterval make_intersection(const ConstantInterval &a, const ConstantInterval &b)
Construct the largest interval contained within two intervals.
bool is_single_point() const
Is the interval just a single value (min == max)
void cast_to(const Type &t)
Track what happens if a constant integer interval is forced to fit into a concrete integer type.
static ConstantInterval single_point(int64_t x)
Construct an interval representing a single point.
The ratio of two expressions.
Is the first expression equal to the second.
Evaluate and discard an expression, presumably because it has some side-effect.
Floating point constants.
A pair of statements executed concurrently.
Free the resources associated with the given buffer.
Is the first expression greater than or equal to the second.
Is the first expression greater than the second.
Represents a location where storage will be hoisted to for a Func / Realize node with a given name.
const T * as() const
Downcast this ir node to its actual type (e.g.
IRNodeType node_type() const
HALIDE_ALWAYS_INLINE bool same_as(const IntrusivePtr &other) const
Is the first expression less than or equal to the second.
Is the first expression less than the second.
A let expression, like you might find in a functional language.
The statement form of a let node.
Load a value from a named symbol if predicate is true.
The greater of two values.
The lesser of two values.
The result of modulus_remainder analysis.
static ModulusRemainder intersect(const ModulusRemainder &a, const ModulusRemainder &b)
The product of two expressions.
Is the first expression not equal to the second.
Logical not - true if the expression false.
Logical or - is at least one of the expression true.
Represent a multi-dimensional region of a Func or an ImageParam that needs to be prefetched.
This node is a helpful annotation to do with permissions.
This defines the value of a function at a multi-dimensional location.
A linear ramp vector node.
Allocate a multi-dimensional buffer of the given type and size.
Reinterpret value as another type, without affecting any of the bits (on little-endian systems).
Construct a new vector by taking elements from another sequence of vectors.
void intersect(const ExprInfo &other)
void trim_bounds_using_alignment()
ModulusRemainder alignment
ScopedFact(ScopedFact &&that)=default
void learn_true(const Expr &fact)
void learn_false(const Expr &fact)
std::vector< const Variable * > bounds_pop_list
ScopedFact(const ScopedFact &that)=delete
std::set< Expr, IRDeepCompare > truths
std::vector< const Variable * > pop_list
void learn_lower_bound(const Variable *v, int64_t val)
std::set< Expr, IRDeepCompare > falsehoods
Expr substitute_facts(const Expr &e)
Stmt substitute_facts(const Stmt &s)
void learn_upper_bound(const Variable *v, int64_t val)
A reference-counted handle to a statement node.
Store a 'value' to the buffer called 'name' at a given 'index' if 'predicate' is true.
The difference of two expressions.
Unsigned integer constants.
Horizontally reduce a vector to a scalar or narrower vector using the given commutative and associati...
Types in the halide type system.
HALIDE_ALWAYS_INLINE bool is_int() const
Is this type a signed integer type?
HALIDE_ALWAYS_INLINE bool is_uint() const
Is this type an unsigned integer type?
HALIDE_ALWAYS_INLINE int bits() const
Return the bit size of a single element of this type.
bool can_represent(Type other) const
Can this type represent all values of another type?
HALIDE_ALWAYS_INLINE bool is_scalar() const
Is this type a scalar type? (lanes() == 1).
HALIDE_ALWAYS_INLINE bool is_float() const
Is this type a floating point type (float or double).