From ef74e2ba382eecfea8d7ef44d54add99c3fd4d92 Mon Sep 17 00:00:00 2001 From: Sebastian Pop Date: Thu, 21 Jul 2011 22:57:59 +0000 Subject: [PATCH] Infer types based on lb and ub. 2011-07-21 Sebastian Pop PR middle-end/47654 PR middle-end/49649 * graphite-clast-to-gimple.c (type_for_clast_term): Pass v1 and v2 in parameter. Initialize v1 and v2 based on the values returned by clast_name_to_lb_ub. (type_for_clast_red): Pass v1 and v2 in parameter, and set their values. (type_for_clast_bin): Same. (type_for_clast_expr): Same. (type_for_clast_eq): Update calls to type_for_clast_expr. (type_for_clast_for): Same. (build_iv_mapping): Same. * graphite-ppl.h (value_min): New. * gcc.dg/graphite/run-id-pr47654.c: New. From-SVN: r176605 --- gcc/ChangeLog | 16 ++ gcc/graphite-clast-to-gimple.c | 184 ++++++++++++++---- gcc/graphite-ppl.h | 11 ++ gcc/testsuite/ChangeLog | 6 + .../gcc.dg/graphite/run-id-pr47654.c | 24 +++ 5 files changed, 204 insertions(+), 37 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/graphite/run-id-pr47654.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ea4db8c36c2..9cfa21b5ef7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2011-07-21 Sebastian Pop + + PR middle-end/47654 + PR middle-end/49649 + * graphite-clast-to-gimple.c (type_for_clast_term): Pass v1 and v2 + in parameter. Initialize v1 and v2 based on the values returned + by clast_name_to_lb_ub. + (type_for_clast_red): Pass v1 and v2 in parameter, and set their + values. + (type_for_clast_bin): Same. + (type_for_clast_expr): Same. + (type_for_clast_eq): Update calls to type_for_clast_expr. + (type_for_clast_for): Same. + (build_iv_mapping): Same. + * graphite-ppl.h (value_min): New. + 2011-07-21 Sebastian Pop * graphite-clast-to-gimple.c (type_for_interval): Generate signed diff --git a/gcc/graphite-clast-to-gimple.c b/gcc/graphite-clast-to-gimple.c index 9cd27372bb6..ddf6d3d7d27 100644 --- a/gcc/graphite-clast-to-gimple.c +++ b/gcc/graphite-clast-to-gimple.c @@ -488,79 +488,164 @@ type_for_value (mpz_t val) return type_for_interval (val, val); } -/* Return the type for the clast_term T used in STMT. */ +/* Return the type for the clast_term T. Initializes V1 and V2 to the + bounds of the term. */ static tree -type_for_clast_term (struct clast_term *t, ivs_params_p ip) +type_for_clast_term (struct clast_term *t, ivs_params_p ip, mpz_t v1, mpz_t v2) { + clast_name_p name = t->var; + bool found = false; + gcc_assert (t->expr.type == clast_expr_term); - if (!t->var) - return type_for_value (t->val); + if (!name) + { + mpz_set (v1, t->val); + mpz_set (v2, t->val); + return type_for_value (t->val); + } + + if (ip->params && ip->params_index) + found = clast_name_to_lb_ub (name, ip->params_index, v1, v2); - return TREE_TYPE (clast_name_to_gcc (t->var, ip)); + if (!found) + { + gcc_assert (*(ip->newivs) && ip->newivs_index); + found = clast_name_to_lb_ub (name, ip->newivs_index, v1, v2); + gcc_assert (found); + } + + mpz_mul (v1, v1, t->val); + mpz_mul (v2, v2, t->val); + + return TREE_TYPE (clast_name_to_gcc (name, ip)); } static tree -type_for_clast_expr (struct clast_expr *, ivs_params_p); +type_for_clast_expr (struct clast_expr *, ivs_params_p, mpz_t, mpz_t); -/* Return the type for the clast_reduction R used in STMT. */ +/* Return the type for the clast_reduction R. Initializes V1 and V2 + to the bounds of the reduction expression. */ static tree -type_for_clast_red (struct clast_reduction *r, ivs_params_p ip) +type_for_clast_red (struct clast_reduction *r, ivs_params_p ip, + mpz_t v1, mpz_t v2) { int i; - tree type = NULL_TREE; + tree type = type_for_clast_expr (r->elts[0], ip, v1, v2); + mpz_t b1, b2, m1, m2; if (r->n == 1) - return type_for_clast_expr (r->elts[0], ip); - - switch (r->type) - { - case clast_red_sum: - case clast_red_min: - case clast_red_max: - type = type_for_clast_expr (r->elts[0], ip); - for (i = 1; i < r->n; i++) - type = max_precision_type - (type, type_for_clast_expr (r->elts[i], ip)); + return type; - return type; + mpz_init (b1); + mpz_init (b2); + mpz_init (m1); + mpz_init (m2); - default: - break; + for (i = 1; i < r->n; i++) + { + tree t = type_for_clast_expr (r->elts[i], ip, b1, b2); + type = max_precision_type (type, t); + + switch (r->type) + { + case clast_red_sum: + value_min (m1, v1, v2); + value_min (m2, b1, b2); + mpz_add (v1, m1, m2); + + value_max (m1, v1, v2); + value_max (m2, b1, b2); + mpz_add (v2, m1, m2); + break; + + case clast_red_min: + value_min (v1, v1, v2); + value_min (v2, b1, b2); + break; + + case clast_red_max: + value_max (v1, v1, v2); + value_max (v2, b1, b2); + break; + + default: + gcc_unreachable (); + break; + } } - gcc_unreachable (); - return NULL_TREE; + mpz_clear (b1); + mpz_clear (b2); + mpz_clear (m1); + mpz_clear (m2); + + /* Return a type that can represent the result of the reduction. */ + return max_precision_type (type, type_for_interval (v1, v2)); } /* Return the type for the clast_binary B used in STMT. */ static tree -type_for_clast_bin (struct clast_binary *b, ivs_params_p ip) +type_for_clast_bin (struct clast_binary *b, ivs_params_p ip, mpz_t v1, mpz_t v2) { - tree l = type_for_clast_expr ((struct clast_expr *) b->LHS, ip); + mpz_t one; + tree l = type_for_clast_expr ((struct clast_expr *) b->LHS, ip, v1, v2); tree r = type_for_value (b->RHS); - return max_precision_type (l, r); + tree type = max_precision_type (l, r); + + switch (b->type) + { + case clast_bin_fdiv: + mpz_mdiv (v1, v1, b->RHS); + mpz_mdiv (v2, v2, b->RHS); + break; + + case clast_bin_cdiv: + mpz_mdiv (v1, v1, b->RHS); + mpz_mdiv (v2, v2, b->RHS); + mpz_init (one); + mpz_add (v1, v1, one); + mpz_add (v2, v2, one); + mpz_clear (one); + break; + + case clast_bin_div: + mpz_div (v1, v1, b->RHS); + mpz_div (v2, v2, b->RHS); + break; + + case clast_bin_mod: + mpz_mod (v1, v1, b->RHS); + mpz_mod (v2, v2, b->RHS); + break; + + default: + gcc_unreachable (); + } + + /* Return a type that can represent the result of the reduction. */ + return max_precision_type (type, type_for_interval (v1, v2)); } /* Returns the type for the CLAST expression E when used in statement STMT. */ static tree -type_for_clast_expr (struct clast_expr *e, ivs_params_p ip) +type_for_clast_expr (struct clast_expr *e, ivs_params_p ip, mpz_t v1, mpz_t v2) { switch (e->type) { case clast_expr_term: - return type_for_clast_term ((struct clast_term *) e, ip); + return type_for_clast_term ((struct clast_term *) e, ip, v1, v2); case clast_expr_red: - return type_for_clast_red ((struct clast_reduction *) e, ip); + return type_for_clast_red ((struct clast_reduction *) e, ip, v1, v2); case clast_expr_bin: - return type_for_clast_bin ((struct clast_binary *) e, ip); + return type_for_clast_bin ((struct clast_binary *) e, ip, v1, v2); default: gcc_unreachable (); @@ -574,8 +659,17 @@ type_for_clast_expr (struct clast_expr *e, ivs_params_p ip) static tree type_for_clast_eq (struct clast_equation *cleq, ivs_params_p ip) { - tree l = type_for_clast_expr (cleq->LHS, ip); - tree r = type_for_clast_expr (cleq->RHS, ip); + mpz_t v1, v2; + tree l, r; + + mpz_init (v1); + mpz_init (v2); + + l = type_for_clast_expr (cleq->LHS, ip, v1, v2); + r = type_for_clast_expr (cleq->RHS, ip, v1, v2); + + mpz_clear (v1); + mpz_clear (v2); return max_precision_type (l, r); } @@ -727,8 +821,17 @@ clast_get_body_of_loop (struct clast_stmt *stmt) static tree type_for_clast_for (struct clast_for *stmt_for, ivs_params_p ip) { - tree lb_type = type_for_clast_expr (stmt_for->LB, ip); - tree ub_type = type_for_clast_expr (stmt_for->UB, ip); + mpz_t v1, v2; + tree lb_type, ub_type; + + mpz_init (v1); + mpz_init (v2); + + lb_type = type_for_clast_expr (stmt_for->LB, ip, v1, v2); + ub_type = type_for_clast_expr (stmt_for->UB, ip, v1, v2); + + mpz_clear (v1); + mpz_clear (v2); return max_precision_type (lb_type, ub_type); } @@ -784,17 +887,24 @@ build_iv_mapping (VEC (tree, heap) *iv_map, struct clast_user_stmt *user_stmt, CloogStatement *cs = user_stmt->statement; poly_bb_p pbb = (poly_bb_p) cloog_statement_usr (cs); gimple_bb_p gbb = PBB_BLACK_BOX (pbb); + mpz_t v1, v2; + + mpz_init (v1); + mpz_init (v2); for (t = user_stmt->substitutions; t; t = t->next, depth++) { struct clast_expr *expr = (struct clast_expr *) ((struct clast_assignment *)t)->RHS; - tree type = type_for_clast_expr (expr, ip); + tree type = type_for_clast_expr (expr, ip, v1, v2); tree new_name = clast_to_gcc_expression (type, expr, ip); loop_p old_loop = gbb_loop_at_index (gbb, ip->region, depth); VEC_replace (tree, iv_map, old_loop->num, new_name); } + + mpz_clear (v1); + mpz_clear (v2); } /* Construct bb_pbb_def with BB and PBB. */ diff --git a/gcc/graphite-ppl.h b/gcc/graphite-ppl.h index 49bde618f47..5820e19927d 100644 --- a/gcc/graphite-ppl.h +++ b/gcc/graphite-ppl.h @@ -124,6 +124,17 @@ ppl_set_coef_tree (ppl_Linear_Expression_t e, ppl_dimension_type i, tree x) mpz_clear (v); } +/* Sets RES to the min of V1 and V2. */ + +static inline void +value_min (mpz_t res, mpz_t v1, mpz_t v2) +{ + if (mpz_cmp (v1, v2) < 0) + mpz_set (res, v1); + else + mpz_set (res, v2); +} + /* Sets RES to the max of V1 and V2. */ static inline void diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d28b4847483..a63b6474cbb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2011-07-21 Sebastian Pop + + PR middle-end/47654 + PR middle-end/49649 + * gcc.dg/graphite/run-id-pr47654.c: New. + 2011-07-21 Ian Lance Taylor PR middle-end/49705 diff --git a/gcc/testsuite/gcc.dg/graphite/run-id-pr47654.c b/gcc/testsuite/gcc.dg/graphite/run-id-pr47654.c new file mode 100644 index 00000000000..85b6e8b70f5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/run-id-pr47654.c @@ -0,0 +1,24 @@ +/* { dg-options "-O -floop-strip-mine" } */ + +int a[128][40]; + +void __attribute__ ((noinline, noclone)) +foo (void) +{ + int i, j; + for (i = 0; i < 40; i++) + for (j = 0; j < 128; j++) + a[j][i] = 4; +} + +int +main () +{ + int i, j; + foo (); + for (i = 0; i < 40; i++) + for (j = 0; j < 128; j++) + if (a[j][i] != 4) + __builtin_abort (); + return 0; +} -- 2.30.2