[PATCH] [graphite] use debug_printer throughout graphite.
The debug_printer provides an elegant way to represent debug related statements, so we are extending its usage throughout graphite infrastructure. No functional changes intended. Passes regtest and bootstrap. gcc/ChangeLog: 2015-10-07 hiraditya * graphite-isl-ast-to-gimple.c (graphite_regenerate_ast_isl): Use debug_printer. * graphite-optimize-isl.c (get_schedule_for_band): Same. (optimize_isl): Same. * graphite-scop-detection.c (canonicalize_loop_closed_ssa): Rename db to dbgs. (scop_detection::merge_sese): Same. (scop_detection::build_scop_depth): Same. (scop_detection::build_scop_breadth): Same. (scop_detection::loop_is_valid_scop): Same. (scop_detection::add_scop): Same. (scop_detection::harmful_stmt_in_region): Same. (scop_detection::remove_subscops): Same. (scop_detection::remove_intersecting_scops): Same. (stmt_has_side_effects): Same. (scop_detection::graphite_can_represent_stmt): Same. (scop_detection::stmt_simple_for_scop_p): Same. (scop_detection::loop_body_is_valid_scop): Same. (build_scops): Same. (debug_printer): Move the declaration to sese.h * graphite.c (graphite_initialize): Initialize the dump_file for debug_printer. (graphite_finalize): Use debug_printer. (graphite_transform_loops): Use debug_printer. * sese.h: Move the declaration of debug_printer here. --- gcc/graphite-isl-ast-to-gimple.c | 28 +--- gcc/graphite-optimize-isl.c | 13 +++--- gcc/graphite-scop-detection.c| 94 +--- gcc/graphite.c | 49 + gcc/sese.h | 34 +++ 5 files changed, 99 insertions(+), 119 deletions(-) diff --git a/gcc/graphite-isl-ast-to-gimple.c b/gcc/graphite-isl-ast-to-gimple.c index 12e6c61..f986866 100644 --- a/gcc/graphite-isl-ast-to-gimple.c +++ b/gcc/graphite-isl-ast-to-gimple.c @@ -1153,12 +1153,9 @@ graphite_regenerate_ast_isl (scop_p scop) graphite_regenerate_error = false; root_node = scop_to_isl_ast (scop, ip); - if (dump_file && (dump_flags & TDF_DETAILS)) -{ - fprintf (dump_file, "\nISL AST generated by ISL: \n"); - print_isl_ast_node (dump_file, root_node, scop->isl_context); - fprintf (dump_file, "\n"); -} + DEBUG_PRINT (dbgs << "\nISL AST generated by ISL: \n"; +print_isl_ast_node (dump_file, root_node, scop->isl_context); +dbgs << "\n"); recompute_all_dominators (); graphite_verify (); @@ -1200,18 +1197,13 @@ graphite_regenerate_ast_isl (scop_p scop) isl_ast_node_free (root_node); timevar_pop (TV_GRAPHITE_CODE_GEN); - if (dump_file && (dump_flags & TDF_DETAILS)) -{ - loop_p loop; - int num_no_dependency = 0; - - FOR_EACH_LOOP (loop, 0) - if (loop->can_be_parallel) - num_no_dependency++; - - fprintf (dump_file, "\n%d loops carried no dependency.\n", - num_no_dependency); -} + DEBUG_PRINT ( +loop_p loop; +int num_no_dependency = 0; +FOR_EACH_LOOP (loop, 0) + if (loop->can_be_parallel) + num_no_dependency++; +dbgs << num_no_dependency << " loops carried no dependency.\n"); return !graphite_regenerate_error; } diff --git a/gcc/graphite-optimize-isl.c b/gcc/graphite-optimize-isl.c index 2bae417..03ab5e9 100644 --- a/gcc/graphite-optimize-isl.c +++ b/gcc/graphite-optimize-isl.c @@ -177,14 +177,12 @@ get_schedule_for_band (isl_band *band, int *dimensions) /* It does not make any sense to tile a band with just one dimension. */ if (*dimensions == 1) { - if (dump_file && dump_flags) - fprintf (dump_file, "not tiled\n"); + DEBUG_PRINT (dbgs << "not tiled\n"); return partial_schedule; } - if (dump_file && dump_flags) -fprintf (dump_file, "tiled by %d\n", -PARAM_VALUE (PARAM_LOOP_BLOCK_TILE_SIZE)); + DEBUG_PRINT (dbgs << "tiled by %d\n" + << PARAM_VALUE (PARAM_LOOP_BLOCK_TILE_SIZE)); ctx = isl_union_map_get_ctx (partial_schedule); space = isl_union_map_get_space (partial_schedule); @@ -348,9 +346,8 @@ optimize_isl (scop_p scop) isl_ctx_set_max_operations (scop->isl_context, old_max_operations); if (!schedule || isl_ctx_last_error (scop->isl_context) == isl_error_quota) { - if (dump_file && dump_flags) - fprintf (dump_file, "ISL timed out at %d operations\n", -max_operations); + DEBUG_PRINT (dbgs << "ISL timed out at " << max_operations + << " operations\n"); if (schedule) isl_schedule_free (schedule); return false; diff --git a/gc
[PATCH] RFC: Enable graphite at -O3 -fprofile_use
Since graphite will not modify the CFG when it does not do any optimization, we would like to propose that graphite's polyhedral optimizer be enabled at -O3 -fprofile-use where, compile time is of lesser concern. gcc/ChangeLog: 2015-11-08 Aditya Kumar Sebastian Pop * graphite.c (gate_graphite_transforms): Enable graphite on -O3 -fprofile-use. --- gcc/graphite.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gcc/graphite.c b/gcc/graphite.c index 5316bc4..49595ac 100644 --- a/gcc/graphite.c +++ b/gcc/graphite.c @@ -383,6 +383,9 @@ gate_graphite_transforms (void) || flag_loop_optimize_isl) flag_graphite = 1; + if (optimize >= 3 && flag_profile_use) +flag_loop_optimize_isl = 1; + return flag_graphite != 0; } -- 2.1.4
[PATCH 2/2] [graphite] Enable condegen in case of cond phis.
From: hiraditya The codegen of conditional PHIs inside the scop where one predecessor dominates the other was difficult so it wasn't enabled in the previous patch. After a couple of bug-fixes this has been enabled in this patch. Not all the cases could be handled in this case because it becomes difficult to map the basic block back to original code in some cases. Bug-fixes: 1. The vec_find returns -1 when no element was found. This wasn't checked. 2. When the arguments to pending phis could not be resolved in the second pass, the codegen would fail so the new code should be cleaned up. This patch passes regtest and bootstrap on linux-x86-64 with BOOT_CFLAGS='-O2 -fgraphite-identity -floop-nest-optimize' 2015-11-14 hiraditya * graphite-isl-ast-to-gimple.c (copy_loop_phi_args): Change the return type to bool for early exit. (translate_isl_ast_to_gimple::copy_loop_phi_nodes): Early return in case of error. (translate_isl_ast_to_gimple::copy_loop_close_phi_args): Same. (add_phi_arg_for_new_expr): Enable codegen for if-block where one predecessor dominates the other. (translate_isl_ast_to_gimple::copy_cond_phi_args): Fix. When the element is not found it returns -1. (translate_isl_ast_to_gimple::translate_pending_phi_nodes): Bail out early when codegen fails. (graphite_regenerate_ast_isl): Remove codegen region when pending phis could not be generated. --- gcc/graphite-isl-ast-to-gimple.c | 168 --- 1 file changed, 106 insertions(+), 62 deletions(-) diff --git a/gcc/graphite-isl-ast-to-gimple.c b/gcc/graphite-isl-ast-to-gimple.c index 82a7740..2021df8 100644 --- a/gcc/graphite-isl-ast-to-gimple.c +++ b/gcc/graphite-isl-ast-to-gimple.c @@ -352,7 +352,7 @@ class translate_isl_ast_to_gimple /* Copy the PHI arguments from OLD_PHI to the NEW_PHI. The arguments to NEW_PHI must be found unless they can be POSTPONEd for later. */ - void copy_loop_phi_args (gphi *old_phi, init_back_edge_pair_t &ibp_old_bb, + bool copy_loop_phi_args (gphi *old_phi, init_back_edge_pair_t &ibp_old_bb, gphi *new_phi, init_back_edge_pair_t &ibp_new_bb, bool postpone); @@ -1928,7 +1928,7 @@ get_edges (basic_block bb) /* Copy the PHI arguments from OLD_PHI to the NEW_PHI. The arguments to NEW_PHI must be found unless they can be POSTPONEd for later. */ -void +bool translate_isl_ast_to_gimple:: copy_loop_phi_args (gphi *old_phi, init_back_edge_pair_t &ibp_old_bb, gphi *new_phi, init_back_edge_pair_t &ibp_new_bb, @@ -1969,8 +1969,9 @@ copy_loop_phi_args (gphi *old_phi, init_back_edge_pair_t &ibp_old_bb, } else /* Either we should add the arg to phi or, we should postpone. */ - gcc_unreachable (); + return false; } + return true; } /* Copy loop phi nodes from BB to NEW_BB. */ @@ -2006,7 +2007,8 @@ translate_isl_ast_to_gimple::copy_loop_phi_nodes (basic_block bb, tree new_res = create_new_def_for (res, new_phi, gimple_phi_result_ptr (new_phi)); set_rename (res, new_res); - copy_loop_phi_args (phi, ibp_old_bb, new_phi, ibp_new_bb, true); + codegen_error = !copy_loop_phi_args (phi, ibp_old_bb, new_phi, + ibp_new_bb, true); update_stmt (new_phi); } @@ -2126,7 +2128,9 @@ translate_isl_ast_to_gimple::copy_loop_close_phi_args (basic_block old_bb, /* A close phi must come from a loop-phi having an init value. */ if (!init) { - gcc_assert (postpone); + if (!postpone) + return false; + region->incomplete_phis.safe_push (std::make_pair (phi, new_phi)); if (dump_file) { @@ -2199,7 +2203,7 @@ add_phi_arg_for_new_expr (tree old_phi_args[2], tree new_phi_args[2], gphi *phi, gphi *new_phi, basic_block new_bb) { - basic_block def_pred[2]; + basic_block def_pred[2] = { NULL, NULL }; int not_found_bb_index = -1; for (int i = 0; i < 2; i++) { @@ -2208,11 +2212,14 @@ add_phi_arg_for_new_expr (tree old_phi_args[2], tree new_phi_args[2], if (TREE_CODE (old_phi_args[i]) == INTEGER_CST) def_pred[i] = get_def_bb_for_const (new_bb, gimple_phi_arg_edge (phi, i)->src); - else + else if (new_phi_args[i] && (TREE_CODE (new_phi_args[i]) == SSA_NAME)) def_pred[i] = gimple_bb (SSA_NAME_DEF_STMT (new_phi_args[i])); + if (!def_pred[i]) { - gcc_assert (not_found_bb_index == -1); + /* When non are available bail out. */ + if (not_found_bb_index != -1) + return false; not_found_bb_index = i;
[PATCH 2/2] Remove individial dependence pointers and add a scop::dependence to contain all the dependence.
Removed the member variables which are only used in scop_get_dependence. Instead only maintaining the overall dependence. Passes regtest and bootstrap. gcc/ChangeLog: 2015-12-15 hiraditya * graphite-dependences.c (scop_get_dependences): Use local pointers. * graphite-isl-ast-to-gimple.c(translate_isl_ast_to_gimple::scop_to_isl_ast): Use scop->dependence. * graphite-optimize-isl.c (optimize_isl): Same. * graphite-poly.c (new_scop): Remove initialization of removed members. (free_scop): Same. * graphite.h (struct scop): Remove individial dependence pointers and add a scop::dependence to contain all the dependence. --- gcc/graphite-dependences.c | 56 gcc/graphite-isl-ast-to-gimple.c | 7 ++--- gcc/graphite-optimize-isl.c | 12 - gcc/graphite-poly.c | 43 -- gcc/graphite.h | 9 ++- 5 files changed, 55 insertions(+), 72 deletions(-) diff --git a/gcc/graphite-dependences.c b/gcc/graphite-dependences.c index bb81ae3..b34ed77 100644 --- a/gcc/graphite-dependences.c +++ b/gcc/graphite-dependences.c @@ -376,28 +376,32 @@ compute_deps (scop_p scop, vec pbbs, isl_union_map * scop_get_dependences (scop_p scop) { - isl_union_map *dependences; - - if (!scop->must_raw) -compute_deps (scop, scop->pbbs, - &scop->must_raw, &scop->may_raw, - &scop->must_raw_no_source, &scop->may_raw_no_source, - &scop->must_war, &scop->may_war, - &scop->must_war_no_source, &scop->may_war_no_source, - &scop->must_waw, &scop->may_waw, - &scop->must_waw_no_source, &scop->may_waw_no_source); - - dependences = isl_union_map_copy (scop->must_raw); - dependences = isl_union_map_union (dependences, -isl_union_map_copy (scop->must_war)); - dependences = isl_union_map_union (dependences, -isl_union_map_copy (scop->must_waw)); - dependences = isl_union_map_union (dependences, -isl_union_map_copy (scop->may_raw)); - dependences = isl_union_map_union (dependences, -isl_union_map_copy (scop->may_war)); - dependences = isl_union_map_union (dependences, -isl_union_map_copy (scop->may_waw)); + if (scop->dependence) +return scop->dependence; + + /* The original dependence relations: + RAW are read after write dependences, + WAR are write after read dependences, + WAW are write after write dependences. */ + isl_union_map *must_raw = NULL, *may_raw = NULL, *must_raw_no_source = NULL, + *may_raw_no_source = NULL, *must_war = NULL, *may_war = NULL, + *must_war_no_source = NULL, *may_war_no_source = NULL, *must_waw = NULL, + *may_waw = NULL, *must_waw_no_source = NULL, *may_waw_no_source = NULL; + + compute_deps (scop, scop->pbbs, + &must_raw, &may_raw, + &must_raw_no_source, &may_raw_no_source, + &must_war, &may_war, + &must_war_no_source, &may_war_no_source, + &must_waw, &may_waw, + &must_waw_no_source, &may_waw_no_source); + + isl_union_map *dependences = must_raw; + dependences = isl_union_map_union (dependences, must_war); + dependences = isl_union_map_union (dependences, must_waw); + dependences = isl_union_map_union (dependences, may_raw); + dependences = isl_union_map_union (dependences, may_war); + dependences = isl_union_map_union (dependences, may_waw); if (dump_file) { @@ -406,6 +410,14 @@ scop_get_dependences (scop_p scop) fprintf (dump_file, ")\n"); } + isl_union_map_free (must_raw_no_source); + isl_union_map_free (may_raw_no_source); + isl_union_map_free (must_war_no_source); + isl_union_map_free (may_war_no_source); + isl_union_map_free (must_waw_no_source); + isl_union_map_free (may_waw_no_source); + + scop->dependence = dependences; return dependences; } diff --git a/gcc/graphite-isl-ast-to-gimple.c b/gcc/graphite-isl-ast-to-gimple.c index ed2a896..af54109 100644 --- a/gcc/graphite-isl-ast-to-gimple.c +++ b/gcc/graphite-isl-ast-to-gimple.c @@ -3203,18 +3203,15 @@ translate_isl_ast_to_gimple::scop_to_isl_ast (scop_p scop, ivs_params &ip) isl_union_map *schedule_isl = generate_isl_schedule (scop); isl_ast_build *context_isl = generate_isl_context (scop); context_isl = set_options (context_isl, schedule_isl); - isl_union_map *dependences = NULL; if (flag_loop_parallelize_all) { - dependences = scop_get_dependences (scop); + isl_union_map *dependence
[PATCH 1/2] [graphite] Use refs instead of values.
Passes bootstrap and regtest. gcc/ChangeLog: 2015-12-15 hiraditya * graphite-sese-to-poly.c (build_poly_sr): Use refs. --- gcc/graphite-sese-to-poly.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gcc/graphite-sese-to-poly.c b/gcc/graphite-sese-to-poly.c index 480c552..ff45599 100644 --- a/gcc/graphite-sese-to-poly.c +++ b/gcc/graphite-sese-to-poly.c @@ -1064,8 +1064,8 @@ build_poly_sr (poly_bb_p pbb) { scop_p scop = PBB_SCOP (pbb); gimple_poly_bb_p gbb = PBB_BLACK_BOX (pbb); - vec reads = gbb->read_scalar_refs; - vec writes = gbb->write_scalar_refs; + vec &reads = gbb->read_scalar_refs; + vec &writes = gbb->write_scalar_refs; isl_space *dc = isl_set_get_space (pbb->domain); int nb_out = 1; -- 2.1.4
[PATCH] Use const-ref instead of values for sese_l passed to functions.
gcc/ChangeLog: 2015-12-24 hiraditya * graphite-sese-to-poly.c (build_loop_iteration_domains): Use ref instead of value. * sese.c (invariant_in_sese_p_rec): Use const ref instead of value. (scalar_evolution_in_region): Same * sese.h (bb_in_region): Same (bb_in_sese_p): Same. (stmt_in_sese_p): Same. (defined_in_sese_p): Same. (loop_in_sese_p): Same. --- gcc/graphite-sese-to-poly.c | 2 +- gcc/sese.c | 4 ++-- gcc/sese.h | 14 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/gcc/graphite-sese-to-poly.c b/gcc/graphite-sese-to-poly.c index 7992c28..a7fd5d9 100644 --- a/gcc/graphite-sese-to-poly.c +++ b/gcc/graphite-sese-to-poly.c @@ -465,7 +465,7 @@ build_loop_iteration_domains (scop_p scop, struct loop *loop, { tree nb_iters = number_of_latch_executions (loop); - sese_l region = scop->scop_info->region; + const sese_l& region = scop->scop_info->region; gcc_assert (loop_in_sese_p (loop, region)); isl_set *inner = isl_set_copy (outer); diff --git a/gcc/sese.c b/gcc/sese.c index 74dc4ac..b0f54de 100644 --- a/gcc/sese.c +++ b/gcc/sese.c @@ -523,7 +523,7 @@ set_ifsese_condition (ifsese if_region, tree condition) when T depends on memory that may change in REGION. */ bool -invariant_in_sese_p_rec (tree t, sese_l ®ion, bool *has_vdefs) +invariant_in_sese_p_rec (tree t, const sese_l ®ion, bool *has_vdefs) { if (!defined_in_sese_p (t, region)) return true; @@ -596,7 +596,7 @@ scev_analyzable_p (tree def, sese_l ®ion) is not defined in the REGION is considered a parameter. */ tree -scalar_evolution_in_region (sese_l ®ion, loop_p loop, tree t) +scalar_evolution_in_region (const sese_l ®ion, loop_p loop, tree t) { gimple *def; struct loop *def_loop; diff --git a/gcc/sese.h b/gcc/sese.h index 626a077..99df354 100644 --- a/gcc/sese.h +++ b/gcc/sese.h @@ -109,9 +109,9 @@ extern void free_sese_info (sese_info_p); extern void sese_insert_phis_for_liveouts (sese_info_p, basic_block, edge, edge); extern void build_sese_loop_nests (sese_info_p); extern struct loop *outermost_loop_in_sese (sese_l &, basic_block); -extern tree scalar_evolution_in_region (sese_l &, loop_p, tree); +extern tree scalar_evolution_in_region (const sese_l &, loop_p, tree); extern bool scev_analyzable_p (tree, sese_l &); -extern bool invariant_in_sese_p_rec (tree, sese_l &, bool *); +extern bool invariant_in_sese_p_rec (tree, const sese_l &, bool *); /* Check that SESE contains LOOP. */ @@ -133,7 +133,7 @@ sese_nb_params (sese_info_p region) EXIT blocks. */ static inline bool -bb_in_region (basic_block bb, basic_block entry, basic_block exit) +bb_in_region (const_basic_block bb, const_basic_block entry, const_basic_block exit) { /* FIXME: PR67842. */ #if 0 @@ -158,7 +158,7 @@ bb_in_region (basic_block bb, basic_block entry, basic_block exit) EXIT blocks. */ static inline bool -bb_in_sese_p (basic_block bb, sese_l &r) +bb_in_sese_p (basic_block bb, const sese_l &r) { return bb_in_region (bb, r.entry->dest, r.exit->dest); } @@ -166,7 +166,7 @@ bb_in_sese_p (basic_block bb, sese_l &r) /* Returns true when STMT is defined in REGION. */ static inline bool -stmt_in_sese_p (gimple *stmt, sese_l &r) +stmt_in_sese_p (gimple *stmt, const sese_l &r) { basic_block bb = gimple_bb (stmt); return bb && bb_in_sese_p (bb, r); @@ -175,7 +175,7 @@ stmt_in_sese_p (gimple *stmt, sese_l &r) /* Returns true when NAME is defined in REGION. */ static inline bool -defined_in_sese_p (tree name, sese_l &r) +defined_in_sese_p (tree name, const sese_l &r) { return stmt_in_sese_p (SSA_NAME_DEF_STMT (name), r); } @@ -183,7 +183,7 @@ defined_in_sese_p (tree name, sese_l &r) /* Returns true when LOOP is in REGION. */ static inline bool -loop_in_sese_p (struct loop *loop, sese_l ®ion) +loop_in_sese_p (struct loop *loop, const sese_l ®ion) { return (bb_in_sese_p (loop->header, region) && bb_in_sese_p (loop->latch, region)); -- 2.1.4
[PATCH] [graphite] PR67842 Remove dead code.
This check is not relevant anymore. Removing. gcc/ChangeLog: 2015-12-24 hiraditya * sese.h (bb_in_region): Remove dead code. --- gcc/sese.h | 14 -- 1 file changed, 14 deletions(-) diff --git a/gcc/sese.h b/gcc/sese.h index 99df354..f7e5570 100644 --- a/gcc/sese.h +++ b/gcc/sese.h @@ -135,20 +135,6 @@ sese_nb_params (sese_info_p region) static inline bool bb_in_region (const_basic_block bb, const_basic_block entry, const_basic_block exit) { - /* FIXME: PR67842. */ -#if 0 - if (flag_checking) -{ - edge e; - edge_iterator ei; - - /* Check that there are no edges coming in the region: all the -predecessors of EXIT are dominated by ENTRY. */ - FOR_EACH_EDGE (e, ei, exit->preds) - gcc_assert (dominated_by_p (CDI_DOMINATORS, e->src, entry)); -} -#endif - return dominated_by_p (CDI_DOMINATORS, bb, entry) && !(dominated_by_p (CDI_DOMINATORS, bb, exit) && !dominated_by_p (CDI_DOMINATORS, entry, exit)); -- 2.1.4