1 #ifndef HALIDE_SIMPLIFY_VISITORS_H 2 #define HALIDE_SIMPLIFY_VISITORS_H 18 #define LOG_EXPR_MUTATIONS 0 19 #define LOG_STMT_MUTATIONS 0 26 #define EVAL_IN_LAMBDA(x) (([&]() HALIDE_NEVER_INLINE { return (x); })()) 35 }
else if ((a > 0) == (b > 0)) {
118 #if (LOG_EXPR_MUTATIONS || LOG_STMT_MUTATIONS) 119 static int debug_indent;
122 #if LOG_EXPR_MUTATIONS 124 const std::string spaces(debug_indent,
' ');
125 debug(1) << spaces <<
"Simplifying Expr: " << e <<
"\n";
131 << spaces <<
"Before: " << e <<
"\n" 132 << spaces <<
"After: " << new_e <<
"\n";
146 #if LOG_STMT_MUTATIONS 148 const std::string spaces(debug_indent,
' ');
149 debug(1) << spaces <<
"Simplifying Stmt: " << s <<
"\n";
155 << spaces <<
"Before: " << s <<
"\n" 156 << spaces <<
"After: " << new_s <<
"\n";
248 return va->
name.compare(vb->name) > 0;
305 template<
typename T,
typename Body>
357 std::pair<std::vector<Expr>,
bool>
mutate_with_changes(
const std::vector<Expr> &old_exprs, ExprInfo *bounds);
IRMatcher::WildConst< 0 > c0
static ModulusRemainder intersect(const ModulusRemainder &a, const ModulusRemainder &b)
Unsigned integer constants.
The actual IR nodes begin here.
Expr max(const FuncRef &a, const FuncRef &b)
Explicit overloads of min and max for FuncRef.
bool const_int(const Expr &e, int64_t *i)
A fragment of Halide syntax.
std::set< Expr, IRDeepCompare > falsehoods
Is the first expression greater than the second.
void learn_true(const Expr &fact)
A reference-counted handle to a statement node.
The result of modulus_remainder analysis.
HALIDE_ALWAYS_INLINE bool no_overflow_int(Type t)
std::vector< Expr > truths
bool const_uint(const Expr &e, uint64_t *u)
Load a value from a named symbol if predicate is true.
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.
std::vector< Expr > falsehoods
Expr min(const FuncRef &a, const FuncRef &b)
Explicit overloads of min and max for FuncRef.
The difference of two expressions.
A vector with 'lanes' elements, in which every element is 'value'.
Defines a method to match a fragment of IR against a pattern containing wildcards.
HALIDE_ALWAYS_INLINE bool should_commute(const Expr &a, const Expr &b)
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.
#define internal_assert(c)
Lock all the Store nodes in the body statement.
Floating point constants.
HALIDE_ALWAYS_INLINE bool is_float() const
Is this type a floating point type (float or double).
The sum of two expressions.
A linear ramp vector node.
Body simplify_let(const T *op, ExprInfo *bounds)
Expr mutate_let_body(const Expr &e, ExprInfo *bounds)
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.
std::pair< std::vector< Expr >, bool > mutate_with_changes(const std::vector< Expr > &old_exprs, ExprInfo *bounds)
HALIDE_ALWAYS_INLINE Expr mutate(const Expr &e, ExprInfo *b)
T mod_imp(T a, T b)
Implementations of division and mod that are specific to Halide.
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.
Is the first expression greater than or equal to the second.
A common pattern when traversing Halide IR is that you need to keep track of stuff when you find a Le...
IRMatcher::WildConst< 2 > c2
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.
Simplify(bool r, const Scope< Interval > *bi, const Scope< ModulusRemainder > *ai)
IRMatcher::WildConst< 5 > c5
HALIDE_MUST_USE_RESULT bool mul_with_overflow(int bits, int64_t a, int64_t b, int64_t *result)
Routines to perform arithmetic on signed types without triggering signed overflow.
Stmt mutate_let_body(const Stmt &s, ExprInfo *)
HALIDE_ALWAYS_INLINE bool no_overflow(Type t)
HALIDE_ALWAYS_INLINE Type type() const
Get the type of this expression node.
Methods for computing the upper and lower bounds of an expression, and the regions of a function read...
For optional debugging during codegen, use the debug class as follows:
Is the first expression less than or equal to the second.
void learn_lower_bound(const Variable *v, int64_t val)
HALIDE_ALWAYS_INLINE int bits() const
Return the bit size of a single element of this type.
Is the first expression not equal to the second.
const T * as() const
Downcast this ir node to its actual type (e.g.
If the 'condition' is false, then evaluate and return the message, which should be a call to an error...
void found_buffer_reference(const std::string &name, size_t dimensions=0)
void intersect(const ExprInfo &other)
Is the first expression equal to the second.
signed __INT64_TYPE__ int64_t
std::vector< const Variable * > bounds_pop_list
Scope< VarInfo > var_info
Represents a location where storage will be hoisted to for a Func / Realize node with a given name...
The greater of two values.
HALIDE_ALWAYS_INLINE bool is_scalar() const
Is this type a scalar type? (lanes() == 1).
A pair of statements executed concurrently.
ModulusRemainder alignment
#define HALIDE_ALWAYS_INLINE
A visitor/mutator capable of passing arbitrary arguments to the visit methods using CRTP and returnin...
Defines the Scope class, which is used for keeping track of names in a scope while traversing IR...
A let expression, like you might find in a functional language.
Stmt mutate(const Stmt &s)
Free the resources associated with the given buffer.
HALIDE_ALWAYS_INLINE void clear_bounds_info(ExprInfo *b)
int64_t saturating_mul(int64_t a, int64_t b)
IRNodeType node_type() const
IRMatcher::WildConst< 4 > c4
HALIDE_ALWAYS_INLINE Stmt dispatch(const Stmt &s, Args &&...args)
std::vector< const Variable * > pop_list
HALIDE_ALWAYS_INLINE bool is_int() const
Is this type a signed integer type?
Types in the halide type system.
Expr visit(const IntImm *op, ExprInfo *bounds)
bool const_float(const Expr &e, double *f)
HALIDE_ALWAYS_INLINE bool same_as(const IntrusivePtr &other) const
HALIDE_MUST_USE_RESULT bool sub_with_overflow(int bits, int64_t a, int64_t b, int64_t *result)
Routines to perform arithmetic on signed types without triggering signed overflow.
IRMatcher::WildConst< 3 > c3
A sequence of statements to be executed in-order.
HALIDE_ALWAYS_INLINE bool no_overflow_scalar_int(Type t)
void learn_upper_bound(const Variable *v, int64_t val)
IRMatcher::WildConst< 1 > c1
The lesser of two values.
ScopedFact scoped_truth(const Expr &fact)
std::set< Expr, IRDeepCompare > truths
void learn_false(const Expr &fact)
void trim_bounds_using_alignment()
Reinterpret value as another type, without affecting any of the bits (on little-endian systems)...
The statement form of a let node.
Expr substitute_facts(const Expr &e)
unsigned __INT64_TYPE__ uint64_t
HALIDE_ALWAYS_INLINE bool may_simplify(const Type &t) const
Logical or - is at least one of the expression true.
This node is a helpful annotation to do with permissions.
Scope< ExprInfo > bounds_and_alignment_info
Evaluate and discard an expression, presumably because it has some side-effect.
ScopedFact scoped_falsehood(const Expr &fact)
Defines the base class for things that recursively walk over the IR.
Construct a new vector by taking elements from another sequence of vectors.