aboutsummaryrefslogtreecommitdiff
path: root/gcc/graphite-scop-detection.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2017-10-06 07:06:17 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2017-10-06 07:06:17 +0000
commitbd8d431f44377efe110b02163d693e60421acdeb (patch)
tree9f466b7e6ad425f1e3c4ebe0ce5cfca37581f726 /gcc/graphite-scop-detection.c
parent57cfa172280fd4a79a1d4120b69054457100af94 (diff)
downloadgcc-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.c181
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. */