From 3b704742b2dabf404594648a1072ec8366f46ca6 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Sun, 15 Dec 2013 18:09:36 +0100 Subject: [PATCH] make pet_expr objects reference counted This will make it easier to keep track of nested accesses as pet_expr objects. In order to avoid outside users subverting the reference counting, we hide the internal representation of pet_expr objects. We also include a reference to the isl_ctx in whith the pet_expr is created. Signed-off-by: Sven Verdoolaege --- emit.c | 4 +- expr.c | 802 +++++++++++++++++++++++++++++++++++++++++++++---------- expr.h | 233 ++++++++++------ include/pet.h | 163 ++++++----- nest.c | 8 +- parse.c | 120 +++++---- pet_check_code.c | 130 +++++---- print.c | 25 +- scan.cc | 240 ++++++++--------- scan.h | 41 ++- scop.c | 33 +-- scop.h | 4 +- scop_plus.cc | 18 +- value_bounds.c | 6 +- value_bounds.h | 2 +- 15 files changed, 1251 insertions(+), 578 deletions(-) rewrite expr.h (70%) diff --git a/emit.c b/emit.c index 86add07..37da991 100644 --- a/emit.c +++ b/emit.c @@ -393,7 +393,7 @@ static int emit_expr_type(yaml_emitter_t *emitter, enum pet_expr_type type) return 0; } -static int emit_expr(yaml_emitter_t *emitter, struct pet_expr *expr) +static int emit_expr(yaml_emitter_t *emitter, __isl_keep pet_expr *expr) { yaml_event_t event; @@ -409,6 +409,8 @@ static int emit_expr(yaml_emitter_t *emitter, struct pet_expr *expr) return -1; switch (expr->type) { + case pet_expr_error: + return -1; case pet_expr_int: if (emit_named_val(emitter, "value", expr->i) < 0) return -1; diff --git a/expr.c b/expr.c index be72cd3..296fd4d 100644 --- a/expr.c +++ b/expr.c @@ -124,22 +124,39 @@ enum pet_expr_type pet_str_type(const char *str) return -1; } +/* Construct a pet_expr of the given type. + */ +__isl_give pet_expr *pet_expr_alloc(isl_ctx *ctx, enum pet_expr_type type) +{ + pet_expr *expr; + + expr = isl_calloc_type(ctx, struct pet_expr); + if (!expr) + return NULL; + + expr->ctx = ctx; + isl_ctx_ref(ctx); + expr->type = type; + expr->ref = 1; + + return expr; +} + /* Construct an access pet_expr from an access relation and an index expression. * By default, it is considered to be a read access. */ -struct pet_expr *pet_expr_from_access_and_index( __isl_take isl_map *access, +__isl_give pet_expr *pet_expr_from_access_and_index( __isl_take isl_map *access, __isl_take isl_multi_pw_aff *index) { isl_ctx *ctx = isl_map_get_ctx(access); - struct pet_expr *expr; + pet_expr *expr; if (!index || !access) goto error; - expr = isl_calloc_type(ctx, struct pet_expr); + expr = pet_expr_alloc(ctx, pet_expr_access); if (!expr) goto error; - expr->type = pet_expr_access; expr->acc.access = access; expr->acc.index = index; expr->acc.read = 1; @@ -155,7 +172,7 @@ error: /* Construct an access pet_expr from an index expression. * By default, the access is considered to be a read access. */ -struct pet_expr *pet_expr_from_index(__isl_take isl_multi_pw_aff *index) +__isl_give pet_expr *pet_expr_from_index(__isl_take isl_multi_pw_aff *index) { isl_map *access; @@ -200,7 +217,7 @@ static __isl_give isl_map *extend_range(__isl_take isl_map *access, int n) * then we assume that all elements of the remaining dimensions * are accessed. */ -struct pet_expr *pet_expr_from_index_and_depth( +__isl_give pet_expr *pet_expr_from_index_and_depth( __isl_take isl_multi_pw_aff *index, int depth) { isl_map *access; @@ -228,21 +245,17 @@ error: /* Construct a pet_expr that kills the elements specified by * the index expression "index" and the access relation "access". */ -struct pet_expr *pet_expr_kill_from_access_and_index(__isl_take isl_map *access, - __isl_take isl_multi_pw_aff *index) +__isl_give pet_expr *pet_expr_kill_from_access_and_index( + __isl_take isl_map *access, __isl_take isl_multi_pw_aff *index) { - isl_ctx *ctx; - struct pet_expr *expr; + pet_expr *expr; if (!access || !index) goto error; - ctx = isl_multi_pw_aff_get_ctx(index); expr = pet_expr_from_access_and_index(access, index); - if (!expr) - return NULL; - expr->acc.read = 0; - return pet_expr_new_unary(ctx, pet_op_kill, expr); + expr = pet_expr_access_set_read(expr, 0); + return pet_expr_new_unary(pet_op_kill, expr); error: isl_map_free(access); isl_multi_pw_aff_free(index); @@ -251,23 +264,21 @@ error: /* Construct a unary pet_expr that performs "op" on "arg". */ -struct pet_expr *pet_expr_new_unary(isl_ctx *ctx, enum pet_op_type op, - struct pet_expr *arg) +__isl_give pet_expr *pet_expr_new_unary(enum pet_op_type op, + __isl_take pet_expr *arg) { - struct pet_expr *expr; + isl_ctx *ctx; + pet_expr *expr; if (!arg) - goto error; - expr = isl_alloc_type(ctx, struct pet_expr); + return NULL; + ctx = pet_expr_get_ctx(arg); + expr = pet_expr_alloc(ctx, pet_expr_op); + expr = pet_expr_set_n_arg(expr, 1); if (!expr) goto error; - expr->type = pet_expr_op; expr->op = op; - expr->n_arg = 1; - expr->args = isl_calloc_array(ctx, struct pet_expr *, 1); - if (!expr->args) - goto error; expr->args[pet_un_arg] = arg; return expr; @@ -278,23 +289,21 @@ error: /* Construct a binary pet_expr that performs "op" on "lhs" and "rhs". */ -struct pet_expr *pet_expr_new_binary(isl_ctx *ctx, enum pet_op_type op, - struct pet_expr *lhs, struct pet_expr *rhs) +__isl_give pet_expr *pet_expr_new_binary(enum pet_op_type op, + __isl_take pet_expr *lhs, __isl_take pet_expr *rhs) { - struct pet_expr *expr; + isl_ctx *ctx; + pet_expr *expr; if (!lhs || !rhs) goto error; - expr = isl_alloc_type(ctx, struct pet_expr); + ctx = pet_expr_get_ctx(lhs); + expr = pet_expr_alloc(ctx, pet_expr_op); + expr = pet_expr_set_n_arg(expr, 2); if (!expr) goto error; - expr->type = pet_expr_op; expr->op = op; - expr->n_arg = 2; - expr->args = isl_calloc_array(ctx, struct pet_expr *, 2); - if (!expr->args) - goto error; expr->args[pet_bin_lhs] = lhs; expr->args[pet_bin_rhs] = rhs; @@ -307,23 +316,21 @@ error: /* Construct a ternary pet_expr that performs "cond" ? "lhs" : "rhs". */ -struct pet_expr *pet_expr_new_ternary(isl_ctx *ctx, struct pet_expr *cond, - struct pet_expr *lhs, struct pet_expr *rhs) +__isl_give pet_expr *pet_expr_new_ternary(__isl_take pet_expr *cond, + __isl_take pet_expr *lhs, __isl_take pet_expr *rhs) { - struct pet_expr *expr; + isl_ctx *ctx; + pet_expr *expr; if (!cond || !lhs || !rhs) goto error; - expr = isl_alloc_type(ctx, struct pet_expr); + ctx = pet_expr_get_ctx(cond); + expr = pet_expr_alloc(ctx, pet_expr_op); + expr = pet_expr_set_n_arg(expr, 3); if (!expr) goto error; - expr->type = pet_expr_op; expr->op = pet_op_cond; - expr->n_arg = 3; - expr->args = isl_calloc_array(ctx, struct pet_expr *, 3); - if (!expr->args) - goto error; expr->args[pet_ter_cond] = cond; expr->args[pet_ter_true] = lhs; expr->args[pet_ter_false] = rhs; @@ -339,20 +346,18 @@ error: /* Construct a call pet_expr that calls function "name" with "n_arg" * arguments. The caller is responsible for filling in the arguments. */ -struct pet_expr *pet_expr_new_call(isl_ctx *ctx, const char *name, +__isl_give pet_expr *pet_expr_new_call(isl_ctx *ctx, const char *name, unsigned n_arg) { - struct pet_expr *expr; + pet_expr *expr; - expr = isl_alloc_type(ctx, struct pet_expr); + expr = pet_expr_alloc(ctx, pet_expr_call); + expr = pet_expr_set_n_arg(expr, n_arg); if (!expr) return NULL; - expr->type = pet_expr_call; - expr->n_arg = n_arg; expr->name = strdup(name); - expr->args = isl_calloc_array(ctx, struct pet_expr *, n_arg); - if (!expr->name || !expr->args) + if (!expr->name) return pet_expr_free(expr); return expr; @@ -360,23 +365,23 @@ struct pet_expr *pet_expr_new_call(isl_ctx *ctx, const char *name, /* Construct a pet_expr that represents the cast of "arg" to "type_name". */ -struct pet_expr *pet_expr_new_cast(isl_ctx *ctx, const char *type_name, - struct pet_expr *arg) +__isl_give pet_expr *pet_expr_new_cast(const char *type_name, + __isl_take pet_expr *arg) { - struct pet_expr *expr; + isl_ctx *ctx; + pet_expr *expr; if (!arg) return NULL; - expr = isl_alloc_type(ctx, struct pet_expr); + ctx = pet_expr_get_ctx(arg); + expr = pet_expr_alloc(ctx, pet_expr_cast); + expr = pet_expr_set_n_arg(expr, 1); if (!expr) goto error; - expr->type = pet_expr_cast; - expr->n_arg = 1; expr->type_name = strdup(type_name); - expr->args = isl_calloc_array(ctx, struct pet_expr *, 1); - if (!expr->type_name || !expr->args) + if (!expr->type_name) goto error; expr->args[0] = arg; @@ -390,15 +395,15 @@ error: /* Construct a pet_expr that represents the double "d". */ -struct pet_expr *pet_expr_new_double(isl_ctx *ctx, double val, const char *s) +__isl_give pet_expr *pet_expr_new_double(isl_ctx *ctx, + double val, const char *s) { - struct pet_expr *expr; + pet_expr *expr; - expr = isl_calloc_type(ctx, struct pet_expr); + expr = pet_expr_alloc(ctx, pet_expr_double); if (!expr) return NULL; - expr->type = pet_expr_double; expr->d.val = val; expr->d.s = strdup(s); if (!expr->d.s) @@ -409,20 +414,19 @@ struct pet_expr *pet_expr_new_double(isl_ctx *ctx, double val, const char *s) /* Construct a pet_expr that represents the integer value "v". */ -struct pet_expr *pet_expr_new_int(__isl_take isl_val *v) +__isl_give pet_expr *pet_expr_new_int(__isl_take isl_val *v) { isl_ctx *ctx; - struct pet_expr *expr; + pet_expr *expr; if (!v) return NULL; ctx = isl_val_get_ctx(v); - expr = isl_calloc_type(ctx, struct pet_expr); + expr = pet_expr_alloc(ctx, pet_expr_int); if (!expr) goto error; - expr->type = pet_expr_int; expr->i = v; return expr; @@ -431,12 +435,73 @@ error: return NULL; } -struct pet_expr *pet_expr_free(struct pet_expr *expr) +static __isl_give pet_expr *pet_expr_dup(__isl_keep pet_expr *expr) +{ + int i; + pet_expr *dup; + + if (!expr) + return NULL; + + dup = pet_expr_alloc(expr->ctx, expr->type); + dup = pet_expr_set_n_arg(dup, expr->n_arg); + for (i = 0; i < expr->n_arg; ++i) + dup = pet_expr_set_arg(dup, i, pet_expr_copy(expr->args[i])); + + switch (expr->type) { + case pet_expr_access: + if (expr->acc.ref_id) + dup = pet_expr_access_set_ref_id(dup, + isl_id_copy(expr->acc.ref_id)); + dup = pet_expr_access_set_access(dup, + isl_map_copy(expr->acc.access)); + dup = pet_expr_access_set_index(dup, + isl_multi_pw_aff_copy(expr->acc.index)); + dup = pet_expr_access_set_read(dup, expr->acc.read); + dup = pet_expr_access_set_write(dup, expr->acc.write); + break; + case pet_expr_call: + dup = pet_expr_call_set_name(dup, expr->name); + break; + case pet_expr_cast: + dup = pet_expr_cast_set_type_name(dup, expr->type_name); + break; + case pet_expr_double: + dup = pet_expr_double_set(dup, expr->d.val, expr->d.s); + break; + case pet_expr_int: + dup = pet_expr_int_set_val(dup, isl_val_copy(expr->i)); + break; + case pet_expr_op: + dup = pet_expr_op_set_type(dup, expr->op); + break; + case pet_expr_error: + dup = pet_expr_free(dup); + break; + } + + return dup; +} + +__isl_give pet_expr *pet_expr_cow(__isl_take pet_expr *expr) +{ + if (!expr) + return NULL; + + if (expr->ref == 1) + return expr; + expr->ref--; + return pet_expr_dup(expr); +} + +__isl_null pet_expr *pet_expr_free(__isl_take pet_expr *expr) { int i; if (!expr) return NULL; + if (--expr->ref > 0) + return NULL; for (i = 0; i < expr->n_arg; ++i) pet_expr_free(expr->args[i]); @@ -461,17 +526,135 @@ struct pet_expr *pet_expr_free(struct pet_expr *expr) isl_val_free(expr->i); break; case pet_expr_op: + case pet_expr_error: break; } + isl_ctx_deref(expr->ctx); free(expr); return NULL; } +/* Return an additional reference to "expr". + */ +__isl_give pet_expr *pet_expr_copy(__isl_keep pet_expr *expr) +{ + if (!expr) + return NULL; + + expr->ref++; + return expr; +} + +/* Return the isl_ctx in which "expr" was created. + */ +isl_ctx *pet_expr_get_ctx(__isl_keep pet_expr *expr) +{ + return expr ? expr->ctx : NULL; +} + +/* Return the type of "expr". + */ +enum pet_expr_type pet_expr_get_type(__isl_keep pet_expr *expr) +{ + if (!expr) + return pet_expr_error; + return expr->type; +} + +/* Return the number of arguments of "expr". + */ +int pet_expr_get_n_arg(__isl_keep pet_expr *expr) +{ + if (!expr) + return -1; + + return expr->n_arg; +} + +/* Set the number of arguments of "expr" to "n". + * + * If "expr" originally had more arguments, then remove the extra arguments. + * If "expr" originally had fewer arguments, then create space for + * the extra arguments ans initialize them to NULL. + */ +__isl_give pet_expr *pet_expr_set_n_arg(__isl_take pet_expr *expr, int n) +{ + int i; + pet_expr **args; + + if (!expr) + return NULL; + if (expr->n_arg == n) + return expr; + expr = pet_expr_cow(expr); + if (!expr) + return NULL; + + if (n < expr->n_arg) { + for (i = n; i < expr->n_arg; ++i) + pet_expr_free(expr->args[i]); + expr->n_arg = n; + return expr; + } + + args = isl_realloc_array(expr->ctx, expr->args, pet_expr *, n); + if (!args) + return pet_expr_free(expr); + expr->args = args; + for (i = expr->n_arg; i < n; ++i) + expr->args[i] = NULL; + expr->n_arg = n; + + return expr; +} + +/* Return the argument of "expr" at position "pos". + */ +__isl_give pet_expr *pet_expr_get_arg(__isl_keep pet_expr *expr, int pos) +{ + if (!expr) + return NULL; + if (pos < 0 || pos >= expr->n_arg) + isl_die(pet_expr_get_ctx(expr), isl_error_invalid, + "position out of bounds", return NULL); + + return pet_expr_copy(expr->args[pos]); +} + +/* Replace the argument of "expr" at position "pos" by "arg". + */ +__isl_give pet_expr *pet_expr_set_arg(__isl_take pet_expr *expr, int pos, + __isl_take pet_expr *arg) +{ + if (!expr || !arg) + goto error; + if (pos < 0 || pos >= expr->n_arg) + isl_die(pet_expr_get_ctx(expr), isl_error_invalid, + "position out of bounds", goto error); + if (expr->args[pos] == arg) { + pet_expr_free(arg); + return expr; + } + + expr = pet_expr_cow(expr); + if (!expr) + goto error; + + pet_expr_free(expr->args[pos]); + expr->args[pos] = arg; + + return expr; +error: + pet_expr_free(expr); + pet_expr_free(arg); + return NULL; +} + /* Does "expr" represent an access to an unnamed space, i.e., * does it represent an affine expression? */ -int pet_expr_is_affine(struct pet_expr *expr) +int pet_expr_is_affine(__isl_keep pet_expr *expr) { int has_id; @@ -489,7 +672,7 @@ int pet_expr_is_affine(struct pet_expr *expr) /* Does "expr" represent an access to a scalar, i.e., zero-dimensional array? */ -int pet_expr_is_scalar_access(struct pet_expr *expr) +int pet_expr_is_scalar_access(__isl_keep pet_expr *expr) { if (!expr) return -1; @@ -501,7 +684,7 @@ int pet_expr_is_scalar_access(struct pet_expr *expr) /* Return 1 if the two pet_exprs are equivalent. */ -int pet_expr_is_equal(struct pet_expr *expr1, struct pet_expr *expr2) +int pet_expr_is_equal(__isl_keep pet_expr *expr1, __isl_keep pet_expr *expr2) { int i; @@ -516,6 +699,8 @@ int pet_expr_is_equal(struct pet_expr *expr1, struct pet_expr *expr2) if (!pet_expr_is_equal(expr1->args[i], expr2->args[i])) return 0; switch (expr1->type) { + case pet_expr_error: + return -1; case pet_expr_double: if (strcmp(expr1->d.s, expr2->d.s)) return 0; @@ -562,24 +747,26 @@ int pet_expr_is_equal(struct pet_expr *expr1, struct pet_expr *expr2) /* Does the access expression "expr" read the accessed elements? */ -int pet_expr_access_is_read(struct pet_expr *expr) +int pet_expr_access_is_read(__isl_keep pet_expr *expr) { if (!expr) return -1; if (expr->type != pet_expr_access) - return -1; + isl_die(pet_expr_get_ctx(expr), isl_error_invalid, + "not an access expression", return -1); return expr->acc.read; } /* Does the access expression "expr" write to the accessed elements? */ -int pet_expr_access_is_write(struct pet_expr *expr) +int pet_expr_access_is_write(__isl_keep pet_expr *expr) { if (!expr) return -1; if (expr->type != pet_expr_access) - return -1; + isl_die(pet_expr_get_ctx(expr), isl_error_invalid, + "not an access expression", return -1); return expr->acc.write; } @@ -589,12 +776,13 @@ int pet_expr_access_is_write(struct pet_expr *expr) * If "expr" represents a member access, then return the identifier * of the outer structure array. */ -__isl_give isl_id *pet_expr_access_get_id(struct pet_expr *expr) +__isl_give isl_id *pet_expr_access_get_id(__isl_keep pet_expr *expr) { if (!expr) return NULL; if (expr->type != pet_expr_access) - return NULL; + isl_die(pet_expr_get_ctx(expr), isl_error_invalid, + "not an access expression", return NULL); if (isl_map_range_is_wrapping(expr->acc.access)) { isl_space *space; @@ -615,14 +803,16 @@ __isl_give isl_id *pet_expr_access_get_id(struct pet_expr *expr) /* Return the parameter space of "expr". */ -__isl_give isl_space *pet_expr_access_get_parameter_space(struct pet_expr *expr) +__isl_give isl_space *pet_expr_access_get_parameter_space( + __isl_keep pet_expr *expr) { isl_space *space; if (!expr) return NULL; if (expr->type != pet_expr_access) - return NULL; + isl_die(pet_expr_get_ctx(expr), isl_error_invalid, + "not an access expression", return NULL); space = isl_multi_pw_aff_get_space(expr->acc.index); space = isl_space_params(space); @@ -632,14 +822,15 @@ __isl_give isl_space *pet_expr_access_get_parameter_space(struct pet_expr *expr) /* Return the space of the data accessed by "expr". */ -__isl_give isl_space *pet_expr_access_get_data_space(struct pet_expr *expr) +__isl_give isl_space *pet_expr_access_get_data_space(__isl_keep pet_expr *expr) { isl_space *space; if (!expr) return NULL; if (expr->type != pet_expr_access) - return NULL; + isl_die(pet_expr_get_ctx(expr), isl_error_invalid, + "not an access expression", return NULL); space = isl_multi_pw_aff_get_space(expr->acc.index); space = isl_space_range(space); @@ -650,21 +841,22 @@ __isl_give isl_space *pet_expr_access_get_data_space(struct pet_expr *expr) /* Modify all expressions of type pet_expr_access in "expr" * by calling "fn" on them. */ -struct pet_expr *pet_expr_map_access(struct pet_expr *expr, - struct pet_expr *(*fn)(struct pet_expr *expr, void *user), +__isl_give pet_expr *pet_expr_map_access(__isl_take pet_expr *expr, + __isl_give pet_expr *(*fn)(__isl_take pet_expr *expr, void *user), void *user) { - int i; + int i, n; + + n = pet_expr_get_n_arg(expr); + for (i = 0; i < n; ++i) { + pet_expr *arg = pet_expr_get_arg(expr, i); + arg = pet_expr_map_access(arg, fn, user); + expr = pet_expr_set_arg(expr, i, arg); + } if (!expr) return NULL; - for (i = 0; i < expr->n_arg; ++i) { - expr->args[i] = pet_expr_map_access(expr->args[i], fn, user); - if (!expr->args[i]) - return pet_expr_free(expr); - } - if (expr->type == pet_expr_access) expr = fn(expr, user); @@ -677,9 +869,9 @@ struct pet_expr *pet_expr_map_access(struct pet_expr *expr, * an error). * Otherwise return 0. */ -int pet_expr_foreach_expr_of_type(struct pet_expr *expr, - enum pet_expr_type type, int (*fn)(struct pet_expr *expr, void *user), - void *user) +int pet_expr_foreach_expr_of_type(__isl_keep pet_expr *expr, + enum pet_expr_type type, + int (*fn)(__isl_keep pet_expr *expr, void *user), void *user) { int i; @@ -703,8 +895,8 @@ int pet_expr_foreach_expr_of_type(struct pet_expr *expr, * an error). * Otherwise return 0. */ -int pet_expr_foreach_access_expr(struct pet_expr *expr, - int (*fn)(struct pet_expr *expr, void *user), void *user) +int pet_expr_foreach_access_expr(__isl_keep pet_expr *expr, + int (*fn)(__isl_keep pet_expr *expr, void *user), void *user) { return pet_expr_foreach_expr_of_type(expr, pet_expr_access, fn, user); } @@ -715,8 +907,8 @@ int pet_expr_foreach_access_expr(struct pet_expr *expr, * an error). * Otherwise return 0. */ -int pet_expr_foreach_call_expr(struct pet_expr *expr, - int (*fn)(struct pet_expr *expr, void *user), void *user) +int pet_expr_foreach_call_expr(__isl_keep pet_expr *expr, + int (*fn)(__isl_keep pet_expr *expr, void *user), void *user) { return pet_expr_foreach_expr_of_type(expr, pet_expr_call, fn, user); } @@ -733,7 +925,7 @@ struct pet_expr_writes_data { /* Given an access expression, check if it writes to data->id. * If so, set data->found and abort the search. */ -static int writes(struct pet_expr *expr, void *user) +static int writes(__isl_keep pet_expr *expr, void *user) { struct pet_expr_writes_data *data = user; isl_id *write_id; @@ -758,7 +950,7 @@ static int writes(struct pet_expr *expr, void *user) /* Does expression "expr" write to "id"? */ -int pet_expr_writes(struct pet_expr *expr, __isl_keep isl_id *id) +int pet_expr_writes(__isl_keep pet_expr *expr, __isl_keep isl_id *id) { struct pet_expr_writes_data data; @@ -775,14 +967,16 @@ int pet_expr_writes(struct pet_expr *expr, __isl_keep isl_id *id) * index expression and access relation of "expr" * to dimensions of "dst_type" at "dst_pos". */ -struct pet_expr *pet_expr_access_move_dims(struct pet_expr *expr, +__isl_give pet_expr *pet_expr_access_move_dims(__isl_take pet_expr *expr, enum isl_dim_type dst_type, unsigned dst_pos, enum isl_dim_type src_type, unsigned src_pos, unsigned n) { + expr = pet_expr_cow(expr); if (!expr) return NULL; if (expr->type != pet_expr_access) - return pet_expr_free(expr); + isl_die(pet_expr_get_ctx(expr), isl_error_invalid, + "not an access pet_expr", return pet_expr_free(expr)); expr->acc.access = isl_map_move_dims(expr->acc.access, dst_type, dst_pos, src_type, src_pos, n); @@ -797,13 +991,15 @@ struct pet_expr *pet_expr_access_move_dims(struct pet_expr *expr, /* Replace the index expression and access relation of "expr" * by their preimages under the function represented by "ma". */ -struct pet_expr *pet_expr_access_pullback_multi_aff( - struct pet_expr *expr, __isl_take isl_multi_aff *ma) +__isl_give pet_expr *pet_expr_access_pullback_multi_aff( + __isl_take pet_expr *expr, __isl_take isl_multi_aff *ma) { + expr = pet_expr_cow(expr); if (!expr || !ma) goto error; if (expr->type != pet_expr_access) - goto error; + isl_die(pet_expr_get_ctx(expr), isl_error_invalid, + "not an access pet_expr", goto error); expr->acc.access = isl_map_preimage_domain_multi_aff(expr->acc.access, isl_multi_aff_copy(ma)); @@ -819,14 +1015,43 @@ error: return NULL; } +/* Return the access relation of access expression "expr". + */ +__isl_give isl_map *pet_expr_access_get_access(__isl_keep pet_expr *expr) +{ + if (!expr) + return NULL; + if (expr->type != pet_expr_access) + isl_die(pet_expr_get_ctx(expr), isl_error_invalid, + "not an access expression", return NULL); + + return isl_map_copy(expr->acc.access); +} + +/* Return the index expression of access expression "expr". + */ +__isl_give isl_multi_pw_aff *pet_expr_access_get_index( + __isl_keep pet_expr *expr) +{ + if (!expr) + return NULL; + if (expr->type != pet_expr_access) + isl_die(pet_expr_get_ctx(expr), isl_error_invalid, + "not an access expression", return NULL); + + return isl_multi_pw_aff_copy(expr->acc.index); +} + /* Align the parameters of expr->acc.index and expr->acc.access. */ -struct pet_expr *pet_expr_access_align_params(struct pet_expr *expr) +__isl_give pet_expr *pet_expr_access_align_params(__isl_take pet_expr *expr) { + expr = pet_expr_cow(expr); if (!expr) return NULL; if (expr->type != pet_expr_access) - return pet_expr_free(expr); + isl_die(pet_expr_get_ctx(expr), isl_error_invalid, + "not an access expression", return pet_expr_free(expr)); expr->acc.access = isl_map_align_params(expr->acc.access, isl_multi_pw_aff_get_space(expr->acc.index)); @@ -843,11 +1068,12 @@ struct pet_expr *pet_expr_access_align_params(struct pet_expr *expr) * The conditions are not added to the index expression. Instead, they * are used to try and simplify the index expression. */ -struct pet_expr *pet_expr_restrict(struct pet_expr *expr, +__isl_give pet_expr *pet_expr_restrict(__isl_take pet_expr *expr, __isl_take isl_set *cond) { int i; + expr = pet_expr_cow(expr); if (!expr) goto error; @@ -886,11 +1112,18 @@ error: * mapping, so we extend the input transformation with an identity mapping * on the space of argument values. */ -struct pet_expr *pet_expr_access_update_domain(struct pet_expr *expr, +__isl_give pet_expr *pet_expr_access_update_domain(__isl_take pet_expr *expr, __isl_keep isl_multi_pw_aff *update) { isl_space *space; + expr = pet_expr_cow(expr); + if (!expr) + return NULL; + if (expr->type != pet_expr_access) + isl_die(pet_expr_get_ctx(expr), isl_error_invalid, + "not an access expression", return pet_expr_free(expr)); + update = isl_multi_pw_aff_copy(update); space = isl_map_get_space(expr->acc.access); @@ -917,7 +1150,7 @@ struct pet_expr *pet_expr_access_update_domain(struct pet_expr *expr, return expr; } -static struct pet_expr *update_domain(struct pet_expr *expr, void *user) +static __isl_give pet_expr *update_domain(__isl_take pet_expr *expr, void *user) { isl_multi_pw_aff *update = user; @@ -927,7 +1160,7 @@ static struct pet_expr *update_domain(struct pet_expr *expr, void *user) /* Modify all access relations in "expr" by precomposing them with * the given iteration space transformation. */ -struct pet_expr *pet_expr_update_domain(struct pet_expr *expr, +__isl_give pet_expr *pet_expr_update_domain(__isl_take pet_expr *expr, __isl_take isl_multi_pw_aff *update) { expr = pet_expr_map_access(expr, &update_domain, update); @@ -938,10 +1171,17 @@ struct pet_expr *pet_expr_update_domain(struct pet_expr *expr, /* Add all parameters in "space" to the access relation and index expression * of "expr". */ -static struct pet_expr *align_params(struct pet_expr *expr, void *user) +static __isl_give pet_expr *align_params(__isl_take pet_expr *expr, void *user) { isl_space *space = user; + expr = pet_expr_cow(expr); + if (!expr) + return NULL; + if (expr->type != pet_expr_access) + isl_die(pet_expr_get_ctx(expr), isl_error_invalid, + "not an access expression", return pet_expr_free(expr)); + expr->acc.access = isl_map_align_params(expr->acc.access, isl_space_copy(space)); expr->acc.index = isl_multi_pw_aff_align_params(expr->acc.index, @@ -955,7 +1195,7 @@ static struct pet_expr *align_params(struct pet_expr *expr, void *user) /* Add all parameters in "space" to all access relations and index expressions * in "expr". */ -struct pet_expr *pet_expr_align_params(struct pet_expr *expr, +__isl_give pet_expr *pet_expr_align_params(__isl_take pet_expr *expr, __isl_take isl_space *space) { expr = pet_expr_map_access(expr, &align_params, space); @@ -966,7 +1206,7 @@ struct pet_expr *pet_expr_align_params(struct pet_expr *expr, /* Insert an argument expression corresponding to "test" in front * of the list of arguments described by *n_arg and *args. */ -static struct pet_expr *insert_access_arg(struct pet_expr *expr, +static __isl_give pet_expr *insert_access_arg(__isl_take pet_expr *expr, __isl_keep isl_multi_pw_aff *test) { int i; @@ -974,14 +1214,17 @@ static struct pet_expr *insert_access_arg(struct pet_expr *expr, if (!test) return pet_expr_free(expr); + expr = pet_expr_cow(expr); + if (!expr) + return NULL; if (!expr->args) { - expr->args = isl_calloc_array(ctx, struct pet_expr *, 1); + expr->args = isl_calloc_array(ctx, pet_expr *, 1); if (!expr->args) return pet_expr_free(expr); } else { - struct pet_expr **ext; - ext = isl_calloc_array(ctx, struct pet_expr *, 1 + expr->n_arg); + pet_expr **ext; + ext = isl_calloc_array(ctx, pet_expr *, 1 + expr->n_arg); if (!ext) return pet_expr_free(expr); for (i = 0; i < expr->n_arg; ++i) @@ -1007,7 +1250,7 @@ static struct pet_expr *insert_access_arg(struct pet_expr *expr, * Otherwise, we add a filter to "expr" (which is then assumed to be * an access expression) corresponding to "test" being equal to "satisfied". */ -struct pet_expr *pet_expr_filter(struct pet_expr *expr, +__isl_give pet_expr *pet_expr_filter(__isl_take pet_expr *expr, __isl_take isl_multi_pw_aff *test, int satisfied) { isl_id *id; @@ -1015,6 +1258,7 @@ struct pet_expr *pet_expr_filter(struct pet_expr *expr, isl_space *space; isl_pw_multi_aff *pma; + expr = pet_expr_cow(expr); if (!expr || !test) goto error; @@ -1138,11 +1382,18 @@ static __isl_give isl_map *access_detect_parameter(__isl_take isl_map *access, /* If "expr" accesses a (0D) array that corresponds to one of the parameters * in "space" then replace it by a value equal to the corresponding parameter. */ -static struct pet_expr *detect_parameter_accesses(struct pet_expr *expr, +static __isl_give pet_expr *detect_parameter_accesses(__isl_take pet_expr *expr, void *user) { isl_space *space = user; + expr = pet_expr_cow(expr); + if (!expr) + return NULL; + if (expr->type != pet_expr_access) + isl_die(pet_expr_get_ctx(expr), isl_error_invalid, + "not an access expression", return pet_expr_free(expr)); + expr->acc.access = access_detect_parameter(expr->acc.access, isl_space_copy(space)); expr->acc.index = index_detect_parameter(expr->acc.index, @@ -1156,8 +1407,8 @@ static struct pet_expr *detect_parameter_accesses(struct pet_expr *expr, /* Replace all accesses to (0D) arrays that correspond to one of the parameters * in "space" by a value equal to the corresponding parameter. */ -struct pet_expr *pet_expr_detect_parameter_accesses(struct pet_expr *expr, - __isl_take isl_space *space) +__isl_give pet_expr *pet_expr_detect_parameter_accesses( + __isl_take pet_expr *expr, __isl_take isl_space *space) { expr = pet_expr_map_access(expr, &detect_parameter_accesses, space); isl_space_free(space); @@ -1168,14 +1419,19 @@ struct pet_expr *pet_expr_detect_parameter_accesses(struct pet_expr *expr, * "user" points to an integer that contains the sequence number * of the next reference. */ -static struct pet_expr *access_add_ref_id(struct pet_expr *expr, void *user) +static __isl_give pet_expr *access_add_ref_id(__isl_take pet_expr *expr, + void *user) { isl_ctx *ctx; char name[50]; int *n_ref = user; + expr = pet_expr_cow(expr); if (!expr) return expr; + if (expr->type != pet_expr_access) + isl_die(pet_expr_get_ctx(expr), isl_error_invalid, + "not an access expression", return pet_expr_free(expr)); ctx = isl_map_get_ctx(expr->acc.access); snprintf(name, sizeof(name), "__pet_ref_%d", (*n_ref)++); @@ -1186,7 +1442,7 @@ static struct pet_expr *access_add_ref_id(struct pet_expr *expr, void *user) return expr; } -struct pet_expr *pet_expr_add_ref_ids(struct pet_expr *expr, int *n_ref) +__isl_give pet_expr *pet_expr_add_ref_ids(__isl_take pet_expr *expr, int *n_ref) { return pet_expr_map_access(expr, &access_add_ref_id, n_ref); } @@ -1195,8 +1451,16 @@ struct pet_expr *pet_expr_add_ref_ids(struct pet_expr *expr, int *n_ref) * the access relation and the index expressions * of the access expression "expr". */ -static struct pet_expr *access_anonymize(struct pet_expr *expr, void *user) +static __isl_give pet_expr *access_anonymize(__isl_take pet_expr *expr, + void *user) { + expr = pet_expr_cow(expr); + if (!expr) + return expr; + if (expr->type != pet_expr_access) + isl_die(pet_expr_get_ctx(expr), isl_error_invalid, + "not an access expression", return pet_expr_free(expr)); + expr->acc.access = isl_map_reset_user(expr->acc.access); expr->acc.index = isl_multi_pw_aff_reset_user(expr->acc.index); if (!expr->acc.access || !expr->acc.index) @@ -1205,7 +1469,7 @@ static struct pet_expr *access_anonymize(struct pet_expr *expr, void *user) return expr; } -struct pet_expr *pet_expr_anonymize(struct pet_expr *expr) +__isl_give pet_expr *pet_expr_anonymize(__isl_take pet_expr *expr) { return pet_expr_map_access(expr, &access_anonymize, NULL); } @@ -1222,11 +1486,18 @@ struct pet_access_gist_data { * with respect to data->domain and the bounds on the values of the arguments * of the expression. */ -static struct pet_expr *access_gist(struct pet_expr *expr, void *user) +static __isl_give pet_expr *access_gist(__isl_take pet_expr *expr, void *user) { struct pet_access_gist_data *data = user; isl_set *domain; + expr = pet_expr_cow(expr); + if (!expr) + return expr; + if (expr->type != pet_expr_access) + isl_die(pet_expr_get_ctx(expr), isl_error_invalid, + "not an access expression", return pet_expr_free(expr)); + domain = isl_set_copy(data->domain); if (expr->n_arg > 0) domain = pet_value_bounds_apply(domain, expr->n_arg, expr->args, @@ -1241,7 +1512,7 @@ static struct pet_expr *access_gist(struct pet_expr *expr, void *user) return expr; } -struct pet_expr *pet_expr_gist(struct pet_expr *expr, +__isl_give pet_expr *pet_expr_gist(__isl_take pet_expr *expr, __isl_keep isl_set *context, __isl_keep isl_union_map *value_bounds) { struct pet_access_gist_data data = { context, value_bounds }; @@ -1249,18 +1520,122 @@ struct pet_expr *pet_expr_gist(struct pet_expr *expr, return pet_expr_map_access(expr, &access_gist, &data); } -/* Return the reference identifier of access expression "expr". +/* Mark "expr" as a read dependening on "read". + */ +__isl_give pet_expr *pet_expr_access_set_read(__isl_take pet_expr *expr, + int read) +{ + if (!expr) + return pet_expr_free(expr); + if (expr->type != pet_expr_access) + isl_die(pet_expr_get_ctx(expr), isl_error_invalid, + "not an access expression", return pet_expr_free(expr)); + if (expr->acc.read == read) + return expr; + expr = pet_expr_cow(expr); + if (!expr) + return NULL; + expr->acc.read = read; + + return expr; +} + +/* Mark "expr" as a write dependening on "write". */ -__isl_give isl_id *pet_expr_access_get_ref_id(struct pet_expr *expr) +__isl_give pet_expr *pet_expr_access_set_write(__isl_take pet_expr *expr, + int write) { if (!expr) + return pet_expr_free(expr); + if (expr->type != pet_expr_access) + isl_die(pet_expr_get_ctx(expr), isl_error_invalid, + "not an access expression", return pet_expr_free(expr)); + if (expr->acc.write == write) + return expr; + expr = pet_expr_cow(expr); + if (!expr) return NULL; + expr->acc.write = write; + + return expr; +} + +/* Replace the access relation of "expr" by "access". + */ +__isl_give pet_expr *pet_expr_access_set_access(__isl_take pet_expr *expr, + __isl_take isl_map *access) +{ + expr = pet_expr_cow(expr); + if (!expr || !access) + goto error; if (expr->type != pet_expr_access) + isl_die(pet_expr_get_ctx(expr), isl_error_invalid, + "not an access expression", goto error); + isl_map_free(expr->acc.access); + expr->acc.access = access; + + return expr; +error: + isl_map_free(access); + pet_expr_free(expr); + return NULL; +} + +/* Replace the index expression of "expr" by "index". + */ +__isl_give pet_expr *pet_expr_access_set_index(__isl_take pet_expr *expr, + __isl_take isl_multi_pw_aff *index) +{ + expr = pet_expr_cow(expr); + if (!expr || !index) + goto error; + if (expr->type != pet_expr_access) + isl_die(pet_expr_get_ctx(expr), isl_error_invalid, + "not an access expression", goto error); + isl_multi_pw_aff_free(expr->acc.index); + expr->acc.index = index; + + return expr; +error: + isl_multi_pw_aff_free(index); + pet_expr_free(expr); + return NULL; +} + +/* Return the reference identifier of access expression "expr". + */ +__isl_give isl_id *pet_expr_access_get_ref_id(__isl_keep pet_expr *expr) +{ + if (!expr) return NULL; + if (expr->type != pet_expr_access) + isl_die(pet_expr_get_ctx(expr), isl_error_invalid, + "not an access expression", return NULL); return isl_id_copy(expr->acc.ref_id); } +/* Replace the reference identifier of access expression "expr" by "ref_id". + */ +__isl_give pet_expr *pet_expr_access_set_ref_id(__isl_take pet_expr *expr, + __isl_take isl_id *ref_id) +{ + expr = pet_expr_cow(expr); + if (!expr || !ref_id) + goto error; + if (expr->type != pet_expr_access) + isl_die(pet_expr_get_ctx(expr), isl_error_invalid, + "not an access expression", goto error); + isl_id_free(expr->acc.ref_id); + expr->acc.ref_id = ref_id; + + return expr; +error: + isl_id_free(ref_id); + pet_expr_free(expr); + return NULL; +} + /* Tag the access relation "access" with "id". * That is, insert the id as the range of a wrapped relation * in the domain of "access". @@ -1273,13 +1648,18 @@ __isl_give isl_id *pet_expr_access_get_ref_id(struct pet_expr *expr) * * [D[i] -> id[]] -> A[a] */ -__isl_give isl_map *pet_expr_tag_access(struct pet_expr *expr, +__isl_give isl_map *pet_expr_tag_access(__isl_keep pet_expr *expr, __isl_take isl_map *access) { isl_space *space; isl_map *add_tag; isl_id *id; + if (expr->type != pet_expr_access) + isl_die(pet_expr_get_ctx(expr), isl_error_invalid, + "not an access expression", + return isl_map_free(access)); + id = isl_id_copy(expr->acc.ref_id); space = isl_space_range(isl_map_get_space(access)); space = isl_space_from_range(space); @@ -1293,12 +1673,14 @@ __isl_give isl_map *pet_expr_tag_access(struct pet_expr *expr, /* Return the relation mapping pairs of domain iterations and argument * values to the corresponding accessed data elements. */ -__isl_give isl_map *pet_expr_access_get_dependent_access(struct pet_expr *expr) +__isl_give isl_map *pet_expr_access_get_dependent_access( + __isl_keep pet_expr *expr) { if (!expr) return NULL; if (expr->type != pet_expr_access) - return NULL; + isl_die(pet_expr_get_ctx(expr), isl_error_invalid, + "not an access expression", return NULL); return isl_map_copy(expr->acc.access); } @@ -1308,7 +1690,7 @@ __isl_give isl_map *pet_expr_access_get_dependent_access(struct pet_expr *expr) * In particular, take the access relation and project out the values * of the arguments, if any. */ -__isl_give isl_map *pet_expr_access_get_may_access(struct pet_expr *expr) +__isl_give isl_map *pet_expr_access_get_may_access(__isl_keep pet_expr *expr) { isl_map *access; isl_space *space; @@ -1317,7 +1699,8 @@ __isl_give isl_map *pet_expr_access_get_may_access(struct pet_expr *expr) if (!expr) return NULL; if (expr->type != pet_expr_access) - return NULL; + isl_die(pet_expr_get_ctx(expr), isl_error_invalid, + "not an access expression", return NULL); access = pet_expr_access_get_dependent_access(expr); if (expr->n_arg == 0) @@ -1338,14 +1721,15 @@ __isl_give isl_map *pet_expr_access_get_may_access(struct pet_expr *expr) * If there are no arguments, then all elements are accessed. * Otherwise, we conservatively return an empty relation. */ -__isl_give isl_map *pet_expr_access_get_must_access(struct pet_expr *expr) +__isl_give isl_map *pet_expr_access_get_must_access(__isl_keep pet_expr *expr) { isl_space *space; if (!expr) return NULL; if (expr->type != pet_expr_access) - return NULL; + isl_die(pet_expr_get_ctx(expr), isl_error_invalid, + "not an access expression", return NULL); if (expr->n_arg == 0) return pet_expr_access_get_dependent_access(expr); @@ -1361,7 +1745,7 @@ __isl_give isl_map *pet_expr_access_get_must_access(struct pet_expr *expr) * identifier. */ __isl_give isl_map *pet_expr_access_get_tagged_may_access( - struct pet_expr *expr) + __isl_keep pet_expr *expr) { isl_map *access; @@ -1374,18 +1758,155 @@ __isl_give isl_map *pet_expr_access_get_tagged_may_access( return access; } -/* Return a string representation of the double expression "expr". +/* Return the operation type of operation expression "expr". + */ +enum pet_op_type pet_expr_op_get_type(__isl_keep pet_expr *expr) +{ + if (!expr) + return pet_op_last; + if (expr->type != pet_expr_op) + isl_die(pet_expr_get_ctx(expr), isl_error_invalid, + "not an operation expression", return pet_op_last); + + return expr->op; +} + +/* Replace the operation type of operation expression "expr" by "type". */ -__isl_give char *pet_expr_double_get_str(struct pet_expr *expr) +__isl_give pet_expr *pet_expr_op_set_type(__isl_take pet_expr *expr, + enum pet_op_type type) +{ + if (!expr) + return pet_expr_free(expr); + if (expr->type != pet_expr_op) + isl_die(pet_expr_get_ctx(expr), isl_error_invalid, + "not an operation expression", + return pet_expr_free(expr)); + if (expr->op == type) + return expr; + expr = pet_expr_cow(expr); + if (!expr) + return NULL; + expr->op = type; + + return expr; +} + +/* Return the name of the function called by "expr". + */ +__isl_keep const char *pet_expr_call_get_name(__isl_keep pet_expr *expr) { if (!expr) return NULL; + if (expr->type != pet_expr_call) + isl_die(pet_expr_get_ctx(expr), isl_error_invalid, + "not a call expression", return NULL); + return expr->name; +} + +/* Replace the name of the function called by "expr" by "name". + */ +__isl_give pet_expr *pet_expr_call_set_name(__isl_take pet_expr *expr, + __isl_keep const char *name) +{ + expr = pet_expr_cow(expr); + if (!expr || !name) + return pet_expr_free(expr); + if (expr->type != pet_expr_call) + isl_die(pet_expr_get_ctx(expr), isl_error_invalid, + "not a call expression", return pet_expr_free(expr)); + free(expr->name); + expr->name = strdup(name); + if (!expr->name) + return pet_expr_free(expr); + return expr; +} + +/* Replace the type of the cast performed by "expr" by "name". + */ +__isl_give pet_expr *pet_expr_cast_set_type_name(__isl_take pet_expr *expr, + __isl_keep const char *name) +{ + expr = pet_expr_cow(expr); + if (!expr || !name) + return pet_expr_free(expr); + if (expr->type != pet_expr_cast) + isl_die(pet_expr_get_ctx(expr), isl_error_invalid, + "not a cast expression", return pet_expr_free(expr)); + free(expr->type_name); + expr->type_name = strdup(name); + if (!expr->type_name) + return pet_expr_free(expr); + return expr; +} + +/* Return the value of the integer represented by "expr". + */ +__isl_give isl_val *pet_expr_int_get_val(__isl_keep pet_expr *expr) +{ + if (!expr) + return NULL; + if (expr->type != pet_expr_int) + isl_die(pet_expr_get_ctx(expr), isl_error_invalid, + "not an int expression", return NULL); + + return isl_val_copy(expr->i); +} + +/* Replace the value of the integer represented by "expr" by "v". + */ +__isl_give pet_expr *pet_expr_int_set_val(__isl_take pet_expr *expr, + __isl_take isl_val *v) +{ + expr = pet_expr_cow(expr); + if (!expr || !v) + goto error; + if (expr->type != pet_expr_int) + isl_die(pet_expr_get_ctx(expr), isl_error_invalid, + "not an int expression", goto error); + isl_val_free(expr->i); + expr->i = v; + + return expr; +error: + isl_val_free(v); + pet_expr_free(expr); + return NULL; +} + +/* Replace the value and string representation of the double + * represented by "expr" by "d" and "s". + */ +__isl_give pet_expr *pet_expr_double_set(__isl_take pet_expr *expr, + double d, __isl_keep const char *s) +{ + expr = pet_expr_cow(expr); + if (!expr || !s) + return pet_expr_free(expr); if (expr->type != pet_expr_double) + isl_die(pet_expr_get_ctx(expr), isl_error_invalid, + "not a double expression", return pet_expr_free(expr)); + expr->d.val = d; + free(expr->d.s); + expr->d.s = strdup(s); + if (!expr->d.s) + return pet_expr_free(expr); + return expr; +} + +/* Return a string representation of the double expression "expr". + */ +__isl_give char *pet_expr_double_get_str(__isl_keep pet_expr *expr) +{ + if (!expr) return NULL; + if (expr->type != pet_expr_double) + isl_die(pet_expr_get_ctx(expr), isl_error_invalid, + "not a double expression", return NULL); return strdup(expr->d.s); } -void pet_expr_dump_with_indent(struct pet_expr *expr, int indent) +void pet_expr_dump_with_indent(__isl_keep pet_expr *expr, int indent) { int i; @@ -1431,10 +1952,13 @@ void pet_expr_dump_with_indent(struct pet_expr *expr, int indent) for (i = 0; i < expr->n_arg; ++i) pet_expr_dump_with_indent(expr->args[i], indent + 2); break; + case pet_expr_error: + fprintf(stderr, "ERROR\n"); + break; } } -void pet_expr_dump(struct pet_expr *expr) +void pet_expr_dump(__isl_keep pet_expr *expr) { pet_expr_dump_with_indent(expr, 0); } diff --git a/expr.h b/expr.h dissimilarity index 70% index 57f65d0..c3d5154 100644 --- a/expr.h +++ b/expr.h @@ -1,79 +1,154 @@ -#ifndef PET_EXPR_H -#define PET_EXPR_H - -#include - -#if defined(__cplusplus) -extern "C" { -#endif - -const char *pet_type_str(enum pet_expr_type type); -enum pet_expr_type pet_str_type(const char *str); - -enum pet_op_type pet_str_op(const char *str); - -struct pet_expr *pet_expr_from_index_and_depth( - __isl_take isl_multi_pw_aff *index, int depth); -struct pet_expr *pet_expr_from_access_and_index(__isl_take isl_map *access, - __isl_take isl_multi_pw_aff *index); -struct pet_expr *pet_expr_kill_from_access_and_index(__isl_take isl_map *access, - __isl_take isl_multi_pw_aff *index); -struct pet_expr *pet_expr_new_unary(isl_ctx *ctx, enum pet_op_type op, - struct pet_expr *arg); -struct pet_expr *pet_expr_new_binary(isl_ctx *ctx, enum pet_op_type op, - struct pet_expr *lhs, struct pet_expr *rhs); -struct pet_expr *pet_expr_new_ternary(isl_ctx *ctx, struct pet_expr *cond, - struct pet_expr *lhs, struct pet_expr *rhs); -struct pet_expr *pet_expr_new_call(isl_ctx *ctx, const char *name, - unsigned n_arg); -struct pet_expr *pet_expr_new_cast(isl_ctx *ctx, const char *type_name, - struct pet_expr *arg); -struct pet_expr *pet_expr_new_double(isl_ctx *ctx, double d, const char *s); -struct pet_expr *pet_expr_new_int(__isl_take isl_val *v); - -int pet_expr_is_scalar_access(struct pet_expr *expr); -int pet_expr_is_equal(struct pet_expr *expr1, struct pet_expr *expr2); - -__isl_give isl_space *pet_expr_access_get_parameter_space( - struct pet_expr *expr); -__isl_give isl_space *pet_expr_access_get_data_space(struct pet_expr *expr); - -struct pet_expr *pet_expr_map_access(struct pet_expr *expr, - struct pet_expr *(*fn)(struct pet_expr *expr, void *user), - void *user); - -int pet_expr_writes(struct pet_expr *expr, __isl_keep isl_id *id); - -struct pet_expr *pet_expr_access_move_dims(struct pet_expr *expr, - enum isl_dim_type dst_type, unsigned dst_pos, - enum isl_dim_type src_type, unsigned src_pos, unsigned n); -struct pet_expr *pet_expr_access_pullback_multi_aff( - struct pet_expr *expr, __isl_take isl_multi_aff *ma); -struct pet_expr *pet_expr_access_align_params(struct pet_expr *expr); -struct pet_expr *pet_expr_restrict(struct pet_expr *expr, - __isl_take isl_set *cond); -struct pet_expr *pet_expr_access_update_domain(struct pet_expr *expr, - __isl_keep isl_multi_pw_aff *update); -struct pet_expr *pet_expr_update_domain(struct pet_expr *expr, - __isl_take isl_multi_pw_aff *update); -struct pet_expr *pet_expr_align_params(struct pet_expr *expr, - __isl_take isl_space *space); -struct pet_expr *pet_expr_filter(struct pet_expr *expr, - __isl_take isl_multi_pw_aff *test, int satisfied); -struct pet_expr *pet_expr_detect_parameter_accesses(struct pet_expr *expr, - __isl_take isl_space *space); -struct pet_expr *pet_expr_add_ref_ids(struct pet_expr *expr, int *n_ref); -struct pet_expr *pet_expr_anonymize(struct pet_expr *expr); -struct pet_expr *pet_expr_gist(struct pet_expr *expr, - __isl_keep isl_set *context, __isl_keep isl_union_map *value_bounds); - -__isl_give isl_map *pet_expr_tag_access(struct pet_expr *expr, - __isl_take isl_map *access); - -void pet_expr_dump_with_indent(struct pet_expr *expr, int indent); - -#if defined(__cplusplus) -} -#endif - -#endif +#ifndef PET_EXPR_H +#define PET_EXPR_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +/* d is valid when type == pet_expr_double + * i isl valid when type == pet_expr_int + * acc is valid when type == pet_expr_access + * name is valid when type == pet_expr_call + * type is valid when type == pet_expr_cast + * op is valid otherwise + * + * For each access expression inside the body of a statement, acc.ref_id + * is a unique reference identifier. + * acc.index represents the index expression, while acc.access + * represents the corresponding access relation. + * The output dimension of the index expression may be smaller + * than the number of dimensions of the accessed array. + * The target space of the access relation, on the other hand, + * is equal to the array space. + * Both acc.index and acc.access usually map an iteration space + * to a (partial) data space. + * If the access has arguments, however, then the domain of the + * mapping is a wrapped mapping from the iteration space + * to a space of dimensionality equal to the number of arguments. + * Each dimension in this space corresponds to the value of the + * corresponding argument. + * + * The ranges of the index expressions and access relations may + * also be wrapped relations, in which case the expression represents + * a member access, with the structure represented by the domain + * of this wrapped relation and the member represented by the range. + * In case of nested member accesses, the domain is itself a wrapped + * relation. + * + * If the data space is unnamed (and 1D), then it represents + * the set of integers. That is, the access represents a value that + * is equal to the index. + * + * A double is represented as both an (approximate) value "val" and + * a string representation "s". + */ +struct pet_expr { + int ref; + isl_ctx *ctx; + + enum pet_expr_type type; + + unsigned n_arg; + pet_expr **args; + + union { + struct { + isl_id *ref_id; + isl_map *access; + isl_multi_pw_aff *index; + int read; + int write; + } acc; + enum pet_op_type op; + char *name; + char *type_name; + struct { + double val; + char *s; + } d; + isl_val *i; + }; +}; + +const char *pet_type_str(enum pet_expr_type type); +enum pet_expr_type pet_str_type(const char *str); + +enum pet_op_type pet_str_op(const char *str); + +__isl_give pet_expr *pet_expr_alloc(isl_ctx *ctx, enum pet_expr_type type); +__isl_give pet_expr *pet_expr_from_index_and_depth( + __isl_take isl_multi_pw_aff *index, int depth); +__isl_give pet_expr *pet_expr_from_access_and_index(__isl_take isl_map *access, + __isl_take isl_multi_pw_aff *index); +__isl_give pet_expr *pet_expr_kill_from_access_and_index( + __isl_take isl_map *access, __isl_take isl_multi_pw_aff *index); +__isl_give pet_expr *pet_expr_new_unary(enum pet_op_type op, + __isl_take pet_expr *arg); +__isl_give pet_expr *pet_expr_new_binary(enum pet_op_type op, + __isl_take pet_expr *lhs, __isl_take pet_expr *rhs); +__isl_give pet_expr *pet_expr_new_ternary(__isl_take pet_expr *cond, + __isl_take pet_expr *lhs, __isl_take pet_expr *rhs); +__isl_give pet_expr *pet_expr_new_call(isl_ctx *ctx, const char *name, + unsigned n_arg); +__isl_give pet_expr *pet_expr_new_cast(const char *type_name, + __isl_take pet_expr *arg); +__isl_give pet_expr *pet_expr_new_double(isl_ctx *ctx, double d, const char *s); +__isl_give pet_expr *pet_expr_new_int(__isl_take isl_val *v); + +__isl_give pet_expr *pet_expr_cow(__isl_take pet_expr *expr); + +int pet_expr_is_scalar_access(__isl_keep pet_expr *expr); +int pet_expr_is_equal(__isl_keep pet_expr *expr1, __isl_keep pet_expr *expr2); + +__isl_give isl_space *pet_expr_access_get_parameter_space( + __isl_take pet_expr *expr); +__isl_give isl_space *pet_expr_access_get_data_space(__isl_keep pet_expr *expr); + +__isl_give pet_expr *pet_expr_map_access(__isl_take pet_expr *expr, + __isl_give pet_expr *(*fn)(__isl_take pet_expr *expr, void *user), + void *user); + +__isl_give isl_map *pet_expr_access_get_access(__isl_keep pet_expr *expr); +__isl_give pet_expr *pet_expr_access_set_access(__isl_take pet_expr *expr, + __isl_take isl_map *access); +__isl_give pet_expr *pet_expr_access_set_index(__isl_take pet_expr *expr, + __isl_take isl_multi_pw_aff *index); + +int pet_expr_writes(__isl_keep pet_expr *expr, __isl_keep isl_id *id); + +__isl_give pet_expr *pet_expr_access_move_dims(__isl_take pet_expr *expr, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n); +__isl_give pet_expr *pet_expr_access_pullback_multi_aff( + __isl_take pet_expr *expr, __isl_take isl_multi_aff *ma); +__isl_give pet_expr *pet_expr_access_align_params(__isl_take pet_expr *expr); +__isl_give pet_expr *pet_expr_restrict(__isl_take pet_expr *expr, + __isl_take isl_set *cond); +__isl_give pet_expr *pet_expr_access_update_domain(__isl_take pet_expr *expr, + __isl_keep isl_multi_pw_aff *update); +__isl_give pet_expr *pet_expr_update_domain(__isl_take pet_expr *expr, + __isl_take isl_multi_pw_aff *update); +__isl_give pet_expr *pet_expr_align_params(__isl_take pet_expr *expr, + __isl_take isl_space *space); +__isl_give pet_expr *pet_expr_filter(__isl_take pet_expr *expr, + __isl_take isl_multi_pw_aff *test, int satisfied); +__isl_give pet_expr *pet_expr_detect_parameter_accesses( + __isl_take pet_expr *expr, __isl_take isl_space *space); +__isl_give pet_expr *pet_expr_add_ref_ids(__isl_take pet_expr *expr, + int *n_ref); +__isl_give pet_expr *pet_expr_anonymize(__isl_take pet_expr *expr); +__isl_give pet_expr *pet_expr_gist(__isl_take pet_expr *expr, + __isl_keep isl_set *context, __isl_keep isl_union_map *value_bounds); + +__isl_give isl_map *pet_expr_tag_access(__isl_keep pet_expr *expr, + __isl_take isl_map *access); + +void pet_expr_dump_with_indent(__isl_keep pet_expr *expr, int indent); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/include/pet.h b/include/pet.h index 9fd4219..79300d5 100644 --- a/include/pet.h +++ b/include/pet.h @@ -32,6 +32,7 @@ int pet_options_set_signed_overflow(isl_ctx *ctx, int val); int pet_options_get_signed_overflow(isl_ctx *ctx); enum pet_expr_type { + pet_expr_error = -1, pet_expr_access, pet_expr_call, pet_expr_cast, @@ -102,106 +103,102 @@ enum pet_ter_arg_type { pet_ter_false }; -/* d is valid when type == pet_expr_double - * i isl valid when type == pet_expr_int - * acc is valid when type == pet_expr_access - * name is valid when type == pet_expr_call - * type is valid when type == pet_expr_cast - * op is valid otherwise - * - * For each access expression inside the body of a statement, acc.ref_id - * is a unique reference identifier. - * acc.index represents the index expression, while acc.access - * represents the corresponding access relation. - * The output dimension of the index expression may be smaller - * than the number of dimensions of the accessed array. - * The target space of the access relation, on the other hand, - * is equal to the array space. - * Both acc.index and acc.access usually map an iteration space - * to a (partial) data space. - * If the access has arguments, however, then the domain of the - * mapping is a wrapped mapping from the iteration space - * to a space of dimensionality equal to the number of arguments. - * Each dimension in this space corresponds to the value of the - * corresponding argument. - * - * The ranges of the index expressions and access relations may - * also be wrapped relations, in which case the expression represents - * a member access, with the structure represented by the domain - * of this wrapped relation and the member represented by the range. - * In case of nested member accesses, the domain is itself a wrapped - * relation. - * - * If the data space is unnamed (and 1D), then it represents - * the set of integers. That is, the access represents a value that - * is equal to the index. - * - * A double is represented as both an (approximate) value "val" and - * a string representation "s". - */ -struct pet_expr { - enum pet_expr_type type; - - unsigned n_arg; - struct pet_expr **args; - - union { - struct { - isl_id *ref_id; - isl_map *access; - isl_multi_pw_aff *index; - int read; - int write; - } acc; - enum pet_op_type op; - char *name; - char *type_name; - struct { - double val; - char *s; - } d; - isl_val *i; - }; -}; - -struct pet_expr *pet_expr_free(struct pet_expr *expr); +struct pet_expr; +typedef struct pet_expr pet_expr; + +/* Return an additional reference to "expr". */ +__isl_give pet_expr *pet_expr_copy(__isl_keep pet_expr *expr); +/* Free a reference to "expr". */ +__isl_null pet_expr *pet_expr_free(__isl_take pet_expr *expr); + +/* Return the isl_ctx in which "expr" was created. */ +isl_ctx *pet_expr_get_ctx(__isl_keep pet_expr *expr); + +/* Return the type of "expr". */ +enum pet_expr_type pet_expr_get_type(__isl_keep pet_expr *expr); +/* Return the number of arguments of "expr". */ +int pet_expr_get_n_arg(__isl_keep pet_expr *expr); +/* Set the number of arguments of "expr" to "n". */ +__isl_give pet_expr *pet_expr_set_n_arg(__isl_take pet_expr *expr, int n); +/* Return the argument of "expr" at position "pos". */ +__isl_give pet_expr *pet_expr_get_arg(__isl_keep pet_expr *expr, int pos); +/* Replace the argument of "expr" at position "pos" by "arg". */ +__isl_give pet_expr *pet_expr_set_arg(__isl_take pet_expr *expr, int pos, + __isl_take pet_expr *arg); + +/* Return the operation type of operation expression "expr". */ +enum pet_op_type pet_expr_op_get_type(__isl_keep pet_expr *expr); +/* Replace the operation type of operation expression "expr" by "type". */ +__isl_give pet_expr *pet_expr_op_set_type(__isl_take pet_expr *expr, + enum pet_op_type type); /* Construct a (read) access pet_expr from an index expression. */ -struct pet_expr *pet_expr_from_index(__isl_take isl_multi_pw_aff *index); +__isl_give pet_expr *pet_expr_from_index(__isl_take isl_multi_pw_aff *index); /* Does "expr" represent an affine expression? */ -int pet_expr_is_affine(struct pet_expr *expr); +int pet_expr_is_affine(__isl_keep pet_expr *expr); /* Does the access expression "expr" read the accessed elements? */ -int pet_expr_access_is_read(struct pet_expr *expr); +int pet_expr_access_is_read(__isl_keep pet_expr *expr); /* Does the access expression "expr" write to the accessed elements? */ -int pet_expr_access_is_write(struct pet_expr *expr); -/* Return the identifier of the outer array accessed by "expr". */ -__isl_give isl_id *pet_expr_access_get_id(struct pet_expr *expr); - +int pet_expr_access_is_write(__isl_keep pet_expr *expr); +/* Mark "expr" as a read dependening on "read". */ +__isl_give pet_expr *pet_expr_access_set_read(__isl_take pet_expr *expr, + int read); +/* Mark "expr" as a write dependening on "write". */ +__isl_give pet_expr *pet_expr_access_set_write(__isl_take pet_expr *expr, + int write); /* Return the reference identifier of access expression "expr". */ -__isl_give isl_id *pet_expr_access_get_ref_id(struct pet_expr *expr); +__isl_give isl_id *pet_expr_access_get_ref_id(__isl_keep pet_expr *expr); +/* Replace the reference identifier of access expression "expr" by "ref_id". */ +__isl_give pet_expr *pet_expr_access_set_ref_id(__isl_take pet_expr *expr, + __isl_take isl_id *ref_id); +/* Return the identifier of the outer array accessed by "expr". */ +__isl_give isl_id *pet_expr_access_get_id(__isl_keep pet_expr *expr); +/* Return the index expression of access expression "expr". */ +__isl_give isl_multi_pw_aff *pet_expr_access_get_index( + __isl_keep pet_expr *expr); /* Return the potential read access relation of access expression "expr". */ -__isl_give isl_map *pet_expr_access_get_may_access(struct pet_expr *expr); +__isl_give isl_map *pet_expr_access_get_may_access(__isl_keep pet_expr *expr); /* Return the definite access relation of access expression "expr". */ -__isl_give isl_map *pet_expr_access_get_must_access(struct pet_expr *expr); +__isl_give isl_map *pet_expr_access_get_must_access(__isl_keep pet_expr *expr); /* Return the argument dependent access relation of access expression "expr". */ -__isl_give isl_map *pet_expr_access_get_dependent_access(struct pet_expr *expr); +__isl_give isl_map *pet_expr_access_get_dependent_access( + __isl_keep pet_expr *expr); /* Return the tagged potential read access relation of access "expr". */ __isl_give isl_map *pet_expr_access_get_tagged_may_access( - struct pet_expr *expr); + __isl_keep pet_expr *expr); + +/* Return the name of the function called by "expr". */ +__isl_keep const char *pet_expr_call_get_name(__isl_keep pet_expr *expr); +/* Replace the name of the function called by "expr" by "name". */ +__isl_give pet_expr *pet_expr_call_set_name(__isl_take pet_expr *expr, + __isl_keep const char *name); + +/* Replace the type of the cast performed by "expr" by "name". */ +__isl_give pet_expr *pet_expr_cast_set_type_name(__isl_take pet_expr *expr, + __isl_keep const char *name); + +/* Return the value of the integer represented by "expr". */ +__isl_give isl_val *pet_expr_int_get_val(__isl_keep pet_expr *expr); +/* Replace the value of the integer represented by "expr" by "v". */ +__isl_give pet_expr *pet_expr_int_set_val(__isl_take pet_expr *expr, + __isl_take isl_val *v); /* Return a string representation of the double expression "expr". */ -__isl_give char *pet_expr_double_get_str(struct pet_expr *expr); +__isl_give char *pet_expr_double_get_str(__isl_keep pet_expr *expr); +/* Replace value and string representation of the double expression "expr" */ +__isl_give pet_expr *pet_expr_double_set(__isl_take pet_expr *expr, + double d, __isl_keep const char *s); /* Call "fn" on each of the subexpressions of "expr" of type pet_expr_access. */ -int pet_expr_foreach_access_expr(struct pet_expr *expr, - int (*fn)(struct pet_expr *expr, void *user), void *user); +int pet_expr_foreach_access_expr(__isl_keep pet_expr *expr, + int (*fn)(__isl_keep pet_expr *expr, void *user), void *user); /* Call "fn" on each of the subexpressions of "expr" of type pet_expr_call. */ -int pet_expr_foreach_call_expr(struct pet_expr *expr, - int (*fn)(struct pet_expr *expr, void *user), void *user); +int pet_expr_foreach_call_expr(__isl_keep pet_expr *expr, + int (*fn)(__isl_keep pet_expr *expr, void *user), void *user); -void pet_expr_dump(struct pet_expr *expr); +void pet_expr_dump(__isl_keep pet_expr *expr); /* If the statement has arguments, i.e., n_arg != 0, then * "domain" is a wrapped map, mapping the iteration domain @@ -218,10 +215,10 @@ struct pet_stmt { int line; isl_set *domain; isl_map *schedule; - struct pet_expr *body; + pet_expr *body; unsigned n_arg; - struct pet_expr **args; + pet_expr **args; }; /* Return the iteration space of "stmt". */ diff --git a/nest.c b/nest.c index e7dc366..e990f20 100644 --- a/nest.c +++ b/nest.c @@ -218,9 +218,13 @@ static __isl_give isl_multi_pw_aff *pet_nested_remove_from_multi_pw_aff( /* Remove all parameters from the index expression and access relation of "expr" * that refer to nested accesses. */ -static struct pet_expr *expr_remove_nested_parameters(struct pet_expr *expr, - void *user) +static __isl_give pet_expr *expr_remove_nested_parameters( + __isl_take pet_expr *expr, void *user) { + expr = pet_expr_cow(expr); + if (!expr) + return NULL; + expr->acc.access = pet_nested_remove_from_map(expr->acc.access); expr->acc.index = pet_nested_remove_from_multi_pw_aff(expr->acc.index); if (!expr->acc.access || !expr->acc.index) diff --git a/parse.c b/parse.c index 4d788e1..1147181 100644 --- a/parse.c +++ b/parse.c @@ -295,33 +295,30 @@ static struct pet_scop *extract_arrays(isl_ctx *ctx, yaml_document_t *document, return scop; } -static struct pet_expr *extract_expr(isl_ctx *ctx, yaml_document_t *document, - yaml_node_t *node); +static __isl_give pet_expr *extract_expr(isl_ctx *ctx, + yaml_document_t *document, yaml_node_t *node); -static struct pet_expr *extract_arguments(isl_ctx *ctx, - yaml_document_t *document, yaml_node_t *node, struct pet_expr *expr) +static __isl_give pet_expr *extract_arguments(isl_ctx *ctx, + yaml_document_t *document, yaml_node_t *node, __isl_take pet_expr *expr) { - int i; + int i, n; yaml_node_item_t *item; if (node->type != YAML_SEQUENCE_NODE) isl_die(ctx, isl_error_invalid, "expecting sequence", return pet_expr_free(expr)); - expr->n_arg = node->data.sequence.items.top - - node->data.sequence.items.start; - expr->args = isl_calloc_array(ctx, struct pet_expr *, expr->n_arg); - if (!expr->args) - return pet_expr_free(expr); + n = node->data.sequence.items.top - node->data.sequence.items.start; + expr = pet_expr_set_n_arg(expr, n); for (item = node->data.sequence.items.start, i = 0; item < node->data.sequence.items.top; ++item, ++i) { yaml_node_t *n; + pet_expr *arg; n = yaml_document_get_node(document, *item); - expr->args[i] = extract_expr(ctx, document, n); - if (!expr->args[i]) - return pet_expr_free(expr); + arg = extract_expr(ctx, document, n); + expr = pet_expr_set_arg(expr, i, arg); } return expr; @@ -330,10 +327,12 @@ static struct pet_expr *extract_arguments(isl_ctx *ctx, /* Extract pet_expr_double specific fields from "node" and * update "expr" accordingly. */ -static struct pet_expr *extract_expr_double(isl_ctx *ctx, - yaml_document_t *document, yaml_node_t *node, struct pet_expr *expr) +static __isl_give pet_expr *extract_expr_double(isl_ctx *ctx, + yaml_document_t *document, yaml_node_t *node, __isl_take pet_expr *expr) { yaml_node_pair_t *pair; + double d = 0; + char *s = NULL; for (pair = node->data.mapping.pairs.start; pair < node->data.mapping.pairs.top; ++pair) { @@ -347,19 +346,22 @@ static struct pet_expr *extract_expr_double(isl_ctx *ctx, return pet_expr_free(expr)); if (!strcmp((char *) key->data.scalar.value, "value")) - expr->d.val = extract_double(ctx, document, value); + d = extract_double(ctx, document, value); if (!strcmp((char *) key->data.scalar.value, "string")) - expr->d.s = extract_string(ctx, document, value); + s = extract_string(ctx, document, value); } + expr = pet_expr_double_set(expr, d, s); + free(s); + return expr; } /* Extract pet_expr_access specific fields from "node" and * update "expr" accordingly. */ -static struct pet_expr *extract_expr_access(isl_ctx *ctx, - yaml_document_t *document, yaml_node_t *node, struct pet_expr *expr) +static __isl_give pet_expr *extract_expr_access(isl_ctx *ctx, + yaml_document_t *document, yaml_node_t *node, __isl_take pet_expr *expr) { yaml_node_pair_t *pair; @@ -375,16 +377,20 @@ static struct pet_expr *extract_expr_access(isl_ctx *ctx, return pet_expr_free(expr)); if (!strcmp((char *) key->data.scalar.value, "relation")) - expr->acc.access = extract_map(ctx, document, value); + expr = pet_expr_access_set_access(expr, + extract_map(ctx, document, value)); if (!strcmp((char *) key->data.scalar.value, "index")) - expr->acc.index = extract_multi_pw_aff(ctx, document, - value); + expr = pet_expr_access_set_index(expr, + extract_multi_pw_aff(ctx, document, value)); if (!strcmp((char *) key->data.scalar.value, "reference")) - expr->acc.ref_id = extract_id(ctx, document, value); + expr = pet_expr_access_set_ref_id(expr, + extract_id(ctx, document, value)); if (!strcmp((char *) key->data.scalar.value, "read")) - expr->acc.read = extract_int(ctx, document, value); + expr = pet_expr_access_set_read(expr, + extract_int(ctx, document, value)); if (!strcmp((char *) key->data.scalar.value, "write")) - expr->acc.write = extract_int(ctx, document, value); + expr = pet_expr_access_set_write(expr, + extract_int(ctx, document, value)); } return expr; @@ -393,8 +399,8 @@ static struct pet_expr *extract_expr_access(isl_ctx *ctx, /* Extract operation expression specific fields from "node" and * update "expr" accordingly. */ -static struct pet_expr *extract_expr_op(isl_ctx *ctx, - yaml_document_t *document, yaml_node_t *node, struct pet_expr *expr) +static __isl_give pet_expr *extract_expr_op(isl_ctx *ctx, + yaml_document_t *document, yaml_node_t *node, __isl_take pet_expr *expr) { yaml_node_pair_t *pair; @@ -410,7 +416,8 @@ static struct pet_expr *extract_expr_op(isl_ctx *ctx, return pet_expr_free(expr)); if (!strcmp((char *) key->data.scalar.value, "operation")) - expr->op = extract_op(ctx, document, value); + expr = pet_expr_op_set_type(expr, + extract_op(ctx, document, value)); } return expr; @@ -419,8 +426,8 @@ static struct pet_expr *extract_expr_op(isl_ctx *ctx, /* Extract pet_expr_call specific fields from "node" and * update "expr" accordingly. */ -static struct pet_expr *extract_expr_call(isl_ctx *ctx, - yaml_document_t *document, yaml_node_t *node, struct pet_expr *expr) +static __isl_give pet_expr *extract_expr_call(isl_ctx *ctx, + yaml_document_t *document, yaml_node_t *node, __isl_take pet_expr *expr) { yaml_node_pair_t *pair; @@ -436,7 +443,8 @@ static struct pet_expr *extract_expr_call(isl_ctx *ctx, return pet_expr_free(expr)); if (!strcmp((char *) key->data.scalar.value, "name")) - expr->name = extract_string(ctx, document, value); + expr = pet_expr_call_set_name(expr, + extract_string(ctx, document, value)); } return expr; @@ -445,8 +453,8 @@ static struct pet_expr *extract_expr_call(isl_ctx *ctx, /* Extract pet_expr_cast specific fields from "node" and * update "expr" accordingly. */ -static struct pet_expr *extract_expr_cast(isl_ctx *ctx, - yaml_document_t *document, yaml_node_t *node, struct pet_expr *expr) +static __isl_give pet_expr *extract_expr_cast(isl_ctx *ctx, + yaml_document_t *document, yaml_node_t *node, __isl_take pet_expr *expr) { yaml_node_pair_t *pair; @@ -462,7 +470,8 @@ static struct pet_expr *extract_expr_cast(isl_ctx *ctx, return pet_expr_free(expr)); if (!strcmp((char *) key->data.scalar.value, "type_name")) - expr->type_name = extract_string(ctx, document, value); + expr = pet_expr_cast_set_type_name(expr, + extract_string(ctx, document, value)); } return expr; @@ -471,8 +480,8 @@ static struct pet_expr *extract_expr_cast(isl_ctx *ctx, /* Extract pet_expr_int specific fields from "node" and * update "expr" accordingly. */ -static struct pet_expr *extract_expr_int(isl_ctx *ctx, - yaml_document_t *document, yaml_node_t *node, struct pet_expr *expr) +static __isl_give pet_expr *extract_expr_int(isl_ctx *ctx, + yaml_document_t *document, yaml_node_t *node, __isl_take pet_expr *expr) { yaml_node_pair_t * pair; @@ -488,7 +497,8 @@ static struct pet_expr *extract_expr_int(isl_ctx *ctx, return pet_expr_free(expr)); if (!strcmp((char *) key->data.scalar.value, "value")) - expr->i = extract_val(ctx, document, value); + expr = pet_expr_int_set_val(expr, + extract_val(ctx, document, value)); } return expr; @@ -499,20 +509,17 @@ static struct pet_expr *extract_expr_int(isl_ctx *ctx, * We first extract the type and arguments of the expression and * then extract additional fields depending on the type. */ -static struct pet_expr *extract_expr(isl_ctx *ctx, yaml_document_t *document, - yaml_node_t *node) +static __isl_give pet_expr *extract_expr(isl_ctx *ctx, + yaml_document_t *document, yaml_node_t *node) { - struct pet_expr *expr; + enum pet_expr_type type = pet_expr_error; + pet_expr *expr; yaml_node_pair_t *pair; if (node->type != YAML_MAPPING_NODE) isl_die(ctx, isl_error_invalid, "expecting mapping", return NULL); - expr = isl_calloc_type(ctx, struct pet_expr); - if (!expr) - return NULL; - for (pair = node->data.mapping.pairs.start; pair < node->data.mapping.pairs.top; ++pair) { yaml_node_t *key, *value; @@ -525,7 +532,23 @@ static struct pet_expr *extract_expr(isl_ctx *ctx, yaml_document_t *document, return pet_expr_free(expr)); if (!strcmp((char *) key->data.scalar.value, "type")) - expr->type = extract_expr_type(ctx, document, value); + type = extract_expr_type(ctx, document, value); + } + + if (type == pet_expr_error) + isl_die(ctx, isl_error_invalid, "cannot determine type", + return NULL); + + expr = pet_expr_alloc(ctx, type); + if (!expr) + return NULL; + + for (pair = node->data.mapping.pairs.start; + pair < node->data.mapping.pairs.top; ++pair) { + yaml_node_t *key, *value; + + key = yaml_document_get_node(document, pair->key); + value = yaml_document_get_node(document, pair->value); if (!strcmp((char *) key->data.scalar.value, "arguments")) expr = extract_arguments(ctx, document, value, expr); @@ -533,7 +556,10 @@ static struct pet_expr *extract_expr(isl_ctx *ctx, yaml_document_t *document, return NULL; } - switch (expr->type) { + switch (type) { + case pet_expr_error: + isl_die(ctx, isl_error_internal, "unreachable code", + return NULL); case pet_expr_access: expr = extract_expr_access(ctx, document, node, expr); break; @@ -569,7 +595,7 @@ static struct pet_stmt *extract_stmt_arguments(isl_ctx *ctx, stmt->n_arg = node->data.sequence.items.top - node->data.sequence.items.start; - stmt->args = isl_calloc_array(ctx, struct pet_expr *, stmt->n_arg); + stmt->args = isl_calloc_array(ctx, pet_expr *, stmt->n_arg); if (!stmt->args) return pet_stmt_free(stmt); diff --git a/pet_check_code.c b/pet_check_code.c index 3320944..74949ba 100644 --- a/pet_check_code.c +++ b/pet_check_code.c @@ -58,7 +58,7 @@ ISL_ARGS_END ISL_ARG_DEF(options, struct options, options_args) -static __isl_give isl_pw_aff *expr_extract_pw_aff(struct pet_expr *expr, +static __isl_give isl_pw_aff *expr_extract_pw_aff(__isl_keep pet_expr *expr, __isl_keep isl_space *space, __isl_keep isl_id_to_pw_aff *assignments); /* Extract an affine expression from the call to floord in "expr", @@ -66,13 +66,18 @@ static __isl_give isl_pw_aff *expr_extract_pw_aff(struct pet_expr *expr, * * "space" is the iteration space of the statement containing the expression. */ -static __isl_give isl_pw_aff *expr_extract_floord(struct pet_expr *expr, +static __isl_give isl_pw_aff *expr_extract_floord(__isl_keep pet_expr *expr, __isl_keep isl_space *space, __isl_keep isl_id_to_pw_aff *assignments) { isl_pw_aff *lhs, *rhs; - - lhs = expr_extract_pw_aff(expr->args[0], space, assignments); - rhs = expr_extract_pw_aff(expr->args[1], space, assignments); + pet_expr *arg; + + arg = pet_expr_get_arg(expr, 0); + lhs = expr_extract_pw_aff(arg, space, assignments); + pet_expr_free(arg); + arg = pet_expr_get_arg(expr, 1); + rhs = expr_extract_pw_aff(arg, space, assignments); + pet_expr_free(arg); return isl_pw_aff_floor(isl_pw_aff_div(lhs, rhs)); } @@ -83,12 +88,20 @@ static __isl_give isl_pw_aff *expr_extract_floord(struct pet_expr *expr, * * We only support calls to the "floord" function for now. */ -static __isl_give isl_pw_aff *call_expr_extract_pw_aff(struct pet_expr *expr, - __isl_keep isl_space *space, __isl_keep isl_id_to_pw_aff *assignments) +static __isl_give isl_pw_aff *call_expr_extract_pw_aff( + __isl_keep pet_expr *expr, __isl_keep isl_space *space, + __isl_keep isl_id_to_pw_aff *assignments) { - assert(!strcmp(expr->name, "floord")); + const char *name; - return expr_extract_floord(expr, space, assignments); + name = pet_expr_call_get_name(expr); + if (!name) + return NULL; + if (!strcmp(name, "floord")) + return expr_extract_floord(expr, space, assignments); + + isl_die(isl_id_to_pw_aff_get_ctx(assignments), isl_error_unsupported, + "unsupported expression", return NULL); } /* Is the variable accessed by "index" assigned in "assignments"? @@ -208,32 +221,34 @@ static __isl_give isl_pw_aff *resolve_access(__isl_take isl_multi_pw_aff *index, * Otherwise, we try and convert the access to an affine expression in * resolve_access(). */ -static __isl_give isl_pw_aff *access_expr_extract_pw_aff(struct pet_expr *expr, - __isl_keep isl_id_to_pw_aff *assignments) +static __isl_give isl_pw_aff *access_expr_extract_pw_aff( + __isl_keep pet_expr *expr, __isl_keep isl_id_to_pw_aff *assignments) { isl_pw_aff *pa; + isl_multi_pw_aff *index; - if (isl_multi_pw_aff_has_tuple_id(expr->acc.index, isl_dim_out)) { - isl_multi_pw_aff *index; - index = isl_multi_pw_aff_copy(expr->acc.index); + index = pet_expr_access_get_index(expr); + if (isl_multi_pw_aff_has_tuple_id(index, isl_dim_out)) { pa = resolve_access(index, assignments); - } else - pa = isl_multi_pw_aff_get_pw_aff(expr->acc.index, 0); + } else { + pa = isl_multi_pw_aff_get_pw_aff(index, 0); + isl_multi_pw_aff_free(index); + } return pa; } /* Extract an affine expression defined over iteration space "space" * from the integer expression "expr". */ -static __isl_give isl_pw_aff *int_expr_extract_pw_aff(struct pet_expr *expr, - __isl_keep isl_space *space) +static __isl_give isl_pw_aff *int_expr_extract_pw_aff( + __isl_keep pet_expr *expr, __isl_keep isl_space *space) { isl_local_space *ls; isl_aff *aff; ls = isl_local_space_from_space(isl_space_copy(space)); aff = isl_aff_zero_on_domain(ls); - aff = isl_aff_add_constant_val(aff, isl_val_copy(expr->i)); + aff = isl_aff_add_constant_val(aff, pet_expr_int_get_val(expr)); return isl_pw_aff_from_aff(aff); } @@ -245,23 +260,29 @@ static __isl_give isl_pw_aff *int_expr_extract_pw_aff(struct pet_expr *expr, * We only handle the kinds of expressions that we would expect * as arguments to a function call in code generated by isl. */ -static __isl_give isl_pw_aff *op_expr_extract_pw_aff(struct pet_expr *expr, +static __isl_give isl_pw_aff *op_expr_extract_pw_aff(__isl_keep pet_expr *expr, __isl_keep isl_space *space, __isl_keep isl_id_to_pw_aff *assignments) { isl_pw_aff *pa, *pa1, *pa2; + pet_expr *arg; - switch (expr->n_arg) { + switch (pet_expr_get_n_arg(expr)) { case 1: - if (expr->op == pet_op_minus) { - pa = expr_extract_pw_aff(expr->args[0], space, - assignments); + if (pet_expr_op_get_type(expr) == pet_op_minus) { + arg = pet_expr_get_arg(expr, 0); + pa = expr_extract_pw_aff(arg, space, assignments); + pet_expr_free(arg); return isl_pw_aff_neg(pa); } assert(0); case 2: - pa1 = expr_extract_pw_aff(expr->args[0], space, assignments); - pa2 = expr_extract_pw_aff(expr->args[1], space, assignments); - switch (expr->op) { + arg = pet_expr_get_arg(expr, 0); + pa1 = expr_extract_pw_aff(arg, space, assignments); + pet_expr_free(arg); + arg = pet_expr_get_arg(expr, 1); + pa2 = expr_extract_pw_aff(arg, space, assignments); + pet_expr_free(arg); + switch (pet_expr_op_get_type(expr)) { case pet_op_mul: pa = isl_pw_aff_mul(pa1, pa2); break; @@ -282,9 +303,15 @@ static __isl_give isl_pw_aff *op_expr_extract_pw_aff(struct pet_expr *expr, } return pa; case 3: - pa = expr_extract_pw_aff(expr->args[0], space, assignments); - pa1 = expr_extract_pw_aff(expr->args[1], space, assignments); - pa2 = expr_extract_pw_aff(expr->args[2], space, assignments); + arg = pet_expr_get_arg(expr, 0); + pa = expr_extract_pw_aff(arg, space, assignments); + pet_expr_free(arg); + arg = pet_expr_get_arg(expr, 1); + pa1 = expr_extract_pw_aff(arg, space, assignments); + pet_expr_free(arg); + arg = pet_expr_get_arg(expr, 2); + pa2 = expr_extract_pw_aff(arg, space, assignments); + pet_expr_free(arg); return isl_pw_aff_cond(pa, pa1, pa2); default: assert(0); @@ -299,10 +326,10 @@ static __isl_give isl_pw_aff *op_expr_extract_pw_aff(struct pet_expr *expr, * We only handle the kinds of expressions that we would expect * as arguments to a function call in code generated by isl. */ -static __isl_give isl_pw_aff *expr_extract_pw_aff(struct pet_expr *expr, +static __isl_give isl_pw_aff *expr_extract_pw_aff(__isl_keep pet_expr *expr, __isl_keep isl_space *space, __isl_keep isl_id_to_pw_aff *assignments) { - switch (expr->type) { + switch (pet_expr_get_type(expr)) { case pet_expr_int: return int_expr_extract_pw_aff(expr, space); case pet_expr_access: @@ -313,6 +340,7 @@ static __isl_give isl_pw_aff *expr_extract_pw_aff(struct pet_expr *expr, return call_expr_extract_pw_aff(expr, space, assignments); case pet_expr_cast: case pet_expr_double: + case pet_expr_error: assert(0); } } @@ -322,7 +350,7 @@ static __isl_give isl_pw_aff *expr_extract_pw_aff(struct pet_expr *expr, * * "space" is the iteration space of the statement containing the expression. */ -static __isl_give isl_map *expr_extract_map(struct pet_expr *expr, +static __isl_give isl_map *expr_extract_map(__isl_keep pet_expr *expr, __isl_keep isl_space *space, __isl_keep isl_id_to_pw_aff *assignments) { isl_pw_aff *pa; @@ -340,26 +368,32 @@ static __isl_give isl_map *expr_extract_map(struct pet_expr *expr, static __isl_give isl_map *stmt_extract_call(struct pet_stmt *stmt, __isl_keep isl_id_to_pw_aff *assignments) { - int i; + int i, n; isl_set *domain; isl_map *call; + const char *name; domain = isl_set_copy(stmt->domain); call = isl_map_from_domain(domain); - assert(stmt->body->type == pet_expr_call); + assert(pet_expr_get_type(stmt->body) == pet_expr_call); - for (i = 0; i < stmt->body->n_arg; ++i) { - isl_map *arg; + n = pet_expr_get_n_arg(stmt->body); + for (i = 0; i < n; ++i) { + isl_map *map_i; isl_space *space; + pet_expr *arg; + arg = pet_expr_get_arg(stmt->body, i); space = pet_stmt_get_space(stmt); - arg = expr_extract_map(stmt->body->args[i], space, assignments); + map_i = expr_extract_map(arg, space, assignments); isl_space_free(space); - call = isl_map_flat_range_product(call, arg); + pet_expr_free(arg); + call = isl_map_flat_range_product(call, map_i); } - call = isl_map_set_tuple_name(call, isl_dim_out, stmt->body->name); + name = pet_expr_call_get_name(stmt->body); + call = isl_map_set_tuple_name(call, isl_dim_out, name); return call; } @@ -380,14 +414,18 @@ static __isl_give isl_id_to_pw_aff *add_assignment( isl_id *var; isl_space *space; isl_pw_aff *val; - - assert(stmt->body->op == pet_op_assign); - assert(stmt->body->args[0]->type == pet_expr_access); - var = isl_map_get_tuple_id(stmt->body->args[0]->acc.access, - isl_dim_out); + pet_expr *arg; + + assert(pet_stmt_is_assign(stmt)); + arg = pet_expr_get_arg(stmt->body, 0); + assert(pet_expr_get_type(arg) == pet_expr_access); + var = pet_expr_access_get_id(arg); + pet_expr_free(arg); + arg = pet_expr_get_arg(stmt->body, 1); space = pet_stmt_get_space(stmt); - val = expr_extract_pw_aff(stmt->body->args[1], space, assignments); + val = expr_extract_pw_aff(arg, space, assignments); isl_space_free(space); + pet_expr_free(arg); assignments = isl_id_to_pw_aff_set(assignments, var, val); diff --git a/print.c b/print.c index 8ae4ba0..c9bbbff 100644 --- a/print.c +++ b/print.c @@ -76,7 +76,7 @@ struct pet_build_ast_expr_data { * */ static __isl_give isl_multi_pw_aff *parametrize_nested_exprs( - __isl_take isl_multi_pw_aff *index, struct pet_expr *expr) + __isl_take isl_multi_pw_aff *index, __isl_keep pet_expr *expr) { int i; isl_ctx *ctx; @@ -114,8 +114,8 @@ static __isl_give isl_multi_pw_aff *parametrize_nested_exprs( return isl_multi_pw_aff_pullback_multi_aff(index, ma); } -static __isl_give isl_ast_expr *pet_expr_build_ast_expr(struct pet_expr *expr, - struct pet_build_ast_expr_data *data); +static __isl_give isl_ast_expr *pet_expr_build_ast_expr( + __isl_keep pet_expr *expr, struct pet_build_ast_expr_data *data); /* Construct an associative array from identifiers for the nested * expressions of "expr" to the corresponding isl_ast_expr. @@ -123,7 +123,7 @@ static __isl_give isl_ast_expr *pet_expr_build_ast_expr(struct pet_expr *expr, * The same identifiers are used in parametrize_nested_exprs. */ static __isl_give isl_id_to_ast_expr *pet_expr_build_nested_ast_exprs( - struct pet_expr *expr, struct pet_build_ast_expr_data *data) + __isl_keep pet_expr *expr, struct pet_build_ast_expr_data *data) { int i; isl_ctx *ctx = isl_ast_build_get_ctx(data->build); @@ -158,8 +158,8 @@ static __isl_give isl_id_to_ast_expr *pet_expr_build_nested_ast_exprs( * Finally, we apply an AST transformation on the result, if any was provided * by the user. */ -static __isl_give isl_ast_expr *pet_expr_build_ast_expr(struct pet_expr *expr, - struct pet_build_ast_expr_data *data) +static __isl_give isl_ast_expr *pet_expr_build_ast_expr( + __isl_keep pet_expr *expr, struct pet_build_ast_expr_data *data) { isl_pw_aff *pa; isl_multi_pw_aff *mpa; @@ -204,7 +204,7 @@ static __isl_give isl_ast_expr *pet_expr_build_ast_expr(struct pet_expr *expr, * add the mapping from reference identifier to AST expression to * data->ref2expr. */ -static int add_access(struct pet_expr *expr, void *user) +static int add_access(__isl_keep pet_expr *expr, void *user) { struct pet_build_ast_expr_data *data = user; isl_id *id; @@ -254,7 +254,7 @@ __isl_give isl_id_to_ast_expr *pet_stmt_build_ast_exprs(struct pet_stmt *stmt, * and print that to "p". */ static __isl_give isl_printer *print_access(__isl_take isl_printer *p, - struct pet_expr *expr, __isl_keep isl_id_to_ast_expr *ref2expr) + __isl_keep pet_expr *expr, __isl_keep isl_id_to_ast_expr *ref2expr) { isl_ast_expr *ast_expr; int is_access; @@ -291,7 +291,7 @@ static int is_postfix(enum pet_op_type op) } static __isl_give isl_printer *print_pet_expr(__isl_take isl_printer *p, - struct pet_expr *expr, int outer, + __isl_keep pet_expr *expr, int outer, __isl_keep isl_id_to_ast_expr *ref2expr); /* Print operation expression "expr" to "p". @@ -300,7 +300,7 @@ static __isl_give isl_printer *print_pet_expr(__isl_take isl_printer *p, * associated to its reference identifier in "ref2expr". */ static __isl_give isl_printer *print_op(__isl_take isl_printer *p, - struct pet_expr *expr, __isl_keep isl_id_to_ast_expr *ref2expr) + __isl_keep pet_expr *expr, __isl_keep isl_id_to_ast_expr *ref2expr) { switch (expr->n_arg) { case 1: @@ -342,12 +342,15 @@ static __isl_give isl_printer *print_op(__isl_take isl_printer *p, * associated to its reference identifier in "ref2expr". */ static __isl_give isl_printer *print_pet_expr(__isl_take isl_printer *p, - struct pet_expr *expr, int outer, + __isl_keep pet_expr *expr, int outer, __isl_keep isl_id_to_ast_expr *ref2expr) { int i; switch (expr->type) { + case pet_expr_error: + p = isl_printer_free(p); + break; case pet_expr_int: p = isl_printer_print_val(p, expr->i); break; diff --git a/scan.cc b/scan.cc index aa2a512..5aa650b 100644 --- a/scan.cc +++ b/scan.cc @@ -1577,9 +1577,9 @@ static enum pet_op_type BinaryOperatorKind2pet_op_type(BinaryOperatorKind kind) /* Construct a pet_expr representing a unary operator expression. */ -struct pet_expr *PetScan::extract_expr(UnaryOperator *expr) +__isl_give pet_expr *PetScan::extract_expr(UnaryOperator *expr) { - struct pet_expr *arg; + pet_expr *arg; enum pet_op_type op; op = UnaryOperatorKind2pet_op_type(expr->getOpcode()); @@ -1591,36 +1591,35 @@ struct pet_expr *PetScan::extract_expr(UnaryOperator *expr) arg = extract_expr(expr->getSubExpr()); if (expr->isIncrementDecrementOp() && - arg && arg->type == pet_expr_access) { - mark_write(arg); - arg->acc.read = 1; + pet_expr_get_type(arg) == pet_expr_access) { + arg = mark_write(arg); + arg = pet_expr_access_set_read(arg, 1); } - return pet_expr_new_unary(ctx, op, arg); + return pet_expr_new_unary(op, arg); } /* Mark the given access pet_expr as a write. * If a scalar is being accessed, then mark its value * as unknown in assigned_value. */ -void PetScan::mark_write(struct pet_expr *access) +__isl_give pet_expr *PetScan::mark_write(__isl_take pet_expr *access) { isl_id *id; ValueDecl *decl; - if (!access) - return; - - access->acc.write = 1; - access->acc.read = 0; + access = pet_expr_access_set_write(access, 1); + access = pet_expr_access_set_read(access, 0); - if (!pet_expr_is_scalar_access(access)) - return; + if (!access || !pet_expr_is_scalar_access(access)) + return access; id = pet_expr_access_get_id(access); decl = (ValueDecl *) isl_id_get_user(id); clear_assignment(assigned_value, decl); isl_id_free(id); + + return access; } /* Assign "rhs" to "lhs". @@ -1630,7 +1629,7 @@ void PetScan::mark_write(struct pet_expr *access) * is an affine expression, then keep track of this value in assigned_value * so that we can plug it in when we later come across the same variable. */ -void PetScan::assign(struct pet_expr *lhs, Expr *rhs) +void PetScan::assign(__isl_keep pet_expr *lhs, Expr *rhs) { isl_id *id; ValueDecl *decl; @@ -1664,9 +1663,9 @@ void PetScan::assign(struct pet_expr *lhs, Expr *rhs) * is affine, then keep track of this value in assigned_value * so that we can plug it in when we later come across the same variable. */ -struct pet_expr *PetScan::extract_expr(BinaryOperator *expr) +__isl_give pet_expr *PetScan::extract_expr(BinaryOperator *expr) { - struct pet_expr *lhs, *rhs; + pet_expr *lhs, *rhs; enum pet_op_type op; op = BinaryOperatorKind2pet_op_type(expr->getOpcode()); @@ -1678,16 +1677,17 @@ struct pet_expr *PetScan::extract_expr(BinaryOperator *expr) lhs = extract_expr(expr->getLHS()); rhs = extract_expr(expr->getRHS()); - if (expr->isAssignmentOp() && lhs && lhs->type == pet_expr_access) { - mark_write(lhs); + if (expr->isAssignmentOp() && + pet_expr_get_type(lhs) == pet_expr_access) { + lhs = mark_write(lhs); if (expr->isCompoundAssignmentOp()) - lhs->acc.read = 1; + lhs = pet_expr_access_set_read(lhs, 1); } if (expr->getOpcode() == BO_Assign) assign(lhs, expr->getRHS()); - return pet_expr_new_binary(ctx, op, lhs, rhs); + return pet_expr_new_binary(op, lhs, rhs); } /* Construct a pet_scop with a single statement killing the entire @@ -1699,7 +1699,7 @@ struct pet_scop *PetScan::kill(Stmt *stmt, struct pet_array *array) isl_space *space; isl_multi_pw_aff *index; isl_map *access; - struct pet_expr *expr; + pet_expr *expr; if (!array) return NULL; @@ -1724,7 +1724,7 @@ struct pet_scop *PetScan::extract(DeclStmt *stmt) { Decl *decl; VarDecl *vd; - struct pet_expr *lhs, *rhs, *pe; + pet_expr *lhs, *rhs, *pe; struct pet_scop *scop_decl, *scop; struct pet_array *array; @@ -1748,10 +1748,10 @@ struct pet_scop *PetScan::extract(DeclStmt *stmt) lhs = extract_access_expr(vd); rhs = extract_expr(vd->getInit()); - mark_write(lhs); + lhs = mark_write(lhs); assign(lhs, vd->getInit()); - pe = pet_expr_new_binary(ctx, pet_op_assign, lhs, rhs); + pe = pet_expr_new_binary(pet_op_assign, lhs, rhs); scop = extract(stmt, pe); scop_decl = pet_scop_prefix(scop_decl, 0); @@ -1767,9 +1767,9 @@ struct pet_scop *PetScan::extract(DeclStmt *stmt) * We first try to extract the condition as an affine expression. * If that fails, we construct a pet_expr tree representing the condition. */ -struct pet_expr *PetScan::extract_expr(ConditionalOperator *expr) +__isl_give pet_expr *PetScan::extract_expr(ConditionalOperator *expr) { - struct pet_expr *cond, *lhs, *rhs; + pet_expr *cond, *lhs, *rhs; isl_pw_aff *pa; pa = try_extract_affine(expr->getCond()); @@ -1782,10 +1782,10 @@ struct pet_expr *PetScan::extract_expr(ConditionalOperator *expr) lhs = extract_expr(expr->getTrueExpr()); rhs = extract_expr(expr->getFalseExpr()); - return pet_expr_new_ternary(ctx, cond, lhs, rhs); + return pet_expr_new_ternary(cond, lhs, rhs); } -struct pet_expr *PetScan::extract_expr(ImplicitCastExpr *expr) +__isl_give pet_expr *PetScan::extract_expr(ImplicitCastExpr *expr) { return extract_expr(expr->getSubExpr()); } @@ -1797,7 +1797,7 @@ struct pet_expr *PetScan::extract_expr(ImplicitCastExpr *expr) * as the string representation. Otherwise, we use the pretty * printer to produce a string representation. */ -struct pet_expr *PetScan::extract_expr(FloatingLiteral *expr) +__isl_give pet_expr *PetScan::extract_expr(FloatingLiteral *expr) { double d; string s; @@ -1820,10 +1820,10 @@ struct pet_expr *PetScan::extract_expr(FloatingLiteral *expr) /* Extract an index expression from "expr" and then convert it into * an access pet_expr. */ -struct pet_expr *PetScan::extract_access_expr(Expr *expr) +__isl_give pet_expr *PetScan::extract_access_expr(Expr *expr) { isl_multi_pw_aff *index; - struct pet_expr *pe; + pet_expr *pe; int depth; index = extract_index(expr); @@ -1837,10 +1837,10 @@ struct pet_expr *PetScan::extract_access_expr(Expr *expr) /* Extract an index expression from "decl" and then convert it into * an access pet_expr. */ -struct pet_expr *PetScan::extract_access_expr(ValueDecl *decl) +__isl_give pet_expr *PetScan::extract_access_expr(ValueDecl *decl) { isl_multi_pw_aff *index; - struct pet_expr *pe; + pet_expr *pe; int depth; index = extract_index(decl); @@ -1851,7 +1851,7 @@ struct pet_expr *PetScan::extract_access_expr(ValueDecl *decl) return pe; } -struct pet_expr *PetScan::extract_expr(ParenExpr *expr) +__isl_give pet_expr *PetScan::extract_expr(ParenExpr *expr) { return extract_expr(expr->getSubExpr()); } @@ -1859,10 +1859,10 @@ struct pet_expr *PetScan::extract_expr(ParenExpr *expr) /* Extract an assume statement from the argument "expr" * of a __pencil_assume statement. */ -struct pet_expr *PetScan::extract_assume(Expr *expr) +__isl_give pet_expr *PetScan::extract_assume(Expr *expr) { isl_pw_aff *cond; - struct pet_expr *res; + pet_expr *res; cond = try_extract_affine_condition(expr); if (!cond) { @@ -1873,7 +1873,7 @@ struct pet_expr *PetScan::extract_assume(Expr *expr) index = isl_multi_pw_aff_from_range(index); res = pet_expr_from_index(index); } - return pet_expr_new_unary(ctx, pet_op_assume, res); + return pet_expr_new_unary(pet_op_assume, res); } /* Construct a pet_expr corresponding to the function call argument "expr". @@ -1887,10 +1887,10 @@ struct pet_expr *PetScan::extract_assume(Expr *expr) * to a const type, then the function will perform a read * and that otherwise, it will perform a write. */ -struct pet_expr *PetScan::extract_argument(FunctionDecl *fd, int pos, +__isl_give pet_expr *PetScan::extract_argument(FunctionDecl *fd, int pos, Expr *expr) { - struct pet_expr *res; + pet_expr *res; int is_addr = 0, is_partial = 0; Stmt::StmtClass sc; @@ -1913,7 +1913,8 @@ struct pet_expr *PetScan::extract_argument(FunctionDecl *fd, int pos, sc == Stmt::MemberExprClass) && array_depth(expr->getType().getTypePtr()) > 0) is_partial = 1; - if ((is_addr || is_partial) && res->type == pet_expr_access) { + if ((is_addr || is_partial) && + pet_expr_get_type(res) == pet_expr_access) { ParmVarDecl *parm; if (!fd->hasPrototype()) { report_prototype_required(expr); @@ -1921,11 +1922,11 @@ struct pet_expr *PetScan::extract_argument(FunctionDecl *fd, int pos, } parm = fd->getParamDecl(pos); if (!const_base(parm->getType())) - mark_write(res); + res = mark_write(res); } if (is_addr) - res = pet_expr_new_unary(ctx, pet_op_address_of, res); + res = pet_expr_new_unary(pet_op_address_of, res); return res; } @@ -1934,9 +1935,9 @@ struct pet_expr *PetScan::extract_argument(FunctionDecl *fd, int pos, * In the special case of a "call" to __pencil_assume, * construct an assume expression instead. */ -struct pet_expr *PetScan::extract_expr(CallExpr *expr) +__isl_give pet_expr *PetScan::extract_expr(CallExpr *expr) { - struct pet_expr *res = NULL; + pet_expr *res = NULL; FunctionDecl *fd; string name; unsigned n_arg; @@ -1959,22 +1960,18 @@ struct pet_expr *PetScan::extract_expr(CallExpr *expr) for (int i = 0; i < n_arg; ++i) { Expr *arg = expr->getArg(i); - res->args[i] = PetScan::extract_argument(fd, i, arg); - if (!res->args[i]) - goto error; + res = pet_expr_set_arg(res, i, + PetScan::extract_argument(fd, i, arg)); } return res; -error: - pet_expr_free(res); - return NULL; } /* Construct a pet_expr representing a (C style) cast. */ -struct pet_expr *PetScan::extract_expr(CStyleCastExpr *expr) +__isl_give pet_expr *PetScan::extract_expr(CStyleCastExpr *expr) { - struct pet_expr *arg; + pet_expr *arg; QualType type; arg = extract_expr(expr->getSubExpr()); @@ -1982,19 +1979,19 @@ struct pet_expr *PetScan::extract_expr(CStyleCastExpr *expr) return NULL; type = expr->getTypeAsWritten(); - return pet_expr_new_cast(ctx, type.getAsString().c_str(), arg); + return pet_expr_new_cast(type.getAsString().c_str(), arg); } /* Construct a pet_expr representing an integer. */ -struct pet_expr *PetScan::extract_expr(IntegerLiteral *expr) +__isl_give pet_expr *PetScan::extract_expr(IntegerLiteral *expr) { return pet_expr_new_int(extract_int(expr)); } /* Try and construct a pet_expr representing "expr". */ -struct pet_expr *PetScan::extract_expr(Expr *expr) +__isl_give pet_expr *PetScan::extract_expr(Expr *expr) { switch (expr->getStmtClass()) { case Stmt::UnaryOperatorClass: @@ -3292,7 +3289,7 @@ struct pet_scop *PetScan::extract(CompoundStmt *stmt, bool skip_declarations) * Return the final number of elements in args or -1 if an error has occurred. */ int PetScan::extract_nested(__isl_keep isl_space *space, - int n_arg, struct pet_expr **args, std::map ¶m2pos) + int n_arg, pet_expr **args, std::map ¶m2pos) { int nparam; @@ -3329,32 +3326,35 @@ int PetScan::extract_nested(__isl_keep isl_space *space, } /* For each nested access parameter in the access relations in "expr", - * construct a corresponding pet_expr, place it in expr->args and - * record its position in "param2pos". + * construct a corresponding pet_expr, place it in the arguments of "expr" + * and record its position in "param2pos". * n is the number of nested access parameters. */ -struct pet_expr *PetScan::extract_nested(struct pet_expr *expr, int n, +__isl_give pet_expr *PetScan::extract_nested(__isl_take pet_expr *expr, int n, std::map ¶m2pos) { isl_space *space; + int i; + pet_expr **args; - expr->args = isl_calloc_array(ctx, struct pet_expr *, n); - expr->n_arg = n; - if (!expr->args) - goto error; + args = isl_calloc_array(ctx, pet_expr *, n); + if (!args) + return pet_expr_free(expr); space = pet_expr_access_get_parameter_space(expr); - n = extract_nested(space, 0, expr->args, param2pos); + n = extract_nested(space, 0, args, param2pos); isl_space_free(space); if (n < 0) - goto error; + expr = pet_expr_free(expr); + else + expr = pet_expr_set_n_arg(expr, n); + + for (i = 0; i < n; ++i) + expr = pet_expr_set_arg(expr, i, args[i]); + free(args); - expr->n_arg = n; return expr; -error: - pet_expr_free(expr); - return NULL; } /* Look for parameters in any access relation in "expr" that @@ -3377,7 +3377,7 @@ error: * [[] -> [t_1,...,t_n]] and precompose index expression and access * relations with this function. */ -struct pet_expr *PetScan::resolve_nested(struct pet_expr *expr) +__isl_give pet_expr *PetScan::resolve_nested(__isl_take pet_expr *expr) { int n; int nparam; @@ -3391,15 +3391,15 @@ struct pet_expr *PetScan::resolve_nested(struct pet_expr *expr) if (!expr) return expr; - for (int i = 0; i < expr->n_arg; ++i) { - expr->args[i] = resolve_nested(expr->args[i]); - if (!expr->args[i]) { - pet_expr_free(expr); - return NULL; - } + n = pet_expr_get_n_arg(expr); + for (int i = 0; i < n; ++i) { + pet_expr *arg; + arg = pet_expr_get_arg(expr, i); + arg = resolve_nested(arg); + expr = pet_expr_set_arg(expr, i, arg); } - if (expr->type != pet_expr_access) + if (pet_expr_get_type(expr) != pet_expr_access) return expr; space = pet_expr_access_get_parameter_space(expr); @@ -3437,7 +3437,8 @@ struct pet_expr *PetScan::resolve_nested(struct pet_expr *expr) space = pet_expr_access_get_parameter_space(expr); space = isl_space_set_from_params(space); - space = isl_space_add_dims(space, isl_dim_set, expr->n_arg); + space = isl_space_add_dims(space, isl_dim_set, + pet_expr_get_n_arg(expr)); space = isl_space_wrap(isl_space_from_range(space)); ls = isl_local_space_from_space(isl_space_copy(space)); space = isl_space_from_domain(space); @@ -3567,7 +3568,7 @@ struct pet_scop *PetScan::update_scop_start_end(struct pet_scop *scop, * If "stmt" is an expression statement, then its range does not * include the semicolon, while it should be included in the pet_scop. */ -struct pet_scop *PetScan::extract(Stmt *stmt, struct pet_expr *expr, +struct pet_scop *PetScan::extract(Stmt *stmt, __isl_take pet_expr *expr, __isl_take isl_id *label) { struct pet_stmt *ps; @@ -3710,7 +3711,7 @@ struct pet_scop *PetScan::extract_conditional_assignment(IfStmt *stmt) isl_multi_pw_aff *index; isl_pw_aff *pa; int equal; - struct pet_expr *pe_cond, *pe_then, *pe_else, *pe, *pe_write; + pet_expr *pe_cond, *pe_then, *pe_else, *pe, *pe_write; bool save_nesting = nesting_enabled; if (!options->detect_conditional_assignment) @@ -3749,14 +3750,12 @@ struct pet_scop *PetScan::extract_conditional_assignment(IfStmt *stmt) pe_else = extract_expr(ass_else->getRHS()); pe_else = pet_expr_restrict(pe_else, comp); - pe = pet_expr_new_ternary(ctx, pe_cond, pe_then, pe_else); + pe = pet_expr_new_ternary(pe_cond, pe_then, pe_else); pe_write = pet_expr_from_index_and_depth(write_then, extract_depth(write_then)); - if (pe_write) { - pe_write->acc.write = 1; - pe_write->acc.read = 0; - } - pe = pet_expr_new_binary(ctx, pet_op_assign, pe_write, pe); + pe_write = pet_expr_access_set_write(pe_write, 1); + pe_write = pet_expr_access_set_read(pe_write, 0); + pe = pet_expr_new_binary(pet_op_assign, pe_write, pe); return extract(stmt, pe); } @@ -3767,25 +3766,24 @@ struct pet_scop *PetScan::extract_conditional_assignment(IfStmt *stmt) struct pet_scop *PetScan::extract_non_affine_condition(Expr *cond, int stmt_nr, __isl_take isl_multi_pw_aff *index) { - struct pet_expr *expr, *write; + pet_expr *expr, *write; struct pet_stmt *ps; SourceLocation loc = cond->getLocStart(); int line = PP.getSourceManager().getExpansionLineNumber(loc); write = pet_expr_from_index(index); - if (write) { - write->acc.write = 1; - write->acc.read = 0; - } + write = pet_expr_access_set_write(write, 1); + write = pet_expr_access_set_read(write, 0); expr = extract_expr(cond); expr = resolve_nested(expr); - expr = pet_expr_new_binary(ctx, pet_op_assign, write, expr); + expr = pet_expr_new_binary(pet_op_assign, write, expr); ps = pet_stmt_from_pet_expr(ctx, line, NULL, stmt_nr, expr); return pet_scop_from_pet_stmt(ctx, ps); } extern "C" { - static struct pet_expr *embed_access(struct pet_expr *expr, void *user); + static __isl_give pet_expr *embed_access(__isl_take pet_expr *expr, + void *user); } /* Precompose the access relation and the index expression associated @@ -3794,7 +3792,7 @@ extern "C" { * The initial domain of the access relation and the index expression * is the zero-dimensional domain. */ -static struct pet_expr *embed_access(struct pet_expr *expr, void *user) +static __isl_give pet_expr *embed_access(__isl_take pet_expr *expr, void *user) { isl_multi_aff *ma = (isl_multi_aff *) user; @@ -3804,7 +3802,7 @@ static struct pet_expr *embed_access(struct pet_expr *expr, void *user) /* Precompose all access relations in "expr" with "ma", thereby * embedding them in the domain of "ma". */ -static struct pet_expr *embed(struct pet_expr *expr, +static __isl_give pet_expr *embed(__isl_take pet_expr *expr, __isl_keep isl_multi_aff *ma) { return pet_expr_map_access(expr, &embed_access, ma); @@ -3821,10 +3819,10 @@ struct pet_stmt *PetScan::extract_nested(struct pet_stmt *stmt, int n, int i; isl_space *space; int n_arg; - struct pet_expr **args; + pet_expr **args; n_arg = stmt->n_arg; - args = isl_calloc_array(ctx, struct pet_expr *, n + n_arg); + args = isl_calloc_array(ctx, pet_expr *, n + n_arg); if (!args) goto error; @@ -3997,7 +3995,7 @@ error: /* Given an access expression "expr", is the variable accessed by * "expr" assigned anywhere inside "scop"? */ -static bool is_assigned(pet_expr *expr, pet_scop *scop) +static bool is_assigned(__isl_keep pet_expr *expr, pet_scop *scop) { bool assigned = false; isl_id *id; @@ -4045,7 +4043,7 @@ bool PetScan::is_nested_allowed(__isl_keep isl_pw_aff *pa, pet_scop *scop) nested = (Expr *) isl_id_get_user(id); expr = extract_expr(nested); - allowed = expr && expr->type == pet_expr_access && + allowed = pet_expr_get_type(expr) == pet_expr_access && !is_assigned(expr, scop); pet_expr_free(expr); @@ -4107,7 +4105,7 @@ static bool need_skip(struct pet_scop *scop_then, struct pet_scop *scop_else, /* Construct an affine expression pet_expr that evaluates * to the constant "val". */ -static struct pet_expr *universally(isl_ctx *ctx, int val) +static __isl_give pet_expr *universally(isl_ctx *ctx, int val) { isl_local_space *ls; isl_aff *aff; @@ -4123,7 +4121,7 @@ static struct pet_expr *universally(isl_ctx *ctx, int val) /* Construct an affine expression pet_expr that evaluates * to the constant 1. */ -static struct pet_expr *universally_true(isl_ctx *ctx) +static __isl_give pet_expr *universally_true(isl_ctx *ctx) { return universally(ctx, 1); } @@ -4131,7 +4129,7 @@ static struct pet_expr *universally_true(isl_ctx *ctx) /* Construct an affine expression pet_expr that evaluates * to the constant 0. */ -static struct pet_expr *universally_false(isl_ctx *ctx) +static __isl_give pet_expr *universally_false(isl_ctx *ctx) { return universally(ctx, 0); } @@ -4158,7 +4156,7 @@ static struct pet_scop *extract_skip(PetScan *scan, struct pet_scop *scop_then, struct pet_scop *scop_else, bool have_else, enum pet_skip type) { - struct pet_expr *expr_then, *expr_else, *expr, *expr_skip; + pet_expr *expr_then, *expr_else, *expr, *expr_skip; struct pet_stmt *stmt; struct pet_scop *scop; isl_ctx *ctx = scan->ctx; @@ -4187,13 +4185,11 @@ static struct pet_scop *extract_skip(PetScan *scan, expr_else = universally_false(ctx); expr = pet_expr_from_index(test_index); - expr = pet_expr_new_ternary(ctx, expr, expr_then, expr_else); + expr = pet_expr_new_ternary(expr, expr_then, expr_else); expr_skip = pet_expr_from_index(isl_multi_pw_aff_copy(skip_index)); - if (expr_skip) { - expr_skip->acc.write = 1; - expr_skip->acc.read = 0; - } - expr = pet_expr_new_binary(ctx, pet_op_assign, expr_skip, expr); + expr_skip = pet_expr_access_set_write(expr_skip, 1); + expr_skip = pet_expr_access_set_read(expr_skip, 0); + expr = pet_expr_new_binary(pet_op_assign, expr_skip, expr); stmt = pet_stmt_from_pet_expr(ctx, -1, NULL, scan->n_stmt++, expr); scop = pet_scop_from_pet_stmt(ctx, stmt); @@ -4738,7 +4734,7 @@ static struct pet_scop *extract_skip_seq(PetScan *ps, __isl_take isl_multi_pw_aff *skip_index, struct pet_scop *scop1, struct pet_scop *scop2, enum pet_skip type) { - struct pet_expr *expr1, *expr2, *expr, *expr_skip; + pet_expr *expr1, *expr2, *expr, *expr_skip; struct pet_stmt *stmt; struct pet_scop *scop; isl_ctx *ctx = ps->ctx; @@ -4750,17 +4746,14 @@ static struct pet_scop *extract_skip_seq(PetScan *ps, expr2 = pet_scop_get_skip_expr(scop2, type); pet_scop_reset_skip(scop2, type); - expr2 = pet_expr_filter(expr2, - isl_multi_pw_aff_copy(expr1->acc.index), 0); + expr2 = pet_expr_filter(expr2, pet_expr_access_get_index(expr1), 0); expr = universally_true(ctx); - expr = pet_expr_new_ternary(ctx, expr1, expr, expr2); + expr = pet_expr_new_ternary(expr1, expr, expr2); expr_skip = pet_expr_from_index(isl_multi_pw_aff_copy(skip_index)); - if (expr_skip) { - expr_skip->acc.write = 1; - expr_skip->acc.read = 0; - } - expr = pet_expr_new_binary(ctx, pet_op_assign, expr_skip, expr); + expr_skip = pet_expr_access_set_write(expr_skip, 1); + expr_skip = pet_expr_access_set_read(expr_skip, 0); + expr = pet_expr_new_binary(pet_op_assign, expr_skip, expr); stmt = pet_stmt_from_pet_expr(ctx, -1, NULL, ps->n_stmt++, expr); scop = pet_scop_from_pet_stmt(ctx, stmt); @@ -4872,10 +4865,11 @@ struct pet_scop *pet_skip_info_seq::add(struct pet_scop *scop, int offset) */ struct pet_stmt *PetScan::extract_kill(struct pet_scop *scop) { - struct pet_expr *kill; + pet_expr *kill; struct pet_stmt *stmt; isl_multi_pw_aff *index; isl_map *access; + pet_expr *arg; if (!scop) return NULL; @@ -4887,8 +4881,10 @@ struct pet_stmt *PetScan::extract_kill(struct pet_scop *scop) isl_die(ctx, isl_error_internal, "expecting kill statement", return NULL); - index = isl_multi_pw_aff_copy(stmt->body->args[0]->acc.index); - access = isl_map_copy(stmt->body->args[0]->acc.access); + arg = pet_expr_get_arg(stmt->body, 0); + index = pet_expr_access_get_index(arg); + access = pet_expr_access_get_access(arg); + pet_expr_free(arg); index = isl_multi_pw_aff_reset_tuple_id(index, isl_dim_in); access = isl_map_reset_tuple_id(access, isl_dim_in); kill = pet_expr_kill_from_access_and_index(access, index); diff --git a/scan.h b/scan.h index fda485a..38482a8 100644 --- a/scan.h +++ b/scan.h @@ -97,7 +97,7 @@ struct PetScan { static __isl_give isl_val *extract_unsigned(isl_ctx *ctx, const llvm::APInt &val); private: - void assign(struct pet_expr *lhs, clang::Expr *rhs); + void assign(__isl_keep pet_expr *lhs, clang::Expr *rhs); __isl_give isl_pw_aff *signed_overflow(__isl_take isl_pw_aff *pa, unsigned width); @@ -138,7 +138,7 @@ private: struct pet_scop *update_scop_start_end(struct pet_scop *scop, clang::SourceRange range, bool skip_semi); - struct pet_scop *extract(clang::Stmt *stmt, struct pet_expr *expr, + struct pet_scop *extract(clang::Stmt *stmt, __isl_take pet_expr *expr, __isl_take isl_id *label = NULL); struct pet_stmt *extract_kill(struct pet_scop *scop); @@ -163,33 +163,32 @@ private: struct pet_scop *extract_affine_while(__isl_take isl_pw_aff *pa, clang::Stmt *body); - void mark_write(struct pet_expr *access); - struct pet_expr *extract_assume(clang::Expr *expr); - struct pet_expr *extract_argument(clang::FunctionDecl *fd, int pos, + __isl_give pet_expr *mark_write(__isl_take pet_expr *access); + __isl_give pet_expr *extract_assume(clang::Expr *expr); + __isl_give pet_expr *extract_argument(clang::FunctionDecl *fd, int pos, clang::Expr *expr); - struct pet_expr *extract_expr(clang::Expr *expr); - struct pet_expr *extract_expr(clang::UnaryOperator *expr); - struct pet_expr *extract_expr(clang::BinaryOperator *expr); - struct pet_expr *extract_expr(clang::ImplicitCastExpr *expr); - struct pet_expr *extract_expr(clang::IntegerLiteral *expr); - struct pet_expr *extract_expr(clang::FloatingLiteral *expr); - struct pet_expr *extract_expr(clang::ParenExpr *expr); - struct pet_expr *extract_expr(clang::ConditionalOperator *expr); - struct pet_expr *extract_expr(clang::CallExpr *expr); - struct pet_expr *extract_expr(clang::CStyleCastExpr *expr); + __isl_give pet_expr *extract_expr(clang::Expr *expr); + __isl_give pet_expr *extract_expr(clang::UnaryOperator *expr); + __isl_give pet_expr *extract_expr(clang::BinaryOperator *expr); + __isl_give pet_expr *extract_expr(clang::ImplicitCastExpr *expr); + __isl_give pet_expr *extract_expr(clang::IntegerLiteral *expr); + __isl_give pet_expr *extract_expr(clang::FloatingLiteral *expr); + __isl_give pet_expr *extract_expr(clang::ParenExpr *expr); + __isl_give pet_expr *extract_expr(clang::ConditionalOperator *expr); + __isl_give pet_expr *extract_expr(clang::CallExpr *expr); + __isl_give pet_expr *extract_expr(clang::CStyleCastExpr *expr); int extract_nested(__isl_keep isl_space *space, - int n_arg, struct pet_expr **args, - std::map ¶m2pos); - struct pet_expr *extract_nested(struct pet_expr *expr, int n, + int n_arg, pet_expr **args, std::map ¶m2pos); + __isl_give pet_expr *extract_nested(__isl_take pet_expr *expr, int n, std::map ¶m2pos); struct pet_stmt *extract_nested(struct pet_stmt *stmt, int n, std::map ¶m2pos); - struct pet_expr *resolve_nested(struct pet_expr *expr); + __isl_give pet_expr *resolve_nested(__isl_take pet_expr *expr); struct pet_scop *resolve_nested(struct pet_scop *scop); struct pet_stmt *resolve_nested(struct pet_stmt *stmt); - struct pet_expr *extract_access_expr(clang::Expr *expr); - struct pet_expr *extract_access_expr(clang::ValueDecl *decl); + __isl_give pet_expr *extract_access_expr(clang::Expr *expr); + __isl_give pet_expr *extract_access_expr(clang::ValueDecl *decl); __isl_give isl_multi_pw_aff *extract_index( clang::ArraySubscriptExpr *expr); diff --git a/scop.c b/scop.c index bb00fd2..26c6962 100644 --- a/scop.c +++ b/scop.c @@ -79,7 +79,7 @@ struct pet_scop_ext { * to the statement iteration domain. */ struct pet_stmt *pet_stmt_from_pet_expr(isl_ctx *ctx, int line, - __isl_take isl_id *label, int id, struct pet_expr *expr) + __isl_take isl_id *label, int id, __isl_take pet_expr *expr) { struct pet_stmt *stmt; isl_space *dim; @@ -302,7 +302,7 @@ static __isl_give isl_set *access_extract_context(__isl_keep isl_map *access, * The parameter then has to be valid for the second argument for * non-zero accesses and valid for the third argument for zero accesses. */ -static __isl_give isl_set *expr_extract_context(struct pet_expr *expr, +static __isl_give isl_set *expr_extract_context(__isl_keep pet_expr *expr, __isl_take isl_set *context) { int i; @@ -1300,10 +1300,11 @@ static __isl_give isl_map *embed_access_relation(__isl_take isl_map *access, * into account the mapping "iv_map" from virtual iterator * to real iterator. */ -static struct pet_expr *embed_access(struct pet_expr *expr, void *user) +static __isl_give pet_expr *embed_access(__isl_take pet_expr *expr, void *user) { struct pet_embed_access *data = user; + expr = pet_expr_cow(expr); expr = pet_expr_access_update_domain(expr, data->extend); if (!expr) return NULL; @@ -1322,7 +1323,7 @@ static struct pet_expr *embed_access(struct pet_expr *expr, void *user) * "iv_map" expresses the real iterator in terms of the virtual iterator * "var_id" represents the induction variable. */ -static struct pet_expr *expr_embed(struct pet_expr *expr, +static __isl_give pet_expr *expr_embed(__isl_take pet_expr *expr, __isl_take isl_multi_pw_aff *extend, __isl_take isl_aff *iv_map, __isl_keep isl_id *var_id) { @@ -1723,7 +1724,7 @@ error: /* Insert an argument expression corresponding to "test" in front * of the list of arguments described by *n_arg and *args. */ -static int args_insert_access(unsigned *n_arg, struct pet_expr ***args, +static int args_insert_access(unsigned *n_arg, pet_expr ***args, __isl_keep isl_multi_pw_aff *test) { int i; @@ -1733,12 +1734,12 @@ static int args_insert_access(unsigned *n_arg, struct pet_expr ***args, return -1; if (!*args) { - *args = isl_calloc_array(ctx, struct pet_expr *, 1); + *args = isl_calloc_array(ctx, pet_expr *, 1); if (!*args) return -1; } else { - struct pet_expr **ext; - ext = isl_calloc_array(ctx, struct pet_expr *, 1 + *n_arg); + pet_expr **ext; + ext = isl_calloc_array(ctx, pet_expr *, 1 + *n_arg); if (!ext) return -1; for (i = 0; i < *n_arg; ++i) @@ -1796,7 +1797,7 @@ static __isl_give isl_map *apply_implications(struct pet_scop *scop, * the implications in "scop" needs to contain "test". */ static int implies_filter(struct pet_scop *scop, - __isl_keep isl_map *domain, int pos, struct pet_expr *expr, + __isl_keep isl_map *domain, int pos, __isl_keep pet_expr *expr, __isl_keep isl_map *test, int satisfied) { isl_id *test_id, *arg_id; @@ -2073,7 +2074,7 @@ __isl_give isl_id *pet_scop_get_skip_id(struct pet_scop *scop, /* Return an access pet_expr corresponding to the skip condition * of the given type. */ -struct pet_expr *pet_scop_get_skip_expr(struct pet_scop *scop, +__isl_give pet_expr *pet_scop_get_skip_expr(struct pet_scop *scop, enum pet_skip type) { return pet_expr_from_index(pet_scop_get_skip(scop, type)); @@ -2159,7 +2160,7 @@ error: /* Add all parameters in "expr" to "space" and return the result. */ -static __isl_give isl_space *expr_collect_params(struct pet_expr *expr, +static __isl_give isl_space *expr_collect_params(__isl_keep pet_expr *expr, __isl_take isl_space *space) { int i; @@ -2422,7 +2423,7 @@ struct pet_scop *pet_scop_detect_parameter_accesses(struct pet_scop *scop) * If "tag" is set, then the access relation is tagged with * the corresponding reference identifier. */ -static __isl_give isl_union_map *expr_collect_access(struct pet_expr *expr, +static __isl_give isl_union_map *expr_collect_access(__isl_keep pet_expr *expr, int tag, __isl_take isl_union_map *accesses, __isl_keep isl_set *domain) { isl_map *access; @@ -2446,8 +2447,8 @@ static __isl_give isl_union_map *expr_collect_access(struct pet_expr *expr, * set we currently skip the access completely. If "must" is not set, * we project out the values of the access arguments. */ -static __isl_give isl_union_map *expr_collect_accesses(struct pet_expr *expr, - int read, int write, int must, int tag, +static __isl_give isl_union_map *expr_collect_accesses( + __isl_keep pet_expr *expr, int read, int write, int must, int tag, __isl_take isl_union_map *accesses, __isl_keep isl_set *domain) { int i; @@ -3152,11 +3153,11 @@ error: /* Given an access expression, check if it is data dependent. * If so, set *found and abort the search. */ -static int is_data_dependent(struct pet_expr *expr, void *user) +static int is_data_dependent(__isl_keep pet_expr *expr, void *user) { int *found = user; - if (expr->n_arg) { + if (pet_expr_get_n_arg(expr) > 0) { *found = 1; return -1; } diff --git a/scop.h b/scop.h index 4cdaf20..5ee9414 100644 --- a/scop.h +++ b/scop.h @@ -16,7 +16,7 @@ extern "C" { enum pet_skip { pet_skip_now = 0, pet_skip_later = 1 }; struct pet_stmt *pet_stmt_from_pet_expr(isl_ctx *ctx, int line, - __isl_take isl_id *label, int id, struct pet_expr *expr); + __isl_take isl_id *label, int id, __isl_take pet_expr *expr); void pet_stmt_dump(struct pet_stmt *stmt); void *pet_stmt_free(struct pet_stmt *stmt); @@ -80,7 +80,7 @@ __isl_give isl_set *pet_scop_get_affine_skip_domain(struct pet_scop *scop, enum pet_skip type); __isl_give isl_id *pet_scop_get_skip_id(struct pet_scop *scop, enum pet_skip type); -struct pet_expr *pet_scop_get_skip_expr(struct pet_scop *scop, +__isl_give pet_expr *pet_scop_get_skip_expr(struct pet_scop *scop, enum pet_skip type); void pet_scop_reset_skip(struct pet_scop *scop, enum pet_skip type); diff --git a/scop_plus.cc b/scop_plus.cc index b249f55..8c77654 100644 --- a/scop_plus.cc +++ b/scop_plus.cc @@ -93,7 +93,7 @@ static void collect_sub_arrays(ValueDecl *decl, vector ancestors, * because they are added to the scop of the statement writing * to the scalar. */ -static void access_collect_arrays(struct pet_expr *expr, +static void access_collect_arrays(__isl_keep pet_expr *expr, set > &arrays) { isl_id *id; @@ -124,16 +124,24 @@ static void access_collect_arrays(struct pet_expr *expr, collect_sub_arrays(decl, ancestors, arrays); } -static void expr_collect_arrays(struct pet_expr *expr, +static void expr_collect_arrays(__isl_keep pet_expr *expr, set > &arrays) { + int n; + if (!expr) return; - for (int i = 0; i < expr->n_arg; ++i) - expr_collect_arrays(expr->args[i], arrays); + n = pet_expr_get_n_arg(expr); + for (int i = 0; i < n; ++i) { + pet_expr *arg; + + arg = pet_expr_get_arg(expr, i); + expr_collect_arrays(arg, arrays); + pet_expr_free(arg); + } - if (expr->type == pet_expr_access) + if (pet_expr_get_type(expr) == pet_expr_access) access_collect_arrays(expr, arrays); } diff --git a/value_bounds.c b/value_bounds.c index 2cb9bf8..be43b36 100644 --- a/value_bounds.c +++ b/value_bounds.c @@ -41,7 +41,7 @@ * then intersect the range of "map" with the valid set of values. */ static __isl_give isl_map *access_apply_value_bounds(__isl_take isl_map *map, - struct pet_expr *arg, __isl_keep isl_union_map *value_bounds) + __isl_keep pet_expr *arg, __isl_keep isl_union_map *value_bounds) { isl_id *id; isl_map *vb; @@ -66,7 +66,7 @@ static __isl_give isl_map *access_apply_value_bounds(__isl_take isl_map *map, * type pet_expr_access, bounded by the bounds specified by "value_bounds". */ __isl_give isl_set *pet_value_bounds_apply(__isl_take isl_set *domain, - unsigned n_arg, struct pet_expr **args, + unsigned n_arg, __isl_keep pet_expr **args, __isl_keep isl_union_map *value_bounds) { int i; @@ -79,7 +79,7 @@ __isl_give isl_set *pet_value_bounds_apply(__isl_take isl_set *domain, for (i = 0; i < n_arg; ++i) { isl_map *map_i; - struct pet_expr *arg = args[i]; + pet_expr *arg = args[i]; map_i = isl_map_universe(isl_space_copy(space)); if (arg->type == pet_expr_access) diff --git a/value_bounds.h b/value_bounds.h index c5bc588..fe2a7e8 100644 --- a/value_bounds.h +++ b/value_bounds.h @@ -11,7 +11,7 @@ extern "C" { #endif __isl_give isl_set *pet_value_bounds_apply(__isl_take isl_set *domain, - unsigned n_arg, struct pet_expr **args, + unsigned n_arg, __isl_keep pet_expr **args, __isl_keep isl_union_map *value_bounds); #if defined(__cplusplus) -- 2.11.4.GIT