#ifndef HALIDE_IR_H
#define HALIDE_IR_H
#include <string>
#include <vector>
#include "Debug.h"
#include "Error.h"
#include "Expr.h"
#include "Function.h"
#include "IntrusivePtr.h"
#include "Parameter.h"
#include "Type.h"
#include "Util.h"
#include "runtime/HalideBuffer.h"
namespace Halide {
namespace Internal {
struct Cast : public ExprNode<Cast> {
Expr value;
EXPORT static Expr make(Type t, const Expr &v);
static const IRNodeType _type_info = IRNodeType::Cast;
};
struct Add : public ExprNode<Add> {
Expr a, b;
EXPORT static Expr make(const Expr &a, const Expr &b);
static const IRNodeType _type_info = IRNodeType::Add;
};
struct Sub : public ExprNode<Sub> {
Expr a, b;
EXPORT static Expr make(const Expr &a, const Expr &b);
static const IRNodeType _type_info = IRNodeType::Sub;
};
struct Mul : public ExprNode<Mul> {
Expr a, b;
EXPORT static Expr make(const Expr &a, const Expr &b);
static const IRNodeType _type_info = IRNodeType::Mul;
};
struct Div : public ExprNode<Div> {
Expr a, b;
EXPORT static Expr make(const Expr &a, const Expr &b);
static const IRNodeType _type_info = IRNodeType::Div;
};
struct Mod : public ExprNode<Mod> {
Expr a, b;
EXPORT static Expr make(const Expr &a, const Expr &b);
static const IRNodeType _type_info = IRNodeType::Mod;
};
struct Min : public ExprNode<Min> {
Expr a, b;
EXPORT static Expr make(const Expr &a, const Expr &b);
static const IRNodeType _type_info = IRNodeType::Min;
};
struct Max : public ExprNode<Max> {
Expr a, b;
EXPORT static Expr make(const Expr &a, const Expr &b);
static const IRNodeType _type_info = IRNodeType::Max;
};
struct EQ : public ExprNode<EQ> {
Expr a, b;
EXPORT static Expr make(const Expr &a, const Expr &b);
static const IRNodeType _type_info = IRNodeType::EQ;
};
struct NE : public ExprNode<NE> {
Expr a, b;
EXPORT static Expr make(const Expr &a, const Expr &b);
static const IRNodeType _type_info = IRNodeType::NE;
};
struct LT : public ExprNode<LT> {
Expr a, b;
EXPORT static Expr make(const Expr &a, const Expr &b);
static const IRNodeType _type_info = IRNodeType::LT;
};
struct LE : public ExprNode<LE> {
Expr a, b;
EXPORT static Expr make(const Expr &a, const Expr &b);
static const IRNodeType _type_info = IRNodeType::LE;
};
struct GT : public ExprNode<GT> {
Expr a, b;
EXPORT static Expr make(const Expr &a, const Expr &b);
static const IRNodeType _type_info = IRNodeType::GT;
};
struct GE : public ExprNode<GE> {
Expr a, b;
EXPORT static Expr make(const Expr &a, const Expr &b);
static const IRNodeType _type_info = IRNodeType::GE;
};
struct And : public ExprNode<And> {
Expr a, b;
EXPORT static Expr make(const Expr &a, const Expr &b);
static const IRNodeType _type_info = IRNodeType::And;
};
struct Or : public ExprNode<Or> {
Expr a, b;
EXPORT static Expr make(const Expr &a, const Expr &b);
static const IRNodeType _type_info = IRNodeType::Or;
};
struct Not : public ExprNode<Not> {
Expr a;
EXPORT static Expr make(const Expr &a);
static const IRNodeType _type_info = IRNodeType::Not;
};
struct Select : public ExprNode<Select> {
Expr condition, true_value, false_value;
EXPORT static Expr make(const Expr &condition, const Expr &true_value, const Expr &false_value);
static const IRNodeType _type_info = IRNodeType::Select;
};
struct Load : public ExprNode<Load> {
std::string name;
Expr predicate, index;
Buffer<> image;
Parameter param;
EXPORT static Expr make(Type type, const std::string &name,
const Expr &index, Buffer<> image,
Parameter param, const Expr &predicate);
static const IRNodeType _type_info = IRNodeType::Load;
};
struct Ramp : public ExprNode<Ramp> {
Expr base, stride;
int lanes;
EXPORT static Expr make(const Expr &base, const Expr &stride, int lanes);
static const IRNodeType _type_info = IRNodeType::Ramp;
};
struct Broadcast : public ExprNode<Broadcast> {
Expr value;
int lanes;
EXPORT static Expr make(const Expr &value, int lanes);
static const IRNodeType _type_info = IRNodeType::Broadcast;
};
struct Let : public ExprNode<Let> {
std::string name;
Expr value, body;
EXPORT static Expr make(const std::string &name, const Expr &value, const Expr &body);
static const IRNodeType _type_info = IRNodeType::Let;
};
struct LetStmt : public StmtNode<LetStmt> {
std::string name;
Expr value;
Stmt body;
EXPORT static Stmt make(const std::string &name, const Expr &value, const Stmt &body);
static const IRNodeType _type_info = IRNodeType::LetStmt;
};
struct AssertStmt : public StmtNode<AssertStmt> {
Expr condition;
Expr message;
EXPORT static Stmt make(const Expr &condition, const Expr &message);
static const IRNodeType _type_info = IRNodeType::AssertStmt;
};
struct ProducerConsumer : public StmtNode<ProducerConsumer> {
std::string name;
bool is_producer;
Stmt body;
EXPORT static Stmt make(const std::string &name, bool is_producer, const Stmt &body);
EXPORT static Stmt make_produce(const std::string &name, const Stmt &body);
EXPORT static Stmt make_consume(const std::string &name, const Stmt &body);
static const IRNodeType _type_info = IRNodeType::ProducerConsumer;
};
struct Store : public StmtNode<Store> {
std::string name;
Expr predicate, value, index;
Parameter param;
EXPORT static Stmt make(const std::string &name, const Expr &value, const Expr &index,
Parameter param, const Expr &predicate);
static const IRNodeType _type_info = IRNodeType::Store;
};
struct Provide : public StmtNode<Provide> {
std::string name;
std::vector<Expr> values;
std::vector<Expr> args;
EXPORT static Stmt make(const std::string &name, const std::vector<Expr> &values, const std::vector<Expr> &args);
static const IRNodeType _type_info = IRNodeType::Provide;
};
struct Allocate : public StmtNode<Allocate> {
std::string name;
Type type;
std::vector<Expr> extents;
Expr condition;
Expr new_expr;
std::string free_function;
Stmt body;
EXPORT static Stmt make(const std::string &name, Type type, const std::vector<Expr> &extents,
const Expr &condition, const Stmt &body,
const Expr &new_expr = Expr(), const std::string &free_function = std::string());
EXPORT static int32_t constant_allocation_size(const std::vector<Expr> &extents, const std::string &name);
EXPORT int32_t constant_allocation_size() const;
static const IRNodeType _type_info = IRNodeType::Allocate;
};
struct Free : public StmtNode<Free> {
std::string name;
EXPORT static Stmt make(const std::string &name);
static const IRNodeType _type_info = IRNodeType::Free;
};
struct Range {
Expr min, extent;
Range() {}
Range(const Expr &min, const Expr &extent) : min(min), extent(extent) {
internal_assert(min.type() == extent.type()) << "Region min and extent must have same type\n";
}
};
typedef std::vector<Range> Region;
struct Realize : public StmtNode<Realize> {
std::string name;
std::vector<Type> types;
Region bounds;
Expr condition;
Stmt body;
EXPORT static Stmt make(const std::string &name, const std::vector<Type> &types, const Region &bounds, const Expr &condition, const Stmt &body);
static const IRNodeType _type_info = IRNodeType::Realize;
};
struct Block : public StmtNode<Block> {
Stmt first, rest;
EXPORT static Stmt make(const Stmt &first, const Stmt &rest);
EXPORT static Stmt make(const std::vector<Stmt> &stmts);
static const IRNodeType _type_info = IRNodeType::Block;
};
struct IfThenElse : public StmtNode<IfThenElse> {
Expr condition;
Stmt then_case, else_case;
EXPORT static Stmt make(const Expr &condition, const Stmt &then_case, const Stmt &else_case = Stmt());
static const IRNodeType _type_info = IRNodeType::IfThenElse;
};
struct Evaluate : public StmtNode<Evaluate> {
Expr value;
EXPORT static Stmt make(const Expr &v);
static const IRNodeType _type_info = IRNodeType::Evaluate;
};
struct Call : public ExprNode<Call> {
std::string name;
std::vector<Expr> args;
typedef enum {Image,
Extern,
ExternCPlusPlus,
PureExtern,
Halide,
Intrinsic,
PureIntrinsic
} CallType;
CallType call_type;
typedef const char* const ConstString;
EXPORT static ConstString debug_to_file,
reinterpret,
bitwise_and,
bitwise_not,
bitwise_xor,
bitwise_or,
shift_left,
shift_right,
abs,
absd,
rewrite_buffer,
random,
lerp,
popcount,
count_leading_zeros,
count_trailing_zeros,
undef,
return_second,
if_then_else,
glsl_texture_load,
glsl_texture_store,
glsl_varying,
image_load,
image_store,
make_struct,
stringify,
memoize_expr,
alloca,
likely,
likely_if_innermost,
register_destructor,
div_round_to_zero,
mod_round_to_zero,
call_cached_indirect_function,
prefetch,
signed_integer_overflow,
indeterminate_expression,
bool_to_mask,
cast_mask,
select_mask,
extract_mask_element,
size_of_halide_buffer_t;
EXPORT static ConstString
buffer_get_min,
buffer_get_extent,
buffer_get_stride,
buffer_get_max,
buffer_get_host,
buffer_get_device,
buffer_get_device_interface,
buffer_get_shape,
buffer_get_host_dirty,
buffer_get_device_dirty,
buffer_get_type_code,
buffer_get_type_bits,
buffer_get_type_lanes,
buffer_set_host_dirty,
buffer_set_device_dirty,
buffer_is_bounds_query,
buffer_init,
buffer_init_from_buffer,
buffer_crop,
trace;
IntrusivePtr<FunctionContents> func;
int value_index;
Buffer<> image;
Parameter param;
EXPORT static Expr make(Type type, const std::string &name, const std::vector<Expr> &args, CallType call_type,
IntrusivePtr<FunctionContents> func = nullptr, int value_index = 0,
Buffer<> image = Buffer<>(), Parameter param = Parameter());
EXPORT static Expr make(Function func, const std::vector<Expr> &args, int idx = 0);
static Expr make(Buffer<> image, const std::vector<Expr> &args) {
return make(image.type(), image.name(), args, Image, nullptr, 0, image, Parameter());
}
static Expr make(Parameter param, const std::vector<Expr> &args) {
return make(param.type(), param.name(), args, Image, nullptr, 0, Buffer<>(), param);
}
bool is_pure() const {
return (call_type == PureExtern ||
call_type == Image ||
call_type == PureIntrinsic);
}
bool is_intrinsic(ConstString intrin_name) const {
return
((call_type == Intrinsic ||
call_type == PureIntrinsic) &&
name == intrin_name);
}
static const IRNodeType _type_info = IRNodeType::Call;
};
struct Variable : public ExprNode<Variable> {
std::string name;
Parameter param;
Buffer<> image;
ReductionDomain reduction_domain;
static Expr make(Type type, const std::string &name) {
return make(type, name, Buffer<>(), Parameter(), ReductionDomain());
}
static Expr make(Type type, const std::string &name, Parameter param) {
return make(type, name, Buffer<>(), param, ReductionDomain());
}
static Expr make(Type type, const std::string &name, Buffer<> image) {
return make(type, name, image, Parameter(), ReductionDomain());
}
static Expr make(Type type, const std::string &name, ReductionDomain reduction_domain) {
return make(type, name, Buffer<>(), Parameter(), reduction_domain);
}
EXPORT static Expr make(Type type, const std::string &name, Buffer<> image,
Parameter param, ReductionDomain reduction_domain);
static const IRNodeType _type_info = IRNodeType::Variable;
};
struct For : public StmtNode<For> {
std::string name;
Expr min, extent;
ForType for_type;
DeviceAPI device_api;
Stmt body;
EXPORT static Stmt make(const std::string &name, const Expr &min, const Expr &extent, ForType for_type, DeviceAPI device_api, const Stmt &body);
bool is_parallel() const {
return (for_type == ForType::Parallel ||
for_type == ForType::GPUBlock ||
for_type == ForType::GPUThread);
}
static const IRNodeType _type_info = IRNodeType::For;
};
struct Shuffle : public ExprNode<Shuffle> {
std::vector<Expr> vectors;
std::vector<int> indices;
EXPORT static Expr make(const std::vector<Expr> &vectors,
const std::vector<int> &indices);
EXPORT static Expr make_interleave(const std::vector<Expr> &vectors);
EXPORT static Expr make_concat(const std::vector<Expr> &vectors);
EXPORT static Expr make_slice(const Expr &vector, int begin, int stride, int size);
EXPORT static Expr make_extract_element(const Expr &vector, int i);
EXPORT bool is_interleave() const;
EXPORT bool is_concat() const;
EXPORT bool is_slice() const;
int slice_begin() const { return indices[0]; }
int slice_stride() const { return indices.size() >= 2 ? indices[1] - indices[0] : 1; }
EXPORT bool is_extract_element() const;
static const IRNodeType _type_info = IRNodeType::Shuffle;
};
struct Prefetch : public StmtNode<Prefetch> {
std::string name;
std::vector<Type> types;
Region bounds;
Parameter param;
EXPORT static Stmt make(const std::string &name, const std::vector<Type> &types,
const Region &bounds, Parameter param = Parameter());
static const IRNodeType _type_info = IRNodeType::Prefetch;
};
}
}
#endif