From f843c34c9cd74830a5e17e301551fa9e9a2a5644 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Tue, 5 Feb 2013 14:37:13 +0100 Subject: [PATCH] support (C style) casts in statements Requested-by: Riyadh Baghdadi Signed-off-by: Sven Verdoolaege --- emit.c | 6 ++++++ include/pet.h | 3 +++ parse.c | 3 +++ pet_check_code.c | 1 + scan.cc | 17 +++++++++++++++++ scan.h | 1 + scop.c | 43 +++++++++++++++++++++++++++++++++++++++++++ scop.h | 2 ++ tests/cast.c | 9 +++++++++ tests/cast.scop | 29 +++++++++++++++++++++++++++++ 10 files changed, 114 insertions(+) create mode 100644 tests/cast.c create mode 100644 tests/cast.scop diff --git a/emit.c b/emit.c index f9ea059..fdac34c 100644 --- a/emit.c +++ b/emit.c @@ -266,6 +266,12 @@ static int emit_expr(yaml_emitter_t *emitter, struct pet_expr *expr) if (emit_string(emitter, expr->name) < 0) return -1; break; + case pet_expr_cast: + if (emit_string(emitter, "type_name") < 0) + return -1; + if (emit_string(emitter, expr->type_name) < 0) + return -1; + break; } if (expr->n_arg > 0) { diff --git a/include/pet.h b/include/pet.h index 557e055..023f6b1 100644 --- a/include/pet.h +++ b/include/pet.h @@ -27,6 +27,7 @@ int pet_options_get_signed_overflow(isl_ctx *ctx); enum pet_expr_type { pet_expr_access, pet_expr_call, + pet_expr_cast, pet_expr_double, pet_expr_unary, pet_expr_binary, @@ -85,6 +86,7 @@ enum pet_ter_arg_type { /* d is valid when type == pet_expr_double * 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 * * acc.access usually maps an iteration space to a data space. @@ -115,6 +117,7 @@ struct pet_expr { } acc; enum pet_op_type op; char *name; + char *type_name; struct { double val; char *s; diff --git a/parse.c b/parse.c index 7283dfa..1688a51 100644 --- a/parse.c +++ b/parse.c @@ -265,6 +265,9 @@ static struct pet_expr *extract_expr(isl_ctx *ctx, yaml_document_t *document, if (!strcmp((char *) key->data.scalar.value, "name")) expr->name = extract_string(ctx, document, value); + if (!strcmp((char *) key->data.scalar.value, "type_name")) + expr->type_name = extract_string(ctx, document, value); + if (!strcmp((char *) key->data.scalar.value, "arguments")) expr = extract_arguments(ctx, document, value, expr); if (!expr) diff --git a/pet_check_code.c b/pet_check_code.c index e56d6b4..c524bf3 100644 --- a/pet_check_code.c +++ b/pet_check_code.c @@ -245,6 +245,7 @@ static __isl_give isl_pw_aff *expr_extract_pw_aff(struct pet_expr *expr, pa1 = expr_extract_pw_aff(expr->args[1], assignments); pa2 = expr_extract_pw_aff(expr->args[2], assignments); return isl_pw_aff_cond(pa, pa1, pa2); + case pet_expr_cast: case pet_expr_double: assert(0); } diff --git a/scan.cc b/scan.cc index 202e57c..20c3066 100644 --- a/scan.cc +++ b/scan.cc @@ -1672,6 +1672,21 @@ error: return NULL; } +/* Construct a pet_expr representing a (C style) cast. + */ +struct pet_expr *PetScan::extract_expr(CStyleCastExpr *expr) +{ + struct pet_expr *arg; + QualType type; + + arg = extract_expr(expr->getSubExpr()); + if (!arg) + return NULL; + + type = expr->getTypeAsWritten(); + return pet_expr_new_cast(ctx, type.getAsString().c_str(), arg); +} + /* Try and onstruct a pet_expr representing "expr". */ struct pet_expr *PetScan::extract_expr(Expr *expr) @@ -1696,6 +1711,8 @@ struct pet_expr *PetScan::extract_expr(Expr *expr) return extract_expr(cast(expr)); case Stmt::CallExprClass: return extract_expr(cast(expr)); + case Stmt::CStyleCastExprClass: + return extract_expr(cast(expr)); default: unsupported(expr); } diff --git a/scan.h b/scan.h index 0c1e2c6..d606e22 100644 --- a/scan.h +++ b/scan.h @@ -148,6 +148,7 @@ private: 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); int extract_nested(__isl_keep isl_space *space, int n_arg, struct pet_expr **args, diff --git a/scop.c b/scop.c index 471125a..b74cb49 100644 --- a/scop.c +++ b/scop.c @@ -42,6 +42,7 @@ static char *type_str[] = { [pet_expr_access] = "access", [pet_expr_call] = "call", + [pet_expr_cast] = "cast", [pet_expr_double] = "double", [pet_expr_unary] = "unary", [pet_expr_binary] = "binary", @@ -280,6 +281,36 @@ struct pet_expr *pet_expr_new_call(isl_ctx *ctx, const char *name, return expr; } +/* 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) +{ + struct pet_expr *expr; + + if (!arg) + return NULL; + + expr = isl_alloc_type(ctx, struct pet_expr); + 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) + goto error; + + expr->args[0] = arg; + + return expr; +error: + pet_expr_free(arg); + pet_expr_free(expr); + return NULL; +} + /* Construct a pet_expr that represents the double "d". */ struct pet_expr *pet_expr_new_double(isl_ctx *ctx, double val, const char *s) @@ -317,6 +348,9 @@ void *pet_expr_free(struct pet_expr *expr) case pet_expr_call: free(expr->name); break; + case pet_expr_cast: + free(expr->type_name); + break; case pet_expr_double: free(expr->d.s); break; @@ -372,6 +406,11 @@ static void expr_dump(struct pet_expr *expr, int indent) for (i = 0; i < expr->n_arg; ++i) expr_dump(expr->args[i], indent + 2); break; + case pet_expr_cast: + fprintf(stderr, "(%s)\n", expr->type_name); + for (i = 0; i < expr->n_arg; ++i) + expr_dump(expr->args[i], indent + 2); + break; } } @@ -442,6 +481,10 @@ int pet_expr_is_equal(struct pet_expr *expr1, struct pet_expr *expr2) if (strcmp(expr1->name, expr2->name)) return 0; break; + case pet_expr_cast: + if (strcmp(expr1->type_name, expr2->type_name)) + return 0; + break; } return 1; diff --git a/scop.h b/scop.h index 4b5e34c..7e42cd0 100644 --- a/scop.h +++ b/scop.h @@ -29,6 +29,8 @@ 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); void pet_expr_dump(struct pet_expr *expr); void *pet_expr_free(struct pet_expr *expr); diff --git a/tests/cast.c b/tests/cast.c new file mode 100644 index 0000000..e3ca3d8 --- /dev/null +++ b/tests/cast.c @@ -0,0 +1,9 @@ +void foo() +{ + int a; + char c = 'a'; + +#pragma scop + a = (int) c; +#pragma endscop +} diff --git a/tests/cast.scop b/tests/cast.scop new file mode 100644 index 0000000..9536bb3 --- /dev/null +++ b/tests/cast.scop @@ -0,0 +1,29 @@ +context: '{ : }' +arrays: +- context: '{ : }' + extent: '{ a[] }' + element_type: int + element_size: 4 +- context: '{ : }' + extent: '{ c[] }' + element_type: char + element_size: 1 +statements: +- line: 7 + domain: '{ S_0[] }' + schedule: '{ S_0[] -> [0] }' + body: + type: binary + operation: = + arguments: + - type: access + relation: '{ S_0[] -> a[] }' + read: 0 + write: 1 + - type: cast + type_name: int + arguments: + - type: access + relation: '{ S_0[] -> c[] }' + read: 1 + write: 0 -- 2.11.4.GIT