From d1cf3bf14c540af05df3ef55d5cbee233d9a2525 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Fri, 9 Mar 2012 11:24:26 +0100 Subject: [PATCH] PetScan::resolve_nested: detect and remove duplicate filters Signed-off-by: Sven Verdoolaege --- scan.cc | 45 ++++++++++++++++++++++++++++++++++++++++++++ tests/dynamic_condition.c | 16 ++++++++++++++++ tests/dynamic_condition.scop | 44 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+) create mode 100644 tests/dynamic_condition.c create mode 100644 tests/dynamic_condition.scop diff --git a/scan.cc b/scan.cc index 6069826..2e4cca9 100644 --- a/scan.cc +++ b/scan.cc @@ -3024,6 +3024,50 @@ error: return NULL; } +/* Check whether any of the arguments i of "stmt" starting at position "n" + * is equal to one of the first "n" arguments j. + * If so, combine the constraints on arguments i and j and remove + * argument i. + */ +static struct pet_stmt *remove_duplicate_arguments(struct pet_stmt *stmt, int n) +{ + int i, j; + isl_map *map; + + if (!stmt) + return NULL; + if (n == 0) + return stmt; + if (n == stmt->n_arg) + return stmt; + + map = isl_set_unwrap(stmt->domain); + + for (i = stmt->n_arg - 1; i >= n; --i) { + for (j = 0; j < n; ++j) + if (pet_expr_is_equal(stmt->args[i], stmt->args[j])) + break; + if (j >= n) + continue; + + map = isl_map_equate(map, isl_dim_out, i, isl_dim_out, j); + map = isl_map_project_out(map, isl_dim_out, i, 1); + + pet_expr_free(stmt->args[i]); + for (j = i; j + 1 < stmt->n_arg; ++j) + stmt->args[j] = stmt->args[j + 1]; + stmt->n_arg--; + } + + stmt->domain = isl_map_wrap(map); + if (!stmt->domain) + goto error; + return stmt; +error: + pet_stmt_free(stmt); + return NULL; +} + /* Look for parameters in the iteration domain of "stmt" that * refer to nested accesses. In particular, these are * parameters with no name. @@ -3094,6 +3138,7 @@ struct pet_stmt *PetScan::resolve_nested(struct pet_stmt *stmt) isl_map_free(map); stmt = remove_nested_parameters(stmt); + stmt = remove_duplicate_arguments(stmt, n); return stmt; error: diff --git a/tests/dynamic_condition.c b/tests/dynamic_condition.c new file mode 100644 index 0000000..ca8e5b2 --- /dev/null +++ b/tests/dynamic_condition.c @@ -0,0 +1,16 @@ +int f(void); + +void foo() +{ + int i, j, a[100]; + +#pragma scop + for (i = 0; i < 100; ++i) { + j = f(); + if (j <= 1) { + if (j >= 0) + a[i] = i; + } + } +#pragma endscop +} diff --git a/tests/dynamic_condition.scop b/tests/dynamic_condition.scop new file mode 100644 index 0000000..d2977a5 --- /dev/null +++ b/tests/dynamic_condition.scop @@ -0,0 +1,44 @@ +context: '{ : }' +arrays: +- context: '{ : }' + extent: '{ j[] }' + element_type: int + element_size: 4 +- context: '{ : }' + extent: '{ a[i0] : i0 >= 0 and i0 <= 99 }' + element_type: int + element_size: 4 +statements: +- line: 9 + domain: '{ S_0[i] : i >= 0 and i <= 99 }' + schedule: '{ S_0[i] -> [0, i, 0] }' + body: + type: binary + operation: = + arguments: + - type: access + relation: '{ S_0[i] -> j[] }' + read: 0 + write: 1 + - type: call + name: f +- line: 12 + domain: '{ [S_3[i] -> [j]] : j >= 0 and j <= 1 and i >= 0 and i <= 99 }' + schedule: '{ S_3[i] -> [0, i, 1, 0] }' + body: + type: binary + operation: = + arguments: + - type: access + relation: '{ S_3[i] -> a[i] }' + read: 0 + write: 1 + - type: access + relation: '{ S_3[i] -> [i] }' + read: 1 + write: 0 + arguments: + - type: access + relation: '{ S_3[i] -> j[] }' + read: 1 + write: 0 -- 2.11.4.GIT