X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fgraphite-clast-to-gimple.c;h=1d33aaa088dd8736fff0c9658e0e1d5b3105db1a;hb=b22f66e203c5928a518440558634496a4ff1b391;hp=f708c76256ed94b10dc3fdccf35b482fd6b49f28;hpb=0f5b569a8972bf209594fdfafda4bfd3b3f3ffff;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/graphite-clast-to-gimple.c b/gcc/graphite-clast-to-gimple.c index f708c76256e..1d33aaa088d 100644 --- a/gcc/graphite-clast-to-gimple.c +++ b/gcc/graphite-clast-to-gimple.c @@ -1,5 +1,5 @@ /* Translation of CLAST (CLooG AST) to Gimple. - Copyright (C) 2009 Free Software Foundation, Inc. + Copyright (C) 2009, 2010 Free Software Foundation, Inc. Contributed by Sebastian Pop . This file is part of GCC. @@ -40,6 +40,7 @@ along with GCC; see the file COPYING3. If not see #include "value-prof.h" #include "pointer-set.h" #include "gimple.h" +#include "langhooks.h" #include "sese.h" #ifdef HAVE_cloog @@ -52,6 +53,10 @@ along with GCC; see the file COPYING3. If not see #include "graphite-clast-to-gimple.h" #include "graphite-dependences.h" +/* This flag is set when an error occurred during the translation of + CLAST to Gimple. */ +static bool gloog_error; + /* Verifies properties that GRAPHITE should maintain during translation. */ static inline void @@ -61,8 +66,7 @@ graphite_verify (void) verify_loop_structure (); verify_dominators (CDI_DOMINATORS); verify_dominators (CDI_POST_DOMINATORS); - verify_ssa (false); - verify_loop_closed_ssa (); + verify_loop_closed_ssa (true); #endif } @@ -117,7 +121,12 @@ save_clast_name_index (htab_t index_table, const char *name, int index) slot = htab_find_slot (index_table, &tmp, INSERT); if (slot) - *slot = new_clast_name_index (name, index); + { + if (*slot) + free (*slot); + + *slot = new_clast_name_index (name, index); + } } /* Print to stderr the element ELT. */ @@ -215,13 +224,46 @@ clast_name_to_gcc (const char *name, sese region, VEC (tree, heap) *newivs, return newivs_to_depth_to_newiv (newivs, index); } -/* Returns the maximal precision type for expressions E1 and E2. */ +/* Returns the signed maximal precision type for expressions TYPE1 and TYPE2. */ -static inline tree -max_precision_type (tree e1, tree e2) +static tree +max_signed_precision_type (tree type1, tree type2) +{ + int p1 = TYPE_PRECISION (type1); + int p2 = TYPE_PRECISION (type2); + int precision; + tree type; + + if (p1 > p2) + precision = TYPE_UNSIGNED (type1) ? p1 * 2 : p1; + else + precision = TYPE_UNSIGNED (type2) ? p2 * 2 : p2; + + type = lang_hooks.types.type_for_size (precision, false); + + if (!type) + { + gloog_error = true; + return integer_type_node; + } + return type; +} + +/* Returns the maximal precision type for expressions TYPE1 and TYPE2. */ + +static tree +max_precision_type (tree type1, tree type2) { - tree type1 = TREE_TYPE (e1); - tree type2 = TREE_TYPE (e2); + if (POINTER_TYPE_P (type1)) + return type1; + + if (POINTER_TYPE_P (type2)) + return type2; + + if (!TYPE_UNSIGNED (type1) + || !TYPE_UNSIGNED (type2)) + return max_signed_precision_type (type1, type2); + return TYPE_PRECISION (type1) > TYPE_PRECISION (type2) ? type1 : type2; } @@ -269,18 +311,28 @@ clast_to_gcc_expression (tree type, struct clast_expr *e, if (t->var) { - if (value_one_p (t->val)) + if (mpz_cmp_si (t->val, 1) == 0) { tree name = clast_name_to_gcc (t->var, region, newivs, newivs_index, params_index); - return fold_convert (type, name); + + if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type)) + name = fold_convert (sizetype, name); + + name = fold_convert (type, name); + return name; } - else if (value_mone_p (t->val)) + else if (mpz_cmp_si (t->val, -1) == 0) { tree name = clast_name_to_gcc (t->var, region, newivs, newivs_index, params_index); + + if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type)) + name = fold_convert (sizetype, name); + name = fold_convert (type, name); + return fold_build1 (NEGATE_EXPR, type, name); } else @@ -288,8 +340,17 @@ clast_to_gcc_expression (tree type, struct clast_expr *e, tree name = clast_name_to_gcc (t->var, region, newivs, newivs_index, params_index); tree cst = gmp_cst_to_tree (type, t->val); + + if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type)) + name = fold_convert (sizetype, name); + name = fold_convert (type, name); - return fold_build2 (MULT_EXPR, type, cst, name); + + if (!POINTER_TYPE_P (type)) + return fold_build2 (MULT_EXPR, type, cst, name); + + gloog_error = true; + return cst; } } else @@ -357,7 +418,168 @@ clast_to_gcc_expression (tree type, struct clast_expr *e, return NULL_TREE; } -/* Returns the type for the expression E. */ +/* Return the precision needed to represent the value VAL. */ + +static int +precision_for_value (Value val) +{ + Value x, y, two; + int precision; + + value_init (x); + value_init (y); + value_init (two); + value_set_si (x, 2); + value_assign (y, val); + value_set_si (two, 2); + precision = 1; + + if (value_neg_p (y)) + value_oppose (y, y); + + while (value_gt (y, x)) + { + value_multiply (x, x, two); + precision++; + } + + value_clear (x); + value_clear (y); + value_clear (two); + + return precision; +} + +/* Return the precision needed to represent the values between LOW and + UP. */ + +static int +precision_for_interval (Value low, Value up) +{ + Value diff; + int precision; + + gcc_assert (value_le (low, up)); + + value_init (diff); + value_subtract (diff, up, low); + precision = precision_for_value (diff); + value_clear (diff); + + return precision; +} + +/* Return a type that could represent the integer value VAL, or + otherwise return NULL_TREE. */ + +static tree +gcc_type_for_interval (Value low, Value up, tree old_type) +{ + bool unsigned_p = true; + int precision, prec_up, prec_int; + tree type; + + gcc_assert (value_le (low, up)); + + /* Preserve the signedness of the old IV. */ + if ((old_type && !TYPE_UNSIGNED (old_type)) + || value_neg_p (low)) + unsigned_p = false; + + prec_up = precision_for_value (up); + prec_int = precision_for_interval (low, up); + precision = prec_up > prec_int ? prec_up : prec_int; + + type = lang_hooks.types.type_for_size (precision, unsigned_p); + if (!type) + { + gloog_error = true; + return integer_type_node; + } + + return type; +} + +/* Return a type that could represent the integer value VAL, or + otherwise return NULL_TREE. */ + +static tree +gcc_type_for_value (Value val) +{ + return gcc_type_for_interval (val, val, NULL_TREE); +} + +/* Return the type for the clast_term T used in STMT. */ + +static tree +gcc_type_for_clast_term (struct clast_term *t, + sese region, VEC (tree, heap) *newivs, + htab_t newivs_index, htab_t params_index) +{ + gcc_assert (t->expr.type == expr_term); + + if (!t->var) + return gcc_type_for_value (t->val); + + return TREE_TYPE (clast_name_to_gcc (t->var, region, newivs, + newivs_index, params_index)); +} + +static tree +gcc_type_for_clast_expr (struct clast_expr *, sese, + VEC (tree, heap) *, htab_t, htab_t); + +/* Return the type for the clast_reduction R used in STMT. */ + +static tree +gcc_type_for_clast_red (struct clast_reduction *r, sese region, + VEC (tree, heap) *newivs, + htab_t newivs_index, htab_t params_index) +{ + int i; + tree type = NULL_TREE; + + if (r->n == 1) + return gcc_type_for_clast_expr (r->elts[0], region, newivs, + newivs_index, params_index); + + switch (r->type) + { + case clast_red_sum: + case clast_red_min: + case clast_red_max: + type = gcc_type_for_clast_expr (r->elts[0], region, newivs, + newivs_index, params_index); + for (i = 1; i < r->n; i++) + type = max_precision_type (type, gcc_type_for_clast_expr + (r->elts[i], region, newivs, + newivs_index, params_index)); + + return type; + + default: + break; + } + + gcc_unreachable (); + return NULL_TREE; +} + +/* Return the type for the clast_binary B used in STMT. */ + +static tree +gcc_type_for_clast_bin (struct clast_binary *b, + sese region, VEC (tree, heap) *newivs, + htab_t newivs_index, htab_t params_index) +{ + tree l = gcc_type_for_clast_expr ((struct clast_expr *) b->LHS, region, + newivs, newivs_index, params_index); + tree r = gcc_type_for_value (b->RHS); + return max_signed_precision_type (l, r); +} + +/* Returns the type for the CLAST expression E when used in statement + STMT. */ static tree gcc_type_for_clast_expr (struct clast_expr *e, @@ -367,45 +589,16 @@ gcc_type_for_clast_expr (struct clast_expr *e, switch (e->type) { case expr_term: - { - struct clast_term *t = (struct clast_term *) e; - - if (t->var) - return TREE_TYPE (clast_name_to_gcc (t->var, region, newivs, - newivs_index, params_index)); - else - return NULL_TREE; - } + return gcc_type_for_clast_term ((struct clast_term *) e, region, + newivs, newivs_index, params_index); case expr_red: - { - struct clast_reduction *r = (struct clast_reduction *) e; - - if (r->n == 1) - return gcc_type_for_clast_expr (r->elts[0], region, newivs, - newivs_index, params_index); - else - { - int i; - for (i = 0; i < r->n; i++) - { - tree type = gcc_type_for_clast_expr (r->elts[i], region, - newivs, newivs_index, - params_index); - if (type) - return type; - } - return NULL_TREE; - } - } + return gcc_type_for_clast_red ((struct clast_reduction *) e, region, + newivs, newivs_index, params_index); case expr_bin: - { - struct clast_binary *b = (struct clast_binary *) e; - struct clast_expr *lhs = (struct clast_expr *) b->LHS; - return gcc_type_for_clast_expr (lhs, region, newivs, - newivs_index, params_index); - } + return gcc_type_for_clast_bin ((struct clast_binary *) e, region, + newivs, newivs_index, params_index); default: gcc_unreachable (); @@ -421,13 +614,11 @@ gcc_type_for_clast_eq (struct clast_equation *cleq, sese region, VEC (tree, heap) *newivs, htab_t newivs_index, htab_t params_index) { - tree type = gcc_type_for_clast_expr (cleq->LHS, region, newivs, - newivs_index, params_index); - if (type) - return type; - - return gcc_type_for_clast_expr (cleq->RHS, region, newivs, newivs_index, - params_index); + tree l = gcc_type_for_clast_expr (cleq->LHS, region, newivs, + newivs_index, params_index); + tree r = gcc_type_for_clast_expr (cleq->RHS, region, newivs, + newivs_index, params_index); + return max_precision_type (l, r); } /* Translates a clast equation CLEQ to a tree. */ @@ -497,6 +688,80 @@ graphite_create_new_guard (sese region, edge entry_edge, return exit_edge; } +/* Compute the lower bound LOW and upper bound UP for the induction + variable at LEVEL for the statement PBB, based on the transformed + scattering of PBB: T|I|G|Cst, with T the scattering transform, I + the iteration domain, and G the context parameters. */ + +static void +compute_bounds_for_level (poly_bb_p pbb, int level, Value low, Value up) +{ + ppl_Pointset_Powerset_C_Polyhedron_t ps; + ppl_Linear_Expression_t le; + + combine_context_id_scat (&ps, pbb, false); + + /* Prepare the linear expression corresponding to the level that we + want to maximize/minimize. */ + { + ppl_dimension_type dim = pbb_nb_scattering_transform (pbb) + + pbb_dim_iter_domain (pbb) + pbb_nb_params (pbb); + + ppl_new_Linear_Expression_with_dimension (&le, dim); + ppl_set_coef (le, 2 * level + 1, 1); + } + + ppl_max_for_le_pointset (ps, le, up); + ppl_min_for_le_pointset (ps, le, low); +} + +/* Compute the type for the induction variable at LEVEL for the + statement PBB, based on the transformed schedule of PBB. OLD_TYPE + is the type of the old induction variable for that loop. */ + +static tree +compute_type_for_level_1 (poly_bb_p pbb, int level, tree old_type) +{ + Value low, up; + tree type; + + value_init (low); + value_init (up); + + compute_bounds_for_level (pbb, level, low, up); + type = gcc_type_for_interval (low, up, old_type); + + value_clear (low); + value_clear (up); + return type; +} + +/* Compute the type for the induction variable at LEVEL for the + statement PBB, based on the transformed schedule of PBB. */ + +static tree +compute_type_for_level (poly_bb_p pbb, int level) +{ + tree oldiv = pbb_to_depth_to_oldiv (pbb, level); + tree type = TREE_TYPE (oldiv); + + if (type && POINTER_TYPE_P (type)) + { +#ifdef ENABLE_CHECKING + tree ctype = compute_type_for_level_1 (pbb, level, type); + + /* In the case of a pointer type, check that after the loop + transform, the lower and the upper bounds of the type fit the + oldiv pointer type. */ + gcc_assert (TYPE_PRECISION (type) >= TYPE_PRECISION (ctype) + && integer_zerop (lower_bound_in_type (ctype, ctype))); +#endif + return type; + } + + return compute_type_for_level_1 (pbb, level, type); +} + /* Walks a CLAST and returns the first statement in the body of a loop. */ @@ -519,38 +784,21 @@ clast_get_body_of_loop (struct clast_stmt *stmt) gcc_unreachable (); } -/* Given a CLOOG_IV, returns the type that it should have in GCC land. - If the information is not available, i.e. in the case one of the - transforms created the loop, just return integer_type_node. */ - -static tree -gcc_type_for_cloog_iv (const char *cloog_iv, gimple_bb_p gbb) -{ - struct ivtype_map_elt_s tmp; - PTR *slot; - - tmp.cloog_iv = cloog_iv; - slot = htab_find_slot (GBB_CLOOG_IV_TYPES (gbb), &tmp, NO_INSERT); - - if (slot && *slot) - return ((ivtype_map_elt) *slot)->type; - - return integer_type_node; -} - -/* Returns the induction variable for the loop that gets translated to - STMT. */ +/* Returns the type for the induction variable for the loop translated + from STMT_FOR. */ static tree -gcc_type_for_iv_of_clast_loop (struct clast_for *stmt_for) +gcc_type_for_iv_of_clast_loop (struct clast_for *stmt_for, int level, + tree lb_type, tree ub_type) { struct clast_stmt *stmt = (struct clast_stmt *) stmt_for; struct clast_user_stmt *body = clast_get_body_of_loop (stmt); - const char *cloog_iv = stmt_for->iterator; CloogStatement *cs = body->statement; poly_bb_p pbb = (poly_bb_p) cloog_statement_usr (cs); - return gcc_type_for_cloog_iv (cloog_iv, PBB_BLACK_BOX (pbb)); + return max_signed_precision_type (lb_type, max_precision_type + (ub_type, compute_type_for_level + (pbb, level - 1))); } /* Creates a new LOOP corresponding to Cloog's STMT. Inserts an @@ -565,9 +813,13 @@ static struct loop * graphite_create_new_loop (sese region, edge entry_edge, struct clast_for *stmt, loop_p outer, VEC (tree, heap) **newivs, - htab_t newivs_index, htab_t params_index) + htab_t newivs_index, htab_t params_index, int level) { - tree type = gcc_type_for_iv_of_clast_loop (stmt); + tree lb_type = gcc_type_for_clast_expr (stmt->LB, region, *newivs, + newivs_index, params_index); + tree ub_type = gcc_type_for_clast_expr (stmt->UB, region, *newivs, + newivs_index, params_index); + tree type = gcc_type_for_iv_of_clast_loop (stmt, level, lb_type, ub_type); tree lb = clast_to_gcc_expression (type, stmt->LB, region, *newivs, newivs_index, params_index); tree ub = clast_to_gcc_expression (type, stmt->UB, region, *newivs, @@ -629,7 +881,7 @@ copy_renames (void **slot, void *s) tmp.old_name = old_name; x = htab_find_slot (res, &tmp, INSERT); - if (!*x) + if (x && !*x) *x = new_rename_map_elt (old_name, expr); return 1; @@ -660,7 +912,7 @@ mark_bb_with_pbb (poly_bb_p pbb, basic_block bb, htab_t bb_pbb_mapping) tmp.bb = bb; x = htab_find_slot (bb_pbb_mapping, &tmp, INSERT); - if (!*x) + if (x && !*x) *x = new_bb_pbb_def (bb, pbb); } @@ -753,28 +1005,78 @@ translate_clast_user (sese region, struct clast_user_stmt *stmt, edge next_e, new_bb = next_e->src; mark_bb_with_pbb (pbb, new_bb, bb_pbb_mapping); update_ssa (TODO_update_ssa); + return next_e; } -/* Translates a clast for statement STMT to gimple. +/* Creates a new if region protecting the loop to be executed, if the execution + count is zero (lb > ub). */ +static edge +graphite_create_new_loop_guard (sese region, edge entry_edge, + struct clast_for *stmt, + VEC (tree, heap) *newivs, + htab_t newivs_index, htab_t params_index) +{ + tree cond_expr; + edge exit_edge; + tree lb_type = gcc_type_for_clast_expr (stmt->LB, region, newivs, + newivs_index, params_index); + tree ub_type = gcc_type_for_clast_expr (stmt->UB, region, newivs, + newivs_index, params_index); + tree type = max_precision_type (lb_type, ub_type); + tree lb = clast_to_gcc_expression (type, stmt->LB, region, newivs, + newivs_index, params_index); + tree ub = clast_to_gcc_expression (type, stmt->UB, region, newivs, + newivs_index, params_index); + tree ub_one; + + /* Adding +1 and using LT_EXPR helps with loop latches that have a + loop iteration count of "PARAMETER - 1". For PARAMETER == 0 this becomes + 2^{32|64}, and the condition lb <= ub is true, even if we do not want this. + However lb < ub + 1 is false, as expected. */ + tree one; + Value gmp_one; + + value_init (gmp_one); + value_set_si (gmp_one, 1); + one = gmp_cst_to_tree (type, gmp_one); + mpz_clear (gmp_one); + + ub_one = fold_build2 (POINTER_TYPE_P (type) ? POINTER_PLUS_EXPR : PLUS_EXPR, + type, ub, one); + + /* When ub + 1 wraps around, use lb <= ub. */ + if (integer_zerop (ub_one)) + cond_expr = fold_build2 (LE_EXPR, boolean_type_node, lb, ub); + else + cond_expr = fold_build2 (LT_EXPR, boolean_type_node, lb, ub_one); + + exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr); + + return exit_edge; +} + + +/* Create the loop for a clast for statement. - REGION is the sese region we used to generate the scop. - NEXT_E is the edge where new generated code should be attached. - - CONTEXT_LOOP is the loop in which the generated code will be placed - RENAME_MAP contains a set of tuples of new names associated to the original variables names. - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. - PARAMS_INDEX connects the cloog parameters with the gimple parameters in the sese region. */ static edge -translate_clast_for (sese region, loop_p context_loop, struct clast_for *stmt, - edge next_e, htab_t rename_map, VEC (tree, heap) **newivs, - htab_t newivs_index, htab_t bb_pbb_mapping, int level, - htab_t params_index) +translate_clast_for_loop (sese region, loop_p context_loop, + struct clast_for *stmt, edge next_e, + htab_t rename_map, VEC (tree, heap) **newivs, + htab_t newivs_index, htab_t bb_pbb_mapping, + int level, htab_t params_index) { struct loop *loop = graphite_create_new_loop (region, next_e, stmt, - context_loop, newivs, - newivs_index, params_index); + context_loop, newivs, + newivs_index, params_index, + level); edge last_e = single_exit (loop); edge to_body = single_succ_edge (loop->header); basic_block after = to_body->dest; @@ -789,18 +1091,60 @@ translate_clast_for (sese region, loop_p context_loop, struct clast_for *stmt, redirect_edge_succ_nodup (next_e, after); set_immediate_dominator (CDI_DOMINATORS, next_e->dest, next_e->src); - /* Remove from rename_map all the tuples containing variables - defined in loop's body. */ + /* Remove from rename_map all the tuples containing variables + defined in loop's body. */ insert_loop_close_phis (rename_map, loop); if (flag_loop_parallelize_all && !dependency_in_loop_p (loop, bb_pbb_mapping, - get_scattering_level (level))) + get_scattering_level (level))) loop->can_be_parallel = true; return last_e; } +/* Translates a clast for statement STMT to gimple. First a guard is created + protecting the loop, if it is executed zero times. In this guard we create + the real loop structure. + + - REGION is the sese region we used to generate the scop. + - NEXT_E is the edge where new generated code should be attached. + - RENAME_MAP contains a set of tuples of new names associated to + the original variables names. + - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. + - PARAMS_INDEX connects the cloog parameters with the gimple parameters in + the sese region. */ +static edge +translate_clast_for (sese region, loop_p context_loop, struct clast_for *stmt, + edge next_e, htab_t rename_map, VEC (tree, heap) **newivs, + htab_t newivs_index, htab_t bb_pbb_mapping, int level, + htab_t params_index) +{ + edge last_e = graphite_create_new_loop_guard (region, next_e, stmt, *newivs, + newivs_index, params_index); + + edge true_e = get_true_edge_from_guard_bb (next_e->dest); + edge false_e = get_false_edge_from_guard_bb (next_e->dest); + edge exit_true_e = single_succ_edge (true_e->dest); + edge exit_false_e = single_succ_edge (false_e->dest); + + htab_t before_guard = htab_create (10, rename_map_elt_info, + eq_rename_map_elts, free); + htab_traverse (rename_map, copy_renames, before_guard); + + next_e = translate_clast_for_loop (region, context_loop, stmt, true_e, + rename_map, newivs, + newivs_index, bb_pbb_mapping, level, + params_index); + + insert_guard_phis (last_e->src, exit_true_e, exit_false_e, + before_guard, rename_map); + + htab_delete (before_guard); + + return last_e; +} + /* Translates a clast guard statement STMT to gimple. - REGION is the sese region we used to generate the scop. @@ -895,126 +1239,6 @@ translate_clast (sese region, loop_p context_loop, struct clast_stmt *stmt, bb_pbb_mapping, level, params_index); } -/* Returns the first cloog name used in EXPR. */ - -static const char * -find_cloog_iv_in_expr (struct clast_expr *expr) -{ - struct clast_term *term = (struct clast_term *) expr; - - if (expr->type == expr_term - && !term->var) - return NULL; - - if (expr->type == expr_term) - return term->var; - - if (expr->type == expr_red) - { - int i; - struct clast_reduction *red = (struct clast_reduction *) expr; - - for (i = 0; i < red->n; i++) - { - const char *res = find_cloog_iv_in_expr ((red)->elts[i]); - - if (res) - return res; - } - } - - return NULL; -} - -/* Build for a clast_user_stmt USER_STMT a map between the CLAST - induction variables and the corresponding GCC old induction - variables. This information is stored on each GRAPHITE_BB. */ - -static void -compute_cloog_iv_types_1 (poly_bb_p pbb, struct clast_user_stmt *user_stmt) -{ - gimple_bb_p gbb = PBB_BLACK_BOX (pbb); - struct clast_stmt *t; - int index = 0; - - for (t = user_stmt->substitutions; t; t = t->next, index++) - { - PTR *slot; - struct ivtype_map_elt_s tmp; - struct clast_expr *expr = (struct clast_expr *) - ((struct clast_assignment *)t)->RHS; - - /* Create an entry (clast_var, type). */ - tmp.cloog_iv = find_cloog_iv_in_expr (expr); - if (!tmp.cloog_iv) - continue; - - slot = htab_find_slot (GBB_CLOOG_IV_TYPES (gbb), &tmp, INSERT); - - if (!*slot) - { - tree oldiv = pbb_to_depth_to_oldiv (pbb, index); - tree type = oldiv ? TREE_TYPE (oldiv) : integer_type_node; - *slot = new_ivtype_map_elt (tmp.cloog_iv, type); - } - } -} - -/* Walk the CLAST tree starting from STMT and build for each - clast_user_stmt a map between the CLAST induction variables and the - corresponding GCC old induction variables. This information is - stored on each GRAPHITE_BB. */ - -static void -compute_cloog_iv_types (struct clast_stmt *stmt) -{ - if (!stmt) - return; - - if (CLAST_STMT_IS_A (stmt, stmt_root)) - goto next; - - if (CLAST_STMT_IS_A (stmt, stmt_user)) - { - CloogStatement *cs = ((struct clast_user_stmt *) stmt)->statement; - poly_bb_p pbb = (poly_bb_p) cloog_statement_usr (cs); - gimple_bb_p gbb = PBB_BLACK_BOX (pbb); - - if (!GBB_CLOOG_IV_TYPES (gbb)) - GBB_CLOOG_IV_TYPES (gbb) = htab_create (10, ivtype_map_elt_info, - eq_ivtype_map_elts, free); - - compute_cloog_iv_types_1 (pbb, (struct clast_user_stmt *) stmt); - goto next; - } - - if (CLAST_STMT_IS_A (stmt, stmt_for)) - { - struct clast_stmt *s = ((struct clast_for *) stmt)->body; - compute_cloog_iv_types (s); - goto next; - } - - if (CLAST_STMT_IS_A (stmt, stmt_guard)) - { - struct clast_stmt *s = ((struct clast_guard *) stmt)->then; - compute_cloog_iv_types (s); - goto next; - } - - if (CLAST_STMT_IS_A (stmt, stmt_block)) - { - struct clast_stmt *s = ((struct clast_block *) stmt)->body; - compute_cloog_iv_types (s); - goto next; - } - - gcc_unreachable (); - - next: - compute_cloog_iv_types (stmt->next); -} - /* Free the SCATTERING domain list. */ static void @@ -1312,8 +1536,8 @@ debug_generated_program (scop_p scop) print_generated_program (stderr, scop); } -/* Add CLooG names to parameter index. The index is used to translate back from - * CLooG names to GCC trees. */ +/* Add CLooG names to parameter index. The index is used to translate + back from CLooG names to GCC trees. */ static void create_params_index (htab_t index_table, CloogProgram *prog) { @@ -1332,17 +1556,18 @@ create_params_index (htab_t index_table, CloogProgram *prog) { */ bool -gloog (scop_p scop, htab_t bb_pbb_mapping) +gloog (scop_p scop, VEC (scop_p, heap) *scops, htab_t bb_pbb_mapping) { - edge new_scop_exit_edge = NULL; VEC (tree, heap) *newivs = VEC_alloc (tree, heap, 10); loop_p context_loop; sese region = SCOP_REGION (scop); ifsese if_region = NULL; htab_t rename_map, newivs_index, params_index; cloog_prog_clast pc; + int i; timevar_push (TV_GRAPHITE_CODE_GEN); + gloog_error = false; pc = scop_to_clast (scop); @@ -1365,7 +1590,6 @@ gloog (scop_p scop, htab_t bb_pbb_mapping) graphite_verify (); context_loop = SESE_ENTRY (region)->src->loop_father; - compute_cloog_iv_types (pc.stmt); rename_map = htab_create (10, rename_map_elt_info, eq_rename_map_elts, free); newivs_index = htab_create (10, clast_name_index_elt_info, eq_clast_name_indexes, free); @@ -1374,18 +1598,27 @@ gloog (scop_p scop, htab_t bb_pbb_mapping) create_params_index (params_index, pc.prog); - new_scop_exit_edge = translate_clast (region, context_loop, pc.stmt, - if_region->true_region->entry, - rename_map, &newivs, newivs_index, - bb_pbb_mapping, 1, params_index); + translate_clast (region, context_loop, pc.stmt, + if_region->true_region->entry, + rename_map, &newivs, newivs_index, + bb_pbb_mapping, 1, params_index); graphite_verify (); sese_adjust_liveout_phis (region, rename_map, if_region->region->exit->src, if_region->false_region->exit, if_region->true_region->exit); + scev_reset_htab (); + rename_nb_iterations (rename_map); + + for (i = 0; VEC_iterate (scop_p, scops, i, scop); i++) + rename_sese_parameters (rename_map, SCOP_REGION (scop)); + recompute_all_dominators (); graphite_verify (); + if (gloog_error) + set_ifsese_condition (if_region, integer_zero_node); + free (if_region->true_region); free (if_region->region); free (if_region); @@ -1412,7 +1645,7 @@ gloog (scop_p scop, htab_t bb_pbb_mapping) num_no_dependency); } - return true; + return !gloog_error; } #endif