#ifndef HALIDE_SIMPLIFY_H #define HALIDE_SIMPLIFY_H /** \file * Methods for simplifying halide statements and expressions */ #include #include "IR.h" #include "Bounds.h" #include "ModulusRemainder.h" namespace Halide { namespace Internal { /** Perform a a wide range of simplifications to expressions and * statements, including constant folding, substituting in trivial * values, arithmetic rearranging, etc. Simplifies across let * statements, so must not be called on stmts with dangling or * repeated variable names. */ // @{ Stmt simplify(Stmt, bool remove_dead_lets = true, const Scope &bounds = Scope::empty_scope(), const Scope &alignment = Scope::empty_scope()); Expr simplify(Expr, bool remove_dead_lets = true, const Scope &bounds = Scope::empty_scope(), const Scope &alignment = Scope::empty_scope()); // @} /** A common use of the simplifier is to prove boolean expressions are * true at compile time. Equivalent to is_one(simplify(e)) */ bool can_prove(Expr e); /** Simplify expressions found in a statement, but don't simplify * across different statements. This is safe to perform at an earlier * stage in lowering than full simplification of a stmt. */ Stmt simplify_exprs(Stmt); /** Implementations of division and mod that are specific to Halide. * Use these implementations; do not use native C division or mod to * simplify Halide expressions. Halide division and modulo satisify * the Euclidean definition of division for integers a and b: * /code (a/b)*b + a%b = a 0 <= a%b < |b| /endcode * */ // @{ template inline T mod_imp(T a, T b) { Type t = type_of(); if (t.is_int()) { T r = a % b; r = r + (r < 0 ? (T)std::abs((int64_t)b) : 0); return r; } else { return a % b; } } template inline T div_imp(T a, T b) { Type t = type_of(); if (t.is_int()) { int64_t q = a / b; int64_t r = a - q * b; int64_t bs = b >> (t.bits() - 1); int64_t rs = r >> (t.bits() - 1); return (T) (q - (rs & bs) + (rs & ~bs)); } else { return a / b; } } // @} // Special cases for float, double. template<> inline float mod_imp(float a, float b) { float f = a - b * (floorf(a / b)); // The remainder has the same sign as b. return f; } template<> inline double mod_imp(double a, double b) { double f = a - b * (std::floor(a / b)); return f; } template<> inline float div_imp(float a, float b) { return a/b; } template<> inline double div_imp(double a, double b) { return a/b; } } // namespace Internal } // namespace Halide #endif