From 2e80169567bb940c933117249ab0f9b6b8b8fdb8 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Mon, 10 Feb 2014 12:52:46 +0100 Subject: [PATCH] extract enum constants as their integer values Prior to this commit, enum constants were extracted as symbolic constants. This could lead to inefficiencies since we would lose any information on the relative order of these constants, especially whether or not they are equal to each other. Extract them as their integer values instead. Requested-by: Uday R Bondhugula Signed-off-by: Sven Verdoolaege --- scan.cc | 40 +++++++++++++++++++++++++++++++++++++--- scan.h | 1 + tests/enum.c | 15 +++++++++++++++ tests/enum.scop | 24 ++++++++++++++++++++++++ 4 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 tests/enum.c create mode 100644 tests/enum.scop diff --git a/scan.cc b/scan.cc index 9a3d3db..7bff664 100644 --- a/scan.cc +++ b/scan.cc @@ -456,6 +456,9 @@ static int extract_depth(__isl_keep pet_expr *expr) /* Construct a pet_expr representing an index expression for an access * to the variable referenced by "expr". + * + * If "expr" references an enum constant, then return an integer expression + * instead, representing the value of the enum constant. */ __isl_give pet_expr *PetScan::extract_index_expr(DeclRefExpr *expr) { @@ -464,12 +467,20 @@ __isl_give pet_expr *PetScan::extract_index_expr(DeclRefExpr *expr) /* Construct a pet_expr representing an index expression for an access * to the variable "decl". + * + * If "decl" is an enum constant, then we return an integer expression + * instead, representing the value of the enum constant. */ __isl_give pet_expr *PetScan::extract_index_expr(ValueDecl *decl) { - isl_id *id = create_decl_id(ctx, decl); - isl_space *space = isl_space_alloc(ctx, 0, 0, 0); + isl_id *id; + isl_space *space; + if (isa(decl)) + return extract_expr(cast(decl)); + + id = create_decl_id(ctx, decl); + space = isl_space_alloc(ctx, 0, 0, 0); space = isl_space_set_tuple_id(space, isl_dim_out, id); return pet_expr_from_index(isl_multi_pw_aff_zero(space)); @@ -477,6 +488,9 @@ __isl_give pet_expr *PetScan::extract_index_expr(ValueDecl *decl) /* Construct a pet_expr representing the index expression "expr" * Return NULL on error. + * + * If "expr" is a reference to an enum constant, then return + * an integer expression instead, representing the value of the enum constant. */ __isl_give pet_expr *PetScan::extract_index_expr(Expr *expr) { @@ -726,10 +740,20 @@ __isl_give pet_expr *PetScan::extract_access_expr(QualType qt, /* Extract an index expression from "expr" and then convert it into * an access pet_expr. + * + * If "expr" is a reference to an enum constant, then return + * an integer expression instead, representing the value of the enum constant. */ __isl_give pet_expr *PetScan::extract_access_expr(Expr *expr) { - return extract_access_expr(expr->getType(), extract_index_expr(expr)); + pet_expr *index; + + index = extract_index_expr(expr); + + if (pet_expr_get_type(index) == pet_expr_int) + return index; + + return extract_access_expr(expr->getType(), index); } /* Extract an index expression from "decl" and then convert it into @@ -866,6 +890,16 @@ __isl_give pet_expr *PetScan::extract_expr(IntegerLiteral *expr) return pet_expr_new_int(extract_int(expr)); } +/* Construct a pet_expr representing the integer enum constant "ecd". + */ +__isl_give pet_expr *PetScan::extract_expr(EnumConstantDecl *ecd) +{ + isl_val *v; + const llvm::APSInt &init = ecd->getInitVal(); + v = ::extract_int(ctx, init.isSigned(), init); + return pet_expr_new_int(v); +} + /* Try and construct a pet_expr representing "expr". */ __isl_give pet_expr *PetScan::extract_expr(Expr *expr) diff --git a/scan.h b/scan.h index a9d93c1..8d5cfa9 100644 --- a/scan.h +++ b/scan.h @@ -138,6 +138,7 @@ private: __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::EnumConstantDecl *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); diff --git a/tests/enum.c b/tests/enum.c new file mode 100644 index 0000000..e7b503c --- /dev/null +++ b/tests/enum.c @@ -0,0 +1,15 @@ +enum type { + type_a = 0, + type_b, + type_c, + type_last +}; + +void foo() +{ + int a[type_last]; + +#pragma scop + a[type_b] = 5; +#pragma endscop +} diff --git a/tests/enum.scop b/tests/enum.scop new file mode 100644 index 0000000..5ec4d72 --- /dev/null +++ b/tests/enum.scop @@ -0,0 +1,24 @@ +start: 91 +end: 136 +context: '{ : }' +arrays: +- context: '{ : }' + extent: '{ a[i0] : i0 >= 0 and i0 <= 2 }' + element_type: int + element_size: 4 +statements: +- line: 13 + domain: '{ S_0[] }' + schedule: '{ S_0[] -> [0] }' + body: + type: op + operation: = + arguments: + - type: access + relation: '{ S_0[] -> a[1] }' + index: '{ S_0[] -> a[(1)] }' + reference: __pet_ref_0 + read: 0 + write: 1 + - type: int + value: 5 -- 2.11.4.GIT