diff options
author | Richard Biener <rguenther@suse.de> | 2017-10-06 07:06:17 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2017-10-06 07:06:17 +0000 |
commit | bd8d431f44377efe110b02163d693e60421acdeb (patch) | |
tree | 9f466b7e6ad425f1e3c4ebe0ce5cfca37581f726 /gcc/graphite-scop-detection.c | |
parent | 57cfa172280fd4a79a1d4120b69054457100af94 (diff) | |
download | gcc-bd8d431f44377efe110b02163d693e60421acdeb.zip gcc-bd8d431f44377efe110b02163d693e60421acdeb.tar.gz gcc-bd8d431f44377efe110b02163d693e60421acdeb.tar.bz2 |
graphite-isl-ast-to-gimple.c: Include ssa.h and tree-ssa.h.
2017-10-06 Richard Biener <rguenther@suse.de>
* graphite-isl-ast-to-gimple.c: Include ssa.h and tree-ssa.h.
(translate_isl_ast_to_gimple::translate_pending_phi_nodes,
translate_isl_ast_to_gimple::is_valid_rename,
translate_isl_ast_to_gimple::get_rename,
translate_isl_ast_to_gimple::get_def_bb_for_const,
translate_isl_ast_to_gimple::get_new_name,
translate_isl_ast_to_gimple::collect_all_ssa_names,
translate_isl_ast_to_gimple::copy_loop_phi_args,
translate_isl_ast_to_gimple::collect_all_ssa_names,
translate_isl_ast_to_gimple::copy_loop_phi_args,
translate_isl_ast_to_gimple::copy_loop_phi_nodes,
translate_isl_ast_to_gimple::add_close_phis_to_merge_points,
translate_isl_ast_to_gimple::add_close_phis_to_outer_loops,
translate_isl_ast_to_gimple::copy_loop_close_phi_args,
translate_isl_ast_to_gimple::copy_loop_close_phi_nodes,
translate_isl_ast_to_gimple::copy_cond_phi_args,
translate_isl_ast_to_gimple::copy_cond_phi_nodes,
translate_isl_ast_to_gimple::edge_for_new_close_phis,
translate_isl_ast_to_gimple::add_phi_arg_for_new_expr,
translate_isl_ast_to_gimple::rename_uses,
translate_isl_ast_to_gimple::rename_all_uses): Remove.
(translate_isl_ast_to_gimple::get_rename_from_scev): Simplify.
(set_rename_for_each_def): Likewise.
(graphite_copy_stmts_from_block): Handle debug stmt resetting
here. Handle rewriting SCEV analyzable uses here.
(copy_bb_and_scalar_dependences): Generate code for PHI
copy-in/outs.
(graphite_regenerate_ast_isl): Adjust.
* graphite-scop-detection.c (trivially_empty_bb_p): Move to sese.[ch].
(add_write, add_read): New functions.
(build_cross_bb_scalars_def): Use it and simplify.
(build_cross_bb_scalars_use): Likewise.
(graphite_find_cross_bb_scalar_vars): Inline into...
(try_generate_gimple_bb): ...here. Add dependences for PHIs,
simulating out-of-SSA. Compute liveout and add dependencies.
(build_scops): Force an empty entry block.
* sese.h (sese_info_t::liveout, sese_info_t::debug_liveout): New
members.
(sese_build_liveouts): Declare.
(sese_trivially_empty_bb_p): Likewise.
* sese.c (sese_build_liveouts_bb): Properly handle PHIs,
compute liveout and debug_liveout.
(sese_bad_liveouts_use): Remove.
(sese_reset_debug_liveouts_bb): Likewise.
(sese_reset_debug_liveouts): Rewrite in terms of debug_liveout.
(sese_build_liveouts): Build liveout and debug_liveout and store
it in region.
(new_sese_info): Adjust.
(free_sese_info): Likewise.
(sese_insert_phis_for_liveouts): Reset debug stmts from here,
do not build liveout here.
(move_sese_in_condition): Adjust region entry.
(scev_analyzable_p): Match up with chrec_apply requirements.
(sese_trivially_empty_bb_p): New.
* tree-into-ssa.c (get_reaching_def): Properly support generating
default-defs for incremental rewrite of anonymous names.
* gcc.dg/graphite/id-15.c: No longer expect a code generation error.
* gcc.dg/graphite/id-16.c: Likewise.
* gcc.dg/graphite/pr46168.c: Likewise.
* gcc.dg/graphite/pr68756.c: Likewise.
* gcc.dg/graphite/pr69728.c: Likewise.
* gcc.dg/graphite/pr71575-2.c: Likewise.
* gcc.dg/graphite/pr77362.c: Likewise.
* gcc.dg/graphite/pr81373.c: Likewise.
* gcc.dg/graphite/run-id-pr67700-1.c: Likewise.
* gfortran.dg/graphite/interchange-1.f: Likewise.
* gfortran.dg/graphite/pr42334-1.f: Likewise.
* gfortran.dg/graphite/pr42393-1.f90: Likewise.
* gfortran.dg/graphite/pr42393.f90: Likewise.
* gfortran.dg/graphite/pr47019.f: Likewise.
* gfortran.dg/graphite/id-17.f: Likewise.
* gfortran.dg/graphite/id-19.f: Likewise.
* gfortran.dg/graphite/run-id-2.f90: Likewise.
* gfortran.dg/graphite/pr42326-1.f90: Likewise.
* gfortran.dg/graphite/pr42326.f90: Likewise.
* gfortran.dg/graphite/pr68550-2.f90: Likewise.
* gfortran.dg/graphite/pr29581.f90: Likewise. No longer expect
a code generation error.
* gfortran.dg/graphite/run-id-3.f90: Likewise.
* gfortran.dg/graphite/pr29832.f90: Likewise.
From-SVN: r253475
Diffstat (limited to 'gcc/graphite-scop-detection.c')
-rw-r--r-- | gcc/graphite-scop-detection.c | 181 |
1 files changed, 111 insertions, 70 deletions
diff --git a/gcc/graphite-scop-detection.c b/gcc/graphite-scop-detection.c index eed4efa..93ab035 100644 --- a/gcc/graphite-scop-detection.c +++ b/gcc/graphite-scop-detection.c @@ -254,21 +254,6 @@ dot_cfg () scops.release (); } -/* Return true if BB is empty, contains only DEBUG_INSNs. */ - -static bool -trivially_empty_bb_p (basic_block bb) -{ - gimple_stmt_iterator gsi; - - for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - if (gimple_code (gsi_stmt (gsi)) != GIMPLE_DEBUG - && gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL) - return false; - - return true; -} - /* Can all ivs be represented by a signed integer? As isl might generate negative values in its expressions, signed loop ivs are required in the backend. */ @@ -471,7 +456,7 @@ scop_detection::get_sese (loop_p loop) canonicalize_loop_closed_ssa makes sure that is in proper shape. */ if (! single_pred_p (scop_end->dest) || ! single_succ_p (scop_end->dest) - || ! trivially_empty_bb_p (scop_end->dest)) + || ! sese_trivially_empty_bb_p (scop_end->dest)) gcc_unreachable (); scop_end = single_succ_edge (scop_end->dest); @@ -1346,13 +1331,35 @@ find_scop_parameters (scop_p scop) scop_set_nb_params (scop, nbp); } +static void +add_write (vec<tree> *writes, tree def) +{ + writes->safe_push (def); + DEBUG_PRINT (dp << "Adding scalar write: "; + print_generic_expr (dump_file, def); + dp << "\nFrom stmt: "; + print_gimple_stmt (dump_file, + SSA_NAME_DEF_STMT (def), 0)); +} + +static void +add_read (vec<scalar_use> *reads, tree use, gimple *use_stmt) +{ + DEBUG_PRINT (dp << "Adding scalar read: "; + print_generic_expr (dump_file, use); + dp << "\nFrom stmt: "; + print_gimple_stmt (dump_file, use_stmt, 0)); + reads->safe_push (std::make_pair (use_stmt, use)); +} + + /* Record DEF if it is used in other bbs different than DEF_BB in the SCOP. */ static void build_cross_bb_scalars_def (scop_p scop, tree def, basic_block def_bb, vec<tree> *writes) { - if (!def || !is_gimple_reg (def)) + if (!is_gimple_reg (def)) return; bool scev_analyzable = scev_analyzable_p (def, scop->scop_info->region); @@ -1366,16 +1373,9 @@ build_cross_bb_scalars_def (scop_p scop, tree def, basic_block def_bb, /* But gather SESE liveouts as we otherwise fail to rewrite their exit PHIs. */ || ! bb_in_sese_p (gimple_bb (use_stmt), scop->scop_info->region)) - && ((def_bb != gimple_bb (use_stmt) && !is_gimple_debug (use_stmt)) - /* PHIs have their effect at "BBs" on the edges. See PR79622. */ - || gimple_code (SSA_NAME_DEF_STMT (def)) == GIMPLE_PHI)) + && (def_bb != gimple_bb (use_stmt) && !is_gimple_debug (use_stmt))) { - writes->safe_push (def); - DEBUG_PRINT (dp << "Adding scalar write: "; - print_generic_expr (dump_file, def); - dp << "\nFrom stmt: "; - print_gimple_stmt (dump_file, - SSA_NAME_DEF_STMT (def), 0)); + add_write (writes, def); /* This is required by the FOR_EACH_IMM_USE_STMT when we want to break before all the uses have been visited. */ BREAK_FROM_IMM_USE_STMT (imm_iter); @@ -1389,7 +1389,6 @@ static void build_cross_bb_scalars_use (scop_p scop, tree use, gimple *use_stmt, vec<scalar_use> *reads) { - gcc_assert (use); if (!is_gimple_reg (use)) return; @@ -1399,46 +1398,8 @@ build_cross_bb_scalars_use (scop_p scop, tree use, gimple *use_stmt, return; gimple *def_stmt = SSA_NAME_DEF_STMT (use); - if (gimple_bb (def_stmt) != gimple_bb (use_stmt) - /* PHIs have their effect at "BBs" on the edges. See PR79622. */ - || gimple_code (def_stmt) == GIMPLE_PHI) - { - DEBUG_PRINT (dp << "Adding scalar read: "; - print_generic_expr (dump_file, use); - dp << "\nFrom stmt: "; - print_gimple_stmt (dump_file, use_stmt, 0)); - reads->safe_push (std::make_pair (use_stmt, use)); - } -} - -/* Record all scalar variables that are defined and used in different BBs of the - SCOP. */ - -static void -graphite_find_cross_bb_scalar_vars (scop_p scop, gimple *stmt, - vec<scalar_use> *reads, vec<tree> *writes) -{ - tree def; - - if (gimple_code (stmt) == GIMPLE_ASSIGN) - def = gimple_assign_lhs (stmt); - else if (gimple_code (stmt) == GIMPLE_CALL) - def = gimple_call_lhs (stmt); - else if (gimple_code (stmt) == GIMPLE_PHI) - def = gimple_phi_result (stmt); - else - return; - - - build_cross_bb_scalars_def (scop, def, gimple_bb (stmt), writes); - - ssa_op_iter iter; - use_operand_p use_p; - FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, iter, SSA_OP_USE) - { - tree use = USE_FROM_PTR (use_p); - build_cross_bb_scalars_use (scop, use, stmt, reads); - } + if (gimple_bb (def_stmt) != gimple_bb (use_stmt)) + add_read (reads, use, use_stmt); } /* Generates a polyhedral black box only if the bb contains interesting @@ -1467,13 +1428,89 @@ try_generate_gimple_bb (scop_p scop, basic_block bb) continue; graphite_find_data_references_in_stmt (nest, loop, stmt, &drs); - graphite_find_cross_bb_scalar_vars (scop, stmt, &reads, &writes); + + tree def = gimple_get_lhs (stmt); + if (def) + build_cross_bb_scalars_def (scop, def, gimple_bb (stmt), &writes); + + ssa_op_iter iter; + tree use; + FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE) + build_cross_bb_scalars_use (scop, use, stmt, &reads); } + /* Handle defs and uses in PHIs. Those need special treatment given + that we have to present ISL with sth that looks like we've rewritten + the IL out-of-SSA. */ for (gphi_iterator psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi)) - if (!virtual_operand_p (gimple_phi_result (psi.phi ()))) - graphite_find_cross_bb_scalar_vars (scop, psi.phi (), &reads, &writes); + { + gphi *phi = psi.phi (); + tree res = gimple_phi_result (phi); + if (virtual_operand_p (res) + || scev_analyzable_p (res, scop->scop_info->region)) + continue; + /* To simulate out-of-SSA the block containing the PHI node has + reads of the PHI destination. And to preserve SSA dependences + we also write to it (the out-of-SSA decl and the SSA result + are coalesced for dependence purposes which is good enough). */ + add_read (&reads, res, phi); + add_write (&writes, res); + } + basic_block bb_for_succs = bb; + if (bb_for_succs == bb_for_succs->loop_father->latch + && bb_in_sese_p (bb_for_succs, scop->scop_info->region) + && sese_trivially_empty_bb_p (bb_for_succs)) + bb_for_succs = NULL; + while (bb_for_succs) + { + basic_block latch = NULL; + edge_iterator ei; + edge e; + FOR_EACH_EDGE (e, ei, bb_for_succs->succs) + { + for (gphi_iterator psi = gsi_start_phis (e->dest); !gsi_end_p (psi); + gsi_next (&psi)) + { + gphi *phi = psi.phi (); + tree res = gimple_phi_result (phi); + if (virtual_operand_p (res)) + continue; + /* To simulate out-of-SSA the predecessor of edges into PHI nodes + has a copy from the PHI argument to the PHI destination. */ + if (! scev_analyzable_p (res, scop->scop_info->region)) + add_write (&writes, res); + tree use = PHI_ARG_DEF_FROM_EDGE (phi, e); + if (TREE_CODE (use) == SSA_NAME + && ! SSA_NAME_IS_DEFAULT_DEF (use) + && gimple_bb (SSA_NAME_DEF_STMT (use)) != bb_for_succs + && ! scev_analyzable_p (use, scop->scop_info->region)) + add_read (&reads, use, phi); + } + if (e->dest == bb_for_succs->loop_father->latch + && bb_in_sese_p (e->dest, scop->scop_info->region) + && sese_trivially_empty_bb_p (e->dest)) + latch = e->dest; + } + /* Handle empty latch block PHIs here, otherwise we confuse ISL + with extra conditional code where it then peels off the last + iteration just because of that. It would be simplest if we + just didn't force simple latches (thus remove the forwarder). */ + bb_for_succs = latch; + } + + /* For the region exit block add reads for all live-out vars. */ + if (bb == scop->scop_info->region.exit->src) + { + sese_build_liveouts (scop->scop_info); + unsigned i; + bitmap_iterator bi; + EXECUTE_IF_SET_IN_BITMAP (scop->scop_info->liveout, 0, i, bi) + { + tree use = ssa_name (i); + add_read (&reads, use, NULL); + } + } if (drs.is_empty () && writes.is_empty () && reads.is_empty ()) return NULL; @@ -1700,6 +1737,10 @@ build_scops (vec<scop_p> *scops) sese_l *s; FOR_EACH_VEC_ELT (scops_l, i, s) { + /* For our out-of-SSA we need a block on s->entry, similar to how + we include the LCSSA block in the region. */ + s->entry = single_pred_edge (split_edge (s->entry)); + scop_p scop = new_scop (s->entry, s->exit); /* Record all basic blocks and their conditions in REGION. */ |