From 09f2ca352f02cfc0408fc87aa6140561d5db75cb Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Sat, 7 Jan 2012 17:31:56 +0100 Subject: [PATCH] pet_scop_from_pet_stmt: extract context constraints from statement expressions Signed-off-by: Sven Verdoolaege --- scop.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/matmul.scop | 18 ++++++------- 2 files changed, 88 insertions(+), 9 deletions(-) diff --git a/scop.c b/scop.c index e9ad878..6653f79 100644 --- a/scop.c +++ b/scop.c @@ -645,6 +645,81 @@ struct pet_scop *pet_scop_empty(isl_ctx *ctx) return scop_alloc(ctx, 0); } +/* Update "context" with respect to the valid parameter values for "access". + */ +static __isl_give isl_set *access_extract_context(__isl_keep isl_map *access, + __isl_take isl_set *context) +{ + context = isl_set_intersect(context, + isl_map_params(isl_map_copy(access))); + return context; +} + +/* Update "context" with respect to the valid parameter values for "expr". + * + * If "expr" represents a ternary operator, then a parameter value + * needs to be valid for the condition and for at least one of the + * remaining two arguments. + * If the condition is an access, then we can be a bit more specific. + * 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, + __isl_take isl_set *context) +{ + int i; + + if (expr->type == pet_expr_ternary) { + isl_set *context1, *context2; + + context = expr_extract_context(expr->args[0], context); + context1 = expr_extract_context(expr->args[1], + isl_set_copy(context)); + context2 = expr_extract_context(expr->args[2], context); + + if (expr->args[0]->type == pet_expr_access && + expr->args[0]->n_arg == 0) { + isl_map *access; + isl_set *zero_set; + + access = isl_map_copy(expr->args[0]->acc.access); + access = isl_map_fix_si(access, isl_dim_out, 0, 0); + zero_set = isl_map_params(access); + context1 = isl_set_subtract(context1, + isl_set_copy(zero_set)); + context2 = isl_set_intersect(context2, zero_set); + } + + context = isl_set_union(context1, context2); + context = isl_set_coalesce(context); + + return context; + } + + for (i = 0; i < expr->n_arg; ++i) + context = expr_extract_context(expr->args[i], context); + + if (expr->type == pet_expr_access) + context = access_extract_context(expr->acc.access, context); + + return context; +} + +/* Update "context" with respect to the valid parameter values for "stmt". + */ +static __isl_give isl_set *stmt_extract_context(struct pet_stmt *stmt, + __isl_take isl_set *context) +{ + int i; + + for (i = 0; i < stmt->n_arg; ++i) + context = expr_extract_context(stmt->args[i], context); + + context = expr_extract_context(stmt->body, context); + + return context; +} + /* Construct a pet_scop that contains the given pet_stmt. */ struct pet_scop *pet_scop_from_pet_stmt(isl_ctx *ctx, struct pet_stmt *stmt) @@ -656,6 +731,10 @@ struct pet_scop *pet_scop_from_pet_stmt(isl_ctx *ctx, struct pet_stmt *stmt) scop = scop_alloc(ctx, 1); + scop->context = stmt_extract_context(stmt, scop->context); + if (!scop->context) + goto error; + scop->stmts[0] = stmt; return scop; diff --git a/tests/matmul.scop b/tests/matmul.scop index 89daf7e..a504972 100644 --- a/tests/matmul.scop +++ b/tests/matmul.scop @@ -1,20 +1,20 @@ -context: '[N, K] -> { : K >= 0 and N >= 0 and N <= 2147483647 and K <= 2147483647 - }' +context: '[N, K, M] -> { : K >= 0 and N >= 0 and N <= 2147483647 and K <= 2147483647 + and M <= 2147483647 and M >= -2147483648 }' arrays: - context: '[K] -> { : K >= 0 }' - extent: '[K] -> { A[i0, i1] : i0 >= 0 and i1 >= 0 and i1 <= -1 + K }' + extent: '[N, K, M] -> { A[i0, i1] : i1 >= 0 and i0 >= 0 and i1 <= -1 + K }' element_type: float - context: '[N] -> { : N >= 0 }' - extent: '[N] -> { B[i0, i1] : i0 >= 0 and i1 >= 0 and i1 <= -1 + N }' + extent: '[N, K, M] -> { B[i0, i1] : i1 >= 0 and i1 <= -1 + N and i0 >= 0 }' element_type: float - context: '[N] -> { : N >= 0 }' - extent: '[N] -> { C[i0, i1] : i0 >= 0 and i1 >= 0 and i1 <= -1 + N }' + extent: '[N, K, M] -> { C[i0, i1] : i1 >= 0 and i1 <= -1 + N and i0 >= 0 }' element_type: float live_out: 1 statements: - line: 9 - domain: '[N, K, M] -> { S_0[i, j] : j >= 0 and j <= -1 + N and i >= 0 and i <= -1 - + M }' + domain: '[N, K, M] -> { S_0[i, j] : i >= 0 and i <= -1 + M and j >= 0 and j <= -1 + + N }' schedule: '[N, M] -> { S_0[i, j] -> [0, i, j, 0] }' body: type: binary @@ -29,8 +29,8 @@ statements: read: 1 write: 0 - line: 11 - domain: '[N, K, M] -> { S_1[i, j, k] : j <= -1 + N and k <= -1 + K and i >= 0 and - i <= -1 + M and k >= 0 and j >= 0 }' + domain: '[N, K, M] -> { S_1[i, j, k] : k >= 0 and j >= 0 and j <= -1 + N and k <= + -1 + K and i >= 0 and i <= -1 + M }' schedule: '[K, N, M] -> { S_1[i, j, k] -> [0, i, j, 1, k] }' body: type: binary -- 2.11.4.GIT