#ifndef HALIDE_BOUNDS_H
#define HALIDE_BOUNDS_H
#include "IROperator.h"
#include "Scope.h"
#include "Interval.h"
namespace Halide {
namespace Internal {
typedef std::map<std::pair<std::string, int>, Interval> FuncValueBounds;
Interval bounds_of_expr_in_scope(Expr expr,
const Scope<Interval> &scope,
const FuncValueBounds &func_bounds = FuncValueBounds());
enum class Direction {Upper, Lower};
Expr find_constant_bound(Expr e, Direction d);
struct Box {
Expr used;
std::vector<Interval> bounds;
Box() {}
Box(size_t sz) : bounds(sz) {}
Box(const std::vector<Interval> &b) : bounds(b) {}
size_t size() const {return bounds.size();}
bool empty() const {return bounds.empty();}
Interval &operator[](int i) {return bounds[i];}
const Interval &operator[](int i) const {return bounds[i];}
void resize(size_t sz) {bounds.resize(sz);}
void push_back(const Interval &i) {bounds.push_back(i);}
bool maybe_unused() const {return used.defined() && !is_one(used);}
};
void merge_boxes(Box &a, const Box &b);
bool boxes_overlap(const Box &a, const Box &b);
Box box_union(const Box &a, const Box &b);
Box box_intersection(const Box &a, const Box &b);
bool box_contains(const Box &a, const Box &b);
std::map<std::string, Box> boxes_required(Expr e,
const Scope<Interval> &scope = Scope<Interval>::empty_scope(),
const FuncValueBounds &func_bounds = FuncValueBounds());
std::map<std::string, Box> boxes_required(Stmt s,
const Scope<Interval> &scope = Scope<Interval>::empty_scope(),
const FuncValueBounds &func_bounds = FuncValueBounds());
std::map<std::string, Box> boxes_provided(Expr e,
const Scope<Interval> &scope = Scope<Interval>::empty_scope(),
const FuncValueBounds &func_bounds = FuncValueBounds());
std::map<std::string, Box> boxes_provided(Stmt s,
const Scope<Interval> &scope = Scope<Interval>::empty_scope(),
const FuncValueBounds &func_bounds = FuncValueBounds());
std::map<std::string, Box> boxes_touched(Expr e,
const Scope<Interval> &scope = Scope<Interval>::empty_scope(),
const FuncValueBounds &func_bounds = FuncValueBounds());
std::map<std::string, Box> boxes_touched(Stmt s,
const Scope<Interval> &scope = Scope<Interval>::empty_scope(),
const FuncValueBounds &func_bounds = FuncValueBounds());
Box box_required(Expr e, std::string fn,
const Scope<Interval> &scope = Scope<Interval>::empty_scope(),
const FuncValueBounds &func_bounds = FuncValueBounds());
Box box_required(Stmt s, std::string fn,
const Scope<Interval> &scope = Scope<Interval>::empty_scope(),
const FuncValueBounds &func_bounds = FuncValueBounds());
Box box_provided(Expr e, std::string fn,
const Scope<Interval> &scope = Scope<Interval>::empty_scope(),
const FuncValueBounds &func_bounds = FuncValueBounds());
Box box_provided(Stmt s, std::string fn,
const Scope<Interval> &scope = Scope<Interval>::empty_scope(),
const FuncValueBounds &func_bounds = FuncValueBounds());
Box box_touched(Expr e, std::string fn,
const Scope<Interval> &scope = Scope<Interval>::empty_scope(),
const FuncValueBounds &func_bounds = FuncValueBounds());
Box box_touched(Stmt s, std::string fn,
const Scope<Interval> &scope = Scope<Interval>::empty_scope(),
const FuncValueBounds &func_bounds = FuncValueBounds());
FuncValueBounds compute_function_value_bounds(const std::vector<std::string> &order,
const std::map<std::string, Function> &env);
EXPORT void bounds_test();
}
}
#endif