From 3ab43e11a620268dfe6cac533ed75dab20d6c3cf Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Wed, 5 Feb 2014 10:06:52 +0100 Subject: [PATCH] pet_expr: keep track of type_size The type_size is needed to perform type based wrapping from within a pet_expr. Signed-off-by: Sven Verdoolaege --- expr.c | 52 +++++++++++++++++++++++++++++++++++++++-------- expr.h | 18 +++++++++++++++-- scan.cc | 72 ++++++++++++++++++++++++++++++++++++++++++++++++----------------- scan.h | 2 +- 4 files changed, 114 insertions(+), 30 deletions(-) diff --git a/expr.c b/expr.c index 296fd4d..18d1b84 100644 --- a/expr.c +++ b/expr.c @@ -209,7 +209,9 @@ static __isl_give isl_map *extend_range(__isl_take isl_map *access, int n) return access; } -/* Construct an access pet_expr from an index expression and +/* Construct an access pet_expr from the number of bits needed to + * represent the type of the expression (may be zero if unknown or + * if the type is not an integer) an index expression and * the depth of the accessed array. * By default, the access is considered to be a read access. * @@ -217,11 +219,12 @@ 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. */ -__isl_give pet_expr *pet_expr_from_index_and_depth( +__isl_give pet_expr *pet_expr_from_index_and_depth(int type_size, __isl_take isl_multi_pw_aff *index, int depth) { isl_map *access; int dim; + pet_expr *expr; access = isl_map_from_multi_pw_aff(isl_multi_pw_aff_copy(index)); if (!access) @@ -231,12 +234,17 @@ __isl_give pet_expr *pet_expr_from_index_and_depth( isl_die(isl_map_get_ctx(access), isl_error_internal, "number of indices greater than depth", access = isl_map_free(access)); - if (dim == depth) - return pet_expr_from_access_and_index(access, index); - access = extend_range(access, depth - dim); + if (dim != depth) + access = extend_range(access, depth - dim); - return pet_expr_from_access_and_index(access, index); + expr = pet_expr_from_access_and_index(access, index); + if (!expr) + return NULL; + + expr->type_size = type_size; + + return expr; error: isl_multi_pw_aff_free(index); return NULL; @@ -287,9 +295,11 @@ error: return NULL; } -/* Construct a binary pet_expr that performs "op" on "lhs" and "rhs". +/* Construct a binary pet_expr that performs "op" on "lhs" and "rhs", + * where the result is represented using a type of "type_size" bits + * (may be zero if unknown or if the type is not an integer). */ -__isl_give pet_expr *pet_expr_new_binary(enum pet_op_type op, +__isl_give pet_expr *pet_expr_new_binary(int type_size, enum pet_op_type op, __isl_take pet_expr *lhs, __isl_take pet_expr *rhs) { isl_ctx *ctx; @@ -304,6 +314,7 @@ __isl_give pet_expr *pet_expr_new_binary(enum pet_op_type op, goto error; expr->op = op; + expr->type_size = type_size; expr->args[pet_bin_lhs] = lhs; expr->args[pet_bin_rhs] = rhs; @@ -444,6 +455,7 @@ static __isl_give pet_expr *pet_expr_dup(__isl_keep pet_expr *expr) return NULL; dup = pet_expr_alloc(expr->ctx, expr->type); + dup = pet_expr_set_type_size(dup, expr->type_size); 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])); @@ -1906,6 +1918,30 @@ __isl_give char *pet_expr_double_get_str(__isl_keep pet_expr *expr) return strdup(expr->d.s); } +/* Return the number of bits needed to represent the type of "expr". + * See the description of the type_size field of pet_expr. + */ +int pet_expr_get_type_size(__isl_keep pet_expr *expr) +{ + return expr ? expr->type_size : 0; +} + +/* Replace the number of bits needed to represent the type of "expr" + * by "type_size". + * See the description of the type_size field of pet_expr. + */ +__isl_give pet_expr *pet_expr_set_type_size(__isl_take pet_expr *expr, + int type_size) +{ + expr = pet_expr_cow(expr); + if (!expr) + return NULL; + + expr->type_size = type_size; + + return expr; +} + void pet_expr_dump_with_indent(__isl_keep pet_expr *expr, int indent) { int i; diff --git a/expr.h b/expr.h index c3d5154..674a8b2 100644 --- a/expr.h +++ b/expr.h @@ -14,6 +14,14 @@ extern "C" { * type is valid when type == pet_expr_cast * op is valid otherwise * + * If type_size is not zero, then the expression is of an integer type + * and type_size represents the size of the type in bits. + * If type_size is greater than zero, then the type is unsigned + * and the number of bits is equal to type_size. + * If type_size is less than zero, then the type is signed + * and the number of bits is equal to -type_size. + * type_size may also be zero if the size is (still) unknown. + * * 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 @@ -50,6 +58,8 @@ struct pet_expr { enum pet_expr_type type; + int type_size; + unsigned n_arg; pet_expr **args; @@ -78,7 +88,7 @@ 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_give pet_expr *pet_expr_from_index_and_depth(int type_size, __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); @@ -86,7 +96,7 @@ __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_give pet_expr *pet_expr_new_binary(int type_size, 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); @@ -145,6 +155,10 @@ __isl_give pet_expr *pet_expr_gist(__isl_take pet_expr *expr, __isl_give isl_map *pet_expr_tag_access(__isl_keep pet_expr *expr, __isl_take isl_map *access); +int pet_expr_get_type_size(__isl_keep pet_expr *expr); +__isl_give pet_expr *pet_expr_set_type_size(__isl_take pet_expr *expr, + int type_size); + void pet_expr_dump_with_indent(__isl_keep pet_expr *expr, int indent); #if defined(__cplusplus) diff --git a/scan.cc b/scan.cc index 837b2c7..e5d56b6 100644 --- a/scan.cc +++ b/scan.cc @@ -490,9 +490,31 @@ __isl_give isl_pw_aff *PetScan::extract_affine(ImplicitCastExpr *expr) return extract_affine(expr->getSubExpr()); } -static unsigned get_type_size(ValueDecl *decl) +/* Return the number of bits needed to represent the type "qt", + * if it is an integer type. Otherwise return 0. + * If qt is signed then return the opposite of the number of bits. + */ +static int get_type_size(QualType qt, ASTContext &ast_context) +{ + int size; + + if (!qt->isIntegerType()) + return 0; + + size = ast_context.getIntWidth(qt); + if (!qt->isUnsignedIntegerType()) + size = -size; + + return size; +} + +/* Return the number of bits needed to represent the type of "decl", + * if it is an integer type. Otherwise return 0. + * If qt is signed then return the opposite of the number of bits. + */ +static int get_type_size(ValueDecl *decl) { - return decl->getASTContext().getIntWidth(decl->getType()); + return get_type_size(decl->getType(), decl->getASTContext()); } /* Bound parameter "pos" of "set" to the possible values of "decl". @@ -500,20 +522,23 @@ static unsigned get_type_size(ValueDecl *decl) static __isl_give isl_set *set_parameter_bounds(__isl_take isl_set *set, unsigned pos, ValueDecl *decl) { - unsigned width; + int type_size; isl_ctx *ctx; isl_val *bound; ctx = isl_set_get_ctx(set); - width = get_type_size(decl); - if (decl->getType()->isUnsignedIntegerType()) { + type_size = get_type_size(decl); + if (type_size == 0) + isl_die(ctx, isl_error_invalid, "not an integer type", + return isl_set_free(set)); + if (type_size > 0) { set = isl_set_lower_bound_si(set, isl_dim_param, pos, 0); - bound = isl_val_int_from_ui(ctx, width); + bound = isl_val_int_from_ui(ctx, type_size); bound = isl_val_2exp(bound); bound = isl_val_sub_ui(bound, 1); set = isl_set_upper_bound_val(set, isl_dim_param, pos, bound); } else { - bound = isl_val_int_from_ui(ctx, width - 1); + bound = isl_val_int_from_ui(ctx, -type_size - 1); bound = isl_val_2exp(bound); bound = isl_val_sub_ui(bound, 1); set = isl_set_upper_bound_val(set, isl_dim_param, pos, @@ -1641,6 +1666,7 @@ void PetScan::assign(__isl_keep pet_expr *lhs, Expr *rhs) */ __isl_give pet_expr *PetScan::extract_expr(BinaryOperator *expr) { + int type_size; pet_expr *lhs, *rhs; enum pet_op_type op; @@ -1663,7 +1689,8 @@ __isl_give pet_expr *PetScan::extract_expr(BinaryOperator *expr) if (expr->getOpcode() == BO_Assign) assign(lhs, expr->getRHS()); - return pet_expr_new_binary(op, lhs, rhs); + type_size = get_type_size(expr->getType(), ast_context); + return pet_expr_new_binary(type_size, op, lhs, rhs); } /* Construct a pet_scop with a single statement killing the entire @@ -1698,6 +1725,7 @@ struct pet_scop *PetScan::kill(Stmt *stmt, struct pet_array *array) */ struct pet_scop *PetScan::extract(DeclStmt *stmt) { + int type_size; Decl *decl; VarDecl *vd; pet_expr *lhs, *rhs, *pe; @@ -1727,7 +1755,8 @@ struct pet_scop *PetScan::extract(DeclStmt *stmt) lhs = mark_write(lhs); assign(lhs, vd->getInit()); - pe = pet_expr_new_binary(pet_op_assign, lhs, rhs); + type_size = get_type_size(vd->getType(), ast_context); + pe = pet_expr_new_binary(type_size, pet_op_assign, lhs, rhs); scop = extract(stmt, pe); scop_decl = pet_scop_prefix(scop_decl, 0); @@ -1793,16 +1822,19 @@ __isl_give pet_expr *PetScan::extract_expr(FloatingLiteral *expr) return pet_expr_new_double(ctx, d, s.c_str()); } -/* Convert the index expression "index" into an access pet_expr. +/* Convert the index expression "index" into an access pet_expr of type "qt". */ -__isl_give pet_expr *PetScan::extract_access_expr( +__isl_give pet_expr *PetScan::extract_access_expr(QualType qt, __isl_take isl_multi_pw_aff *index) { pet_expr *pe; int depth; + int type_size; depth = extract_depth(index); - pe = pet_expr_from_index_and_depth(index, depth); + type_size = get_type_size(qt, ast_context); + + pe = pet_expr_from_index_and_depth(type_size, index, depth); return pe; } @@ -1812,7 +1844,7 @@ __isl_give pet_expr *PetScan::extract_access_expr( */ __isl_give pet_expr *PetScan::extract_access_expr(Expr *expr) { - return extract_access_expr(extract_index(expr)); + return extract_access_expr(expr->getType(), extract_index(expr)); } /* Extract an index expression from "decl" and then convert it into @@ -1820,7 +1852,7 @@ __isl_give pet_expr *PetScan::extract_access_expr(Expr *expr) */ __isl_give pet_expr *PetScan::extract_access_expr(ValueDecl *decl) { - return extract_access_expr(extract_index(decl)); + return extract_access_expr(decl->getType(), extract_index(decl)); } __isl_give pet_expr *PetScan::extract_expr(ParenExpr *expr) @@ -3683,6 +3715,7 @@ struct pet_scop *PetScan::extract_conditional_assignment(IfStmt *stmt) isl_multi_pw_aff *index; isl_pw_aff *pa; int equal; + int type_size; pet_expr *pe_cond, *pe_then, *pe_else, *pe, *pe_write; bool save_nesting = nesting_enabled; @@ -3723,11 +3756,12 @@ struct pet_scop *PetScan::extract_conditional_assignment(IfStmt *stmt) pe_else = pet_expr_restrict(pe_else, comp); pe = pet_expr_new_ternary(pe_cond, pe_then, pe_else); - pe_write = pet_expr_from_index_and_depth(write_then, + type_size = get_type_size(ass_then->getType(), ast_context); + pe_write = pet_expr_from_index_and_depth(type_size, write_then, extract_depth(write_then)); 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); + pe = pet_expr_new_binary(type_size, pet_op_assign, pe_write, pe); return extract(stmt, pe); } @@ -3748,7 +3782,7 @@ struct pet_scop *PetScan::extract_non_affine_condition(Expr *cond, int stmt_nr, write = pet_expr_access_set_read(write, 0); expr = extract_expr(cond); expr = resolve_nested(expr); - expr = pet_expr_new_binary(pet_op_assign, write, expr); + expr = pet_expr_new_binary(1, pet_op_assign, write, expr); ps = pet_stmt_from_pet_expr(line, NULL, stmt_nr, expr); return pet_scop_from_pet_stmt(ctx, ps); } @@ -4161,7 +4195,7 @@ static struct pet_scop *extract_skip(PetScan *scan, expr_skip = pet_expr_from_index(isl_multi_pw_aff_copy(skip_index)); 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); + expr = pet_expr_new_binary(1, pet_op_assign, expr_skip, expr); stmt = pet_stmt_from_pet_expr(-1, NULL, scan->n_stmt++, expr); scop = pet_scop_from_pet_stmt(ctx, stmt); @@ -4725,7 +4759,7 @@ static struct pet_scop *extract_skip_seq(PetScan *ps, expr_skip = pet_expr_from_index(isl_multi_pw_aff_copy(skip_index)); 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); + expr = pet_expr_new_binary(1, pet_op_assign, expr_skip, expr); stmt = pet_stmt_from_pet_expr(-1, NULL, ps->n_stmt++, expr); scop = pet_scop_from_pet_stmt(ctx, stmt); diff --git a/scan.h b/scan.h index eabf7dd..bc2a09f 100644 --- a/scan.h +++ b/scan.h @@ -187,7 +187,7 @@ private: __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); - __isl_give pet_expr *extract_access_expr( + __isl_give pet_expr *extract_access_expr(clang::QualType qt, __isl_take isl_multi_pw_aff *index); __isl_give pet_expr *extract_access_expr(clang::Expr *expr); __isl_give pet_expr *extract_access_expr(clang::ValueDecl *decl); -- 2.11.4.GIT