#ifndef HALIDE_SIMPLIFY_H
#define HALIDE_SIMPLIFY_H
#include <cmath>
#include "IR.h"
#include "Bounds.h"
#include "ModulusRemainder.h"
namespace Halide {
namespace Internal {
EXPORT Stmt simplify(Stmt, bool simplify_lets = true,
const Scope<Interval> &bounds = Scope<Interval>::empty_scope(),
const Scope<ModulusRemainder> &alignment = Scope<ModulusRemainder>::empty_scope());
EXPORT Expr simplify(Expr, bool simplify_lets = true,
const Scope<Interval> &bounds = Scope<Interval>::empty_scope(),
const Scope<ModulusRemainder> &alignment = Scope<ModulusRemainder>::empty_scope());
EXPORT bool can_prove(Expr e);
EXPORT Stmt simplify_exprs(Stmt);
template<typename T>
inline T mod_imp(T a, T b) {
Type t = type_of<T>();
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<typename T>
inline T div_imp(T a, T b) {
Type t = type_of<T>();
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;
}
}
template<> inline float mod_imp<float>(float a, float b) {
float f = a - b * (floorf(a / b));
return f;
}
template<> inline double mod_imp<double>(double a, double b) {
double f = a - b * (std::floor(a / b));
return f;
}
template<> inline float div_imp<float>(float a, float b) {
return a/b;
}
template<> inline double div_imp<double>(double a, double b) {
return a/b;
}
EXPORT void simplify_test();
}
}
#endif