Postpone the rewrite out of SSA to the end of the translation to polyhedral representation.

2010-11-22  Sebastian Pop  <sebastian.pop@amd.com>

	PR middle-end/45297
	* graphite-poly.c (new_poly_bb): Returns a poly_bb_p.  Do not take
	the reduction bool in parameter.  Clear PBB_IS_REDUCTION.  Set GBB_PBB.
	* graphite-poly.h (new_poly_bb): Update declaration.
	(gbb_from_bb): Moved here...
	(pbb_from_bb): New.
	* graphite-sese-to-poly.c (var_used_in_not_loop_header_phi_node):
	Removed.
	(graphite_stmt_p): Removed.
	(try_generate_gimple_bb): Returns a gimple_bb_p.  Do not pass in
	sbitmap reductions.  Always build a gimple_bb_p.  Do not call
	new_poly_bb.
	(build_scop_bbs_1): Do not pass in sbitmap reductions.
	(build_scop_bbs): Same.
	(gbb_from_bb): ... from here.
	(add_conditions_to_constraints): Moved up.
	(analyze_drs): New.
	(build_scop_drs): Call analyze_drs.  Remove all the PBBs that do
	not contain data references.
	(new_pbb_from_pbb): New.
	(insert_out_of_ssa_copy_on_edge): Call new_pbb_from_pbb after a
	block is split.
	(rewrite_close_phi_out_of_ssa): Update call to
	insert_out_of_ssa_copy_on_edge.
	(rewrite_reductions_out_of_ssa): Now static.
	(rewrite_cross_bb_scalar_deps_out_of_ssa): Same.
	(split_pbb): New.
	(split_reduction_stmt): Call split_pbb.
	(translate_scalar_reduction_to_array): Pass in the scop, do not
	pass in the sbitmap reductions.
	(rewrite_commutative_reductions_out_of_ssa_close_phi): Same.
	(rewrite_commutative_reductions_out_of_ssa_loop): Same.
	(rewrite_commutative_reductions_out_of_ssa): Same.
	(build_poly_scop): Call build_scop_bbs,
	rewrite_commutative_reductions_out_of_ssa,
	rewrite_reductions_out_of_ssa, and
	rewrite_cross_bb_scalar_deps_out_of_ssa.  Move build_scop_drs
	before scop_to_lst.
	* graphite-sese-to-poly.h (rewrite_commutative_reductions_out_of_ssa):
	Removed declaration.
	(rewrite_reductions_out_of_ssa): Same.
	(rewrite_cross_bb_scalar_deps_out_of_ssa): Same.
	(build_scop_bbs): Same.
	* graphite.c (graphite_transform_loops): Do not initialize reductions.
	Do not call build_scop_bbs,
	rewrite_commutative_reductions_out_of_ssa,
	rewrite_reductions_out_of_ssa, and
	rewrite_cross_bb_scalar_deps_out_of_ssa.
	* sese.h (struct gimple_bb): Add field pbb.
	(GBB_PBB): New.

	* gcc.dg/graphite/pr45297.c: New.

From-SVN: r167348
This commit is contained in:
Sebastian Pop 2010-12-01 17:25:10 +00:00 committed by Sebastian Pop
parent 70a2ae0f45
commit efa213905e
10 changed files with 337 additions and 203 deletions

View File

@ -1,3 +1,56 @@
2010-12-01 Sebastian Pop <sebastian.pop@amd.com>
PR middle-end/45297
* graphite-poly.c (new_poly_bb): Returns a poly_bb_p. Do not take
the reduction bool in parameter. Clear PBB_IS_REDUCTION. Set GBB_PBB.
* graphite-poly.h (new_poly_bb): Update declaration.
(gbb_from_bb): Moved here...
(pbb_from_bb): New.
* graphite-sese-to-poly.c (var_used_in_not_loop_header_phi_node):
Removed.
(graphite_stmt_p): Removed.
(try_generate_gimple_bb): Returns a gimple_bb_p. Do not pass in
sbitmap reductions. Always build a gimple_bb_p. Do not call
new_poly_bb.
(build_scop_bbs_1): Do not pass in sbitmap reductions.
(build_scop_bbs): Same.
(gbb_from_bb): ... from here.
(add_conditions_to_constraints): Moved up.
(analyze_drs): New.
(build_scop_drs): Call analyze_drs. Remove all the PBBs that do
not contain data references.
(new_pbb_from_pbb): New.
(insert_out_of_ssa_copy_on_edge): Call new_pbb_from_pbb after a
block is split.
(rewrite_close_phi_out_of_ssa): Update call to
insert_out_of_ssa_copy_on_edge.
(rewrite_reductions_out_of_ssa): Now static.
(rewrite_cross_bb_scalar_deps_out_of_ssa): Same.
(split_pbb): New.
(split_reduction_stmt): Call split_pbb.
(translate_scalar_reduction_to_array): Pass in the scop, do not
pass in the sbitmap reductions.
(rewrite_commutative_reductions_out_of_ssa_close_phi): Same.
(rewrite_commutative_reductions_out_of_ssa_loop): Same.
(rewrite_commutative_reductions_out_of_ssa): Same.
(build_poly_scop): Call build_scop_bbs,
rewrite_commutative_reductions_out_of_ssa,
rewrite_reductions_out_of_ssa, and
rewrite_cross_bb_scalar_deps_out_of_ssa. Move build_scop_drs
before scop_to_lst.
* graphite-sese-to-poly.h (rewrite_commutative_reductions_out_of_ssa):
Removed declaration.
(rewrite_reductions_out_of_ssa): Same.
(rewrite_cross_bb_scalar_deps_out_of_ssa): Same.
(build_scop_bbs): Same.
* graphite.c (graphite_transform_loops): Do not initialize reductions.
Do not call build_scop_bbs,
rewrite_commutative_reductions_out_of_ssa,
rewrite_reductions_out_of_ssa, and
rewrite_cross_bb_scalar_deps_out_of_ssa.
* sese.h (struct gimple_bb): Add field pbb.
(GBB_PBB): New.
2010-12-01 Sebastian Pop <sebastian.pop@amd.com>
* graphite-sese-to-poly.c (handle_scalar_deps_crossing_scop_limits):

View File

@ -1,3 +1,58 @@
2010-11-22 Sebastian Pop <sebastian.pop@amd.com>
PR middle-end/45297
* graphite-poly.c (new_poly_bb): Returns a poly_bb_p. Do not take
the reduction bool in parameter. Clear PBB_IS_REDUCTION. Set GBB_PBB.
* graphite-poly.h (new_poly_bb): Update declaration.
(gbb_from_bb): Moved here...
(pbb_from_bb): New.
* graphite-sese-to-poly.c (var_used_in_not_loop_header_phi_node):
Removed.
(graphite_stmt_p): Removed.
(try_generate_gimple_bb): Returns a gimple_bb_p. Do not pass in
sbitmap reductions. Always build a gimple_bb_p. Do not call
new_poly_bb.
(build_scop_bbs_1): Do not pass in sbitmap reductions.
(build_scop_bbs): Same.
(gbb_from_bb): ... from here.
(add_conditions_to_constraints): Moved up.
(analyze_drs): New.
(build_scop_drs): Call analyze_drs. Remove all the PBBs that do
not contain data references.
(new_pbb_from_pbb): New.
(insert_out_of_ssa_copy_on_edge): Call new_pbb_from_pbb after a
block is split.
(rewrite_close_phi_out_of_ssa): Update call to
insert_out_of_ssa_copy_on_edge.
(rewrite_reductions_out_of_ssa): Now static.
(rewrite_cross_bb_scalar_deps_out_of_ssa): Same.
(split_pbb): New.
(split_reduction_stmt): Call split_pbb.
(translate_scalar_reduction_to_array): Pass in the scop, do not
pass in the sbitmap reductions.
(rewrite_commutative_reductions_out_of_ssa_close_phi): Same.
(rewrite_commutative_reductions_out_of_ssa_loop): Same.
(rewrite_commutative_reductions_out_of_ssa): Same.
(build_poly_scop): Call build_scop_bbs,
rewrite_commutative_reductions_out_of_ssa,
rewrite_reductions_out_of_ssa, and
rewrite_cross_bb_scalar_deps_out_of_ssa. Move build_scop_drs
before scop_to_lst.
* graphite-sese-to-poly.h (rewrite_commutative_reductions_out_of_ssa):
Removed declaration.
(rewrite_reductions_out_of_ssa): Same.
(rewrite_cross_bb_scalar_deps_out_of_ssa): Same.
(build_scop_bbs): Same.
* graphite.c (graphite_transform_loops): Do not initialize reductions.
Do not call build_scop_bbs,
rewrite_commutative_reductions_out_of_ssa,
rewrite_reductions_out_of_ssa, and
rewrite_cross_bb_scalar_deps_out_of_ssa.
* sese.h (struct gimple_bb): Add field pbb.
(GBB_PBB): New.
* gcc.dg/graphite/pr45297.c: New.
2010-11-22 Sebastian Pop <sebastian.pop@amd.com>
* graphite-sese-to-poly.c (handle_scalar_deps_crossing_scop_limits):

View File

@ -874,8 +874,8 @@ free_poly_dr (poly_dr_p pdr)
/* Create a new polyhedral black box. */
void
new_poly_bb (scop_p scop, void *black_box, bool reduction)
poly_bb_p
new_poly_bb (scop_p scop, void *black_box)
{
poly_bb_p pbb = XNEW (struct poly_bb);
@ -886,9 +886,11 @@ new_poly_bb (scop_p scop, void *black_box, bool reduction)
PBB_SAVED (pbb) = NULL;
PBB_ORIGINAL (pbb) = NULL;
PBB_DRS (pbb) = VEC_alloc (poly_dr_p, heap, 3);
PBB_IS_REDUCTION (pbb) = reduction;
PBB_IS_REDUCTION (pbb) = false;
PBB_PDR_DUPLICATES_REMOVED (pbb) = false;
VEC_safe_push (poly_bb_p, heap, SCOP_BBS (scop), pbb);
GBB_PBB ((gimple_bb_p) black_box) = pbb;
return pbb;
}
/* Free polyhedral black box. */

View File

@ -389,7 +389,7 @@ struct poly_bb
#define PBB_PDR_DUPLICATES_REMOVED(PBB) (PBB->pdr_duplicates_removed)
#define PBB_IS_REDUCTION(PBB) (PBB->is_reduction)
extern void new_poly_bb (scop_p, void *, bool);
extern poly_bb_p new_poly_bb (scop_p, void *);
extern void free_poly_bb (poly_bb_p);
extern void debug_loop_vec (poly_bb_p);
extern void schedule_to_scattering (poly_bb_p, int);
@ -434,6 +434,22 @@ number_of_write_pdrs (poly_bb_p pbb)
return res;
}
/* Returns a gimple_bb from BB. */
static inline gimple_bb_p
gbb_from_bb (basic_block bb)
{
return (gimple_bb_p) bb->aux;
}
/* The poly_bb of the BB. */
static inline poly_bb_p
pbb_from_bb (basic_block bb)
{
return GBB_PBB (gbb_from_bb (bb));
}
/* The basic block of the PBB. */
static inline basic_block

View File

@ -49,27 +49,6 @@ along with GCC; see the file COPYING3. If not see
#include "graphite-scop-detection.h"
#include "graphite-sese-to-poly.h"
/* Check if VAR is used in a phi node, that is no loop header. */
static bool
var_used_in_not_loop_header_phi_node (tree var)
{
imm_use_iterator imm_iter;
gimple stmt;
bool result = false;
FOR_EACH_IMM_USE_STMT (stmt, imm_iter, var)
{
basic_block bb = gimple_bb (stmt);
if (gimple_code (stmt) == GIMPLE_PHI
&& bb->loop_father->header != bb)
result = true;
}
return result;
}
/* Returns the index of the PHI argument defined in the outermost
loop. */
@ -196,58 +175,6 @@ reduction_phi_p (sese region, gimple_stmt_iterator *psi)
return true;
}
/* Returns true when BB will be represented in graphite. Return false
for the basic blocks that contain code eliminated in the code
generation pass: i.e. induction variables and exit conditions. */
static bool
graphite_stmt_p (sese region, basic_block bb,
VEC (data_reference_p, heap) *drs)
{
gimple_stmt_iterator gsi;
loop_p loop = bb->loop_father;
if (VEC_length (data_reference_p, drs) > 0)
return true;
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
gimple stmt = gsi_stmt (gsi);
switch (gimple_code (stmt))
{
case GIMPLE_DEBUG:
/* Control flow expressions can be ignored, as they are
represented in the iteration domains and will be
regenerated by graphite. */
case GIMPLE_COND:
case GIMPLE_GOTO:
case GIMPLE_SWITCH:
break;
case GIMPLE_ASSIGN:
{
tree var = gimple_assign_lhs (stmt);
/* We need these bbs to be able to construct the phi nodes. */
if (var_used_in_not_loop_header_phi_node (var))
return true;
var = scalar_evolution_in_region (region, loop, var);
if (chrec_contains_undetermined (var))
return true;
break;
}
default:
return true;
}
}
return false;
}
/* Store the GRAPHITE representation of BB. */
static gimple_bb_p
@ -330,8 +257,8 @@ free_scops (VEC (scop_p, heap) *scops)
/* Generates a polyhedral black box only if the bb contains interesting
information. */
static void
try_generate_gimple_bb (scop_p scop, basic_block bb, sbitmap reductions)
static gimple_bb_p
try_generate_gimple_bb (scop_p scop, basic_block bb)
{
VEC (data_reference_p, heap) *drs = VEC_alloc (data_reference_p, heap, 5);
loop_p nest = outermost_loop_in_sese (SCOP_REGION (scop), bb);
@ -344,11 +271,7 @@ try_generate_gimple_bb (scop_p scop, basic_block bb, sbitmap reductions)
graphite_find_data_references_in_stmt (nest, stmt, &drs);
}
if (!graphite_stmt_p (SCOP_REGION (scop), bb, drs))
free_data_refs (drs);
else
new_poly_bb (scop, new_gimple_bb (bb, drs), TEST_BIT (reductions,
bb->index));
return new_gimple_bb (bb, drs);
}
/* Returns true if all predecessors of BB, that are not dominated by BB, are
@ -400,16 +323,18 @@ graphite_sort_dominated_info (VEC (basic_block, heap) *dom)
/* Recursive helper function for build_scops_bbs. */
static void
build_scop_bbs_1 (scop_p scop, sbitmap visited, basic_block bb, sbitmap reductions)
build_scop_bbs_1 (scop_p scop, sbitmap visited, basic_block bb)
{
sese region = SCOP_REGION (scop);
VEC (basic_block, heap) *dom;
poly_bb_p pbb;
if (TEST_BIT (visited, bb->index)
|| !bb_in_sese_p (bb, region))
return;
try_generate_gimple_bb (scop, bb, reductions);
pbb = new_poly_bb (scop, try_generate_gimple_bb (scop, bb));
VEC_safe_push (poly_bb_p, heap, SCOP_BBS (scop), pbb);
SET_BIT (visited, bb->index);
dom = get_dominated_by (CDI_DOMINATORS, bb);
@ -427,7 +352,7 @@ build_scop_bbs_1 (scop_p scop, sbitmap visited, basic_block bb, sbitmap reductio
FOR_EACH_VEC_ELT (basic_block, dom, i, dom_bb)
if (all_non_dominated_preds_marked_p (dom_bb, visited))
{
build_scop_bbs_1 (scop, visited, dom_bb, reductions);
build_scop_bbs_1 (scop, visited, dom_bb);
VEC_unordered_remove (basic_block, dom, i);
break;
}
@ -438,14 +363,14 @@ build_scop_bbs_1 (scop_p scop, sbitmap visited, basic_block bb, sbitmap reductio
/* Gather the basic blocks belonging to the SCOP. */
void
build_scop_bbs (scop_p scop, sbitmap reductions)
static void
build_scop_bbs (scop_p scop)
{
sbitmap visited = sbitmap_alloc (last_basic_block);
sese region = SCOP_REGION (scop);
sbitmap_zero (visited);
build_scop_bbs_1 (scop, visited, SESE_ENTRY_BB (region), reductions);
build_scop_bbs_1 (scop, visited, SESE_ENTRY_BB (region));
sbitmap_free (visited);
}
@ -1004,14 +929,6 @@ find_scop_parameters (scop_p scop)
(&SCOP_CONTEXT (scop), scop_nb_params (scop), 0);
}
/* Returns a gimple_bb from BB. */
static inline gimple_bb_p
gbb_from_bb (basic_block bb)
{
return (gimple_bb_p) bb->aux;
}
/* Insert in the SCOP context constraints from the estimation of the
number of iterations. UB_EXPR is a linear expression describing
the number of iterations in a loop. This expression is bounded by
@ -1348,6 +1265,19 @@ add_conditions_to_domain (poly_bb_p pbb)
}
}
/* Traverses all the GBBs of the SCOP and add their constraints to the
iteration domains. */
static void
add_conditions_to_constraints (scop_p scop)
{
int i;
poly_bb_p pbb;
FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
add_conditions_to_domain (pbb);
}
/* Structure used to pass data to dom_walk. */
struct bsc
@ -1470,19 +1400,6 @@ build_sese_conditions (sese region)
VEC_free (gimple, heap, cases);
}
/* Traverses all the GBBs of the SCOP and add their constraints to the
iteration domains. */
static void
add_conditions_to_constraints (scop_p scop)
{
int i;
poly_bb_p pbb;
FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
add_conditions_to_domain (pbb);
}
/* Add constraints on the possible values of parameter P from the type
of P. */
@ -1950,7 +1867,7 @@ build_alias_set_optimal_p (VEC (data_reference_p, heap) *drs)
return all_components_are_cliques;
}
/* Group each data reference in DRS with it's base object set num. */
/* Group each data reference in DRS with its base object set num. */
static void
build_base_obj_set_for_drs (VEC (data_reference_p, heap) *drs)
@ -2039,6 +1956,36 @@ dump_alias_graphs (VEC (data_reference_p, heap) *drs)
}
}
/* Recompute all the data references of BB and add them to the
GBB_DATA_REFS vector. */
static void
analyze_drs (scop_p scop, basic_block bb)
{
loop_p nest;
poly_bb_p pbb;
gimple_stmt_iterator gsi;
gimple_bb_p gbb;
if (!bb_in_sese_p (bb, SCOP_REGION (scop)))
return;
nest = outermost_loop_in_sese (SCOP_REGION (scop), bb);
pbb = pbb_from_bb (bb);
gbb = PBB_BLACK_BOX (pbb);
VEC_free (data_reference_p, heap, GBB_DATA_REFS (gbb));
GBB_DATA_REFS (gbb) = VEC_alloc (data_reference_p, heap, 3);
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
gimple stmt = gsi_stmt (gsi);
if (!is_gimple_debug (stmt))
graphite_find_data_references_in_stmt (nest, stmt,
&GBB_DATA_REFS (gbb));
}
}
/* Build data references in SCOP. */
static void
@ -2049,6 +1996,18 @@ build_scop_drs (scop_p scop)
data_reference_p dr;
VEC (data_reference_p, heap) *drs = VEC_alloc (data_reference_p, heap, 3);
/* Remove all the PBBs that do not have data references: these basic
blocks are not handled in the polyhedral representation. */
for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
{
analyze_drs (scop, GBB_BB (PBB_BLACK_BOX (pbb)));
if (VEC_empty (data_reference_p, GBB_DATA_REFS (PBB_BLACK_BOX (pbb))))
{
VEC_ordered_remove (poly_bb_p, SCOP_BBS (scop), i);
i--;
}
}
FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
for (j = 0; VEC_iterate (data_reference_p,
GBB_DATA_REFS (PBB_BLACK_BOX (pbb)), j, dr); j++)
@ -2092,18 +2051,17 @@ gsi_for_phi_node (gimple stmt)
return psi;
}
/* Insert the assignment "RES := VAR" just after AFTER_STMT. */
/* Insert the assignment "RES := EXPR" just after AFTER_STMT. */
static void
insert_out_of_ssa_copy (tree res, tree var, gimple after_stmt)
insert_out_of_ssa_copy (tree res, tree expr, gimple after_stmt)
{
gimple stmt;
gimple_seq stmts;
gimple_stmt_iterator si;
gimple_stmt_iterator gsi;
tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
gimple stmt = gimple_build_assign (res, var);
var = force_gimple_operand (var, &stmts, true, NULL_TREE);
stmt = gimple_build_assign (res, var);
if (!stmts)
stmts = gimple_seq_alloc ();
si = gsi_last (stmts);
@ -2121,15 +2079,40 @@ insert_out_of_ssa_copy (tree res, tree var, gimple after_stmt)
}
}
/* Creates a poly_bb_p for basic_block BB from the existing PBB. */
static void
new_pbb_from_pbb (scop_p scop, poly_bb_p pbb, basic_block bb)
{
VEC (data_reference_p, heap) *drs = VEC_alloc (data_reference_p, heap, 3);
gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
gimple_bb_p gbb1 = new_gimple_bb (bb, drs);
poly_bb_p pbb1 = new_poly_bb (scop, gbb1);
int index, n = VEC_length (poly_bb_p, SCOP_BBS (scop));
/* The INDEX of PBB in SCOP_BBS. */
for (index = 0; index < n; index++)
if (VEC_index (poly_bb_p, SCOP_BBS (scop), index) == pbb)
break;
GBB_PBB (gbb1) = pbb1;
ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron
(&PBB_DOMAIN (pbb1), PBB_DOMAIN (pbb));
GBB_CONDITIONS (gbb1) = VEC_copy (gimple, heap, GBB_CONDITIONS (gbb));
GBB_CONDITION_CASES (gbb1) = VEC_copy (gimple, heap, GBB_CONDITION_CASES (gbb));
VEC_safe_insert (poly_bb_p, heap, SCOP_BBS (scop), index + 1, pbb1);
}
/* Insert on edge E the assignment "RES := EXPR". */
static void
insert_out_of_ssa_copy_on_edge (edge e, tree res, tree expr)
insert_out_of_ssa_copy_on_edge (scop_p scop, edge e, tree res, tree expr)
{
gimple_stmt_iterator gsi;
gimple_seq stmts;
tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
gimple stmt = gimple_build_assign (res, var);
basic_block bb;
if (!stmts)
stmts = gimple_seq_alloc ();
@ -2138,6 +2121,13 @@ insert_out_of_ssa_copy_on_edge (edge e, tree res, tree expr)
gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
gsi_insert_seq_on_edge (e, stmts);
gsi_commit_edge_inserts ();
bb = gimple_bb (stmt);
if (!bb_in_sese_p (bb, SCOP_REGION (scop)))
return;
if (!gbb_from_bb (bb))
new_pbb_from_pbb (scop, pbb_from_bb (e->src), bb);
}
/* Creates a zero dimension array of the same type as VAR. */
@ -2213,8 +2203,9 @@ propagate_expr_outside_region (tree def, tree expr, sese region)
dimension array for it. */
static void
rewrite_close_phi_out_of_ssa (gimple_stmt_iterator *psi, sese region)
rewrite_close_phi_out_of_ssa (scop_p scop, gimple_stmt_iterator *psi)
{
sese region = SCOP_REGION (scop);
gimple phi = gsi_stmt (*psi);
tree res = gimple_phi_result (phi);
tree var = SSA_NAME_VAR (res);
@ -2278,9 +2269,10 @@ rewrite_close_phi_out_of_ssa (gimple_stmt_iterator *psi, sese region)
stmt = gimple_build_assign (res, zero_dim_array);
if (TREE_CODE (arg) == SSA_NAME)
insert_out_of_ssa_copy (zero_dim_array, arg, SSA_NAME_DEF_STMT (arg));
insert_out_of_ssa_copy (zero_dim_array, arg,
SSA_NAME_DEF_STMT (arg));
else
insert_out_of_ssa_copy_on_edge (single_pred_edge (bb),
insert_out_of_ssa_copy_on_edge (scop, single_pred_edge (bb),
zero_dim_array, arg);
}
@ -2293,7 +2285,7 @@ rewrite_close_phi_out_of_ssa (gimple_stmt_iterator *psi, sese region)
dimension array for it. */
static void
rewrite_phi_out_of_ssa (gimple_stmt_iterator *psi)
rewrite_phi_out_of_ssa (scop_p scop, gimple_stmt_iterator *psi)
{
size_t i;
gimple phi = gsi_stmt (*psi);
@ -2314,9 +2306,10 @@ rewrite_phi_out_of_ssa (gimple_stmt_iterator *psi)
pattern matching of the vectorizer. */
if (TREE_CODE (arg) == SSA_NAME
&& e->src == bb->loop_father->latch)
insert_out_of_ssa_copy (zero_dim_array, arg, SSA_NAME_DEF_STMT (arg));
insert_out_of_ssa_copy (zero_dim_array, arg,
SSA_NAME_DEF_STMT (arg));
else
insert_out_of_ssa_copy_on_edge (e, zero_dim_array, arg);
insert_out_of_ssa_copy_on_edge (scop, e, zero_dim_array, arg);
}
var = force_gimple_operand (zero_dim_array, &stmts, true, NULL_TREE);
@ -2362,7 +2355,7 @@ rewrite_degenerate_phi (gimple_stmt_iterator *psi)
/* Rewrite out of SSA all the reduction phi nodes of SCOP. */
void
static void
rewrite_reductions_out_of_ssa (scop_p scop)
{
basic_block bb;
@ -2386,10 +2379,10 @@ rewrite_reductions_out_of_ssa (scop_p scop)
rewrite_degenerate_phi (&psi);
else if (scalar_close_phi_node_p (phi))
rewrite_close_phi_out_of_ssa (&psi, region);
rewrite_close_phi_out_of_ssa (scop, &psi);
else if (reduction_phi_p (region, &psi))
rewrite_phi_out_of_ssa (&psi);
rewrite_phi_out_of_ssa (scop, &psi);
}
update_ssa (TODO_update_ssa);
@ -2402,7 +2395,8 @@ rewrite_reductions_out_of_ssa (scop_p scop)
read from ZERO_DIM_ARRAY. */
static void
rewrite_cross_bb_scalar_dependence (tree zero_dim_array, tree def, gimple use_stmt)
rewrite_cross_bb_scalar_dependence (tree zero_dim_array,
tree def, gimple use_stmt)
{
tree var = SSA_NAME_VAR (def);
gimple name_stmt = gimple_build_assign (var, zero_dim_array);
@ -2525,9 +2519,9 @@ rewrite_cross_bb_scalar_deps (scop_p scop, gimple_stmt_iterator *gsi)
gimple_stmt_iterator psi = gsi_for_stmt (use_stmt);
if (scalar_close_phi_node_p (gsi_stmt (psi)))
rewrite_close_phi_out_of_ssa (&psi, region);
rewrite_close_phi_out_of_ssa (scop, &psi);
else
rewrite_phi_out_of_ssa (&psi);
rewrite_phi_out_of_ssa (scop, &psi);
}
FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
@ -2545,7 +2539,8 @@ rewrite_cross_bb_scalar_deps (scop_p scop, gimple_stmt_iterator *gsi)
gsi_next (gsi);
}
rewrite_cross_bb_scalar_dependence (zero_dim_array, def, use_stmt);
rewrite_cross_bb_scalar_dependence (zero_dim_array,
def, use_stmt);
}
return res;
@ -2553,7 +2548,7 @@ rewrite_cross_bb_scalar_deps (scop_p scop, gimple_stmt_iterator *gsi)
/* Rewrite out of SSA all the reduction phi nodes of SCOP. */
void
static void
rewrite_cross_bb_scalar_deps_out_of_ssa (scop_p scop)
{
basic_block bb;
@ -2612,30 +2607,44 @@ nb_data_writes_in_bb (basic_block bb)
return res;
}
/* Splits STMT out of its current BB. */
/* Splits at STMT the basic block BB represented as PBB in the
polyhedral form. */
static edge
split_pbb (scop_p scop, poly_bb_p pbb, basic_block bb, gimple stmt)
{
edge e1 = split_block (bb, stmt);
new_pbb_from_pbb (scop, pbb, e1->dest);
return e1;
}
/* Splits STMT out of its current BB. This is done for reduction
statements for which we want to ignore data dependences. */
static basic_block
split_reduction_stmt (gimple stmt)
split_reduction_stmt (scop_p scop, gimple stmt)
{
gimple_stmt_iterator gsi;
basic_block bb = gimple_bb (stmt);
edge e;
poly_bb_p pbb = pbb_from_bb (bb);
edge e1;
/* Do not split basic blocks with no writes to memory: the reduction
will be the only write to memory. */
if (nb_data_writes_in_bb (bb) == 0)
return bb;
split_block (bb, stmt);
e1 = split_pbb (scop, pbb, bb, stmt);
if (gsi_one_before_end_p (gsi_start_nondebug_bb (bb)))
return bb;
/* Split once more only when the reduction stmt is not the only one
left in the original BB. */
if (!gsi_one_before_end_p (gsi_start_nondebug_bb (bb)))
{
gimple_stmt_iterator gsi = gsi_last_bb (bb);
gsi_prev (&gsi);
e1 = split_pbb (scop, pbb, bb, gsi_stmt (gsi));
}
gsi = gsi_last_bb (bb);
gsi_prev (&gsi);
e = split_block (bb, gsi_stmt (gsi));
return e->dest;
return e1->dest;
}
/* Return true when stmt is a reduction operation. */
@ -2864,13 +2873,12 @@ static void
translate_scalar_reduction_to_array_for_stmt (tree red, gimple stmt,
gimple loop_phi)
{
gimple_stmt_iterator insert_gsi = gsi_after_labels (gimple_bb (loop_phi));
tree res = gimple_phi_result (loop_phi);
gimple assign = gimple_build_assign (res, red);
gimple_stmt_iterator insert_gsi = gsi_after_labels (gimple_bb (loop_phi));
gsi_insert_before (&insert_gsi, assign, GSI_SAME_STMT);
insert_gsi = gsi_after_labels (gimple_bb (stmt));
assign = gimple_build_assign (red, gimple_assign_lhs (stmt));
insert_gsi = gsi_for_stmt (stmt);
gsi_insert_after (&insert_gsi, assign, GSI_SAME_STMT);
@ -2922,9 +2930,9 @@ remove_phi (gimple phi)
are the loop and close phi nodes of each of the outer loops. */
static void
translate_scalar_reduction_to_array (VEC (gimple, heap) *in,
VEC (gimple, heap) *out,
sbitmap reductions)
translate_scalar_reduction_to_array (scop_p scop,
VEC (gimple, heap) *in,
VEC (gimple, heap) *out)
{
unsigned int i;
gimple loop_phi;
@ -2937,9 +2945,9 @@ translate_scalar_reduction_to_array (VEC (gimple, heap) *in,
if (i == 0)
{
gimple stmt = loop_phi;
basic_block bb = split_reduction_stmt (stmt);
SET_BIT (reductions, bb->index);
basic_block bb = split_reduction_stmt (scop, stmt);
poly_bb_p pbb = pbb_from_bb (bb);
PBB_IS_REDUCTION (pbb) = true;
gcc_assert (close_phi == loop_phi);
red = create_zero_dim_array
@ -2954,7 +2962,7 @@ translate_scalar_reduction_to_array (VEC (gimple, heap) *in,
insert_out_of_ssa_copy (gimple_phi_result (close_phi), red,
close_phi);
insert_out_of_ssa_copy_on_edge
(edge_initial_value_for_loop_phi (loop_phi),
(scop, edge_initial_value_for_loop_phi (loop_phi),
red, initial_value_for_loop_phi (loop_phi));
}
@ -2967,8 +2975,8 @@ translate_scalar_reduction_to_array (VEC (gimple, heap) *in,
true when something has been changed. */
static bool
rewrite_commutative_reductions_out_of_ssa_close_phi (gimple close_phi,
sbitmap reductions)
rewrite_commutative_reductions_out_of_ssa_close_phi (scop_p scop,
gimple close_phi)
{
bool res;
VEC (gimple, heap) *in = VEC_alloc (gimple, heap, 10);
@ -2977,7 +2985,7 @@ rewrite_commutative_reductions_out_of_ssa_close_phi (gimple close_phi,
detect_commutative_reduction (close_phi, &in, &out);
res = VEC_length (gimple, in) > 0;
if (res)
translate_scalar_reduction_to_array (in, out, reductions);
translate_scalar_reduction_to_array (scop, in, out);
VEC_free (gimple, heap, in);
VEC_free (gimple, heap, out);
@ -2988,9 +2996,8 @@ rewrite_commutative_reductions_out_of_ssa_close_phi (gimple close_phi,
Returns true when something has been changed. */
static bool
rewrite_commutative_reductions_out_of_ssa_loop (loop_p loop,
sbitmap reductions,
sese region)
rewrite_commutative_reductions_out_of_ssa_loop (scop_p scop,
loop_p loop)
{
gimple_stmt_iterator gsi;
edge exit = single_exit (loop);
@ -3003,30 +3010,26 @@ rewrite_commutative_reductions_out_of_ssa_loop (loop_p loop,
for (gsi = gsi_start_phis (exit->dest); !gsi_end_p (gsi); gsi_next (&gsi))
if ((res = gimple_phi_result (gsi_stmt (gsi)))
&& is_gimple_reg (res)
&& !scev_analyzable_p (res, region))
&& !scev_analyzable_p (res, SCOP_REGION (scop)))
changed |= rewrite_commutative_reductions_out_of_ssa_close_phi
(gsi_stmt (gsi), reductions);
(scop, gsi_stmt (gsi));
return changed;
}
/* Rewrites all the commutative reductions from SCOP out of SSA. */
void
rewrite_commutative_reductions_out_of_ssa (sese region, sbitmap reductions)
static void
rewrite_commutative_reductions_out_of_ssa (scop_p scop)
{
loop_iterator li;
loop_p loop;
bool changed = false;
if (!flag_associative_math)
return;
sese region = SCOP_REGION (scop);
FOR_EACH_LOOP (li, loop, 0)
if (loop_in_sese_p (loop, region))
changed |= rewrite_commutative_reductions_out_of_ssa_loop (loop,
reductions,
region);
changed |= rewrite_commutative_reductions_out_of_ssa_loop (scop, loop);
if (changed)
{
@ -3084,6 +3087,7 @@ build_poly_scop (scop_p scop)
sese region = SCOP_REGION (scop);
graphite_dim_t max_dim;
build_scop_bbs (scop);
/* FIXME: This restriction is needed to avoid a problem in CLooG.
Once CLooG is fixed, remove this guard. Anyways, it makes no
@ -3105,11 +3109,20 @@ build_poly_scop (scop_p scop)
build_scop_iteration_domain (scop);
build_scop_context (scop);
add_conditions_to_constraints (scop);
/* Rewrite out of SSA only after having translated the
representation to the polyhedral representation to avoid scev
analysis failures. That means that these functions will insert
new data references that they create in the right place. */
if (flag_associative_math)
rewrite_commutative_reductions_out_of_ssa (scop);
rewrite_reductions_out_of_ssa (scop);
rewrite_cross_bb_scalar_deps_out_of_ssa (scop);
build_scop_drs (scop);
scop_to_lst (scop);
build_scop_scattering (scop);
build_scop_drs (scop);
/* This SCoP has been translated to the polyhedral
representation. */

View File

@ -29,9 +29,5 @@ struct base_alias_pair
};
void build_poly_scop (scop_p);
void rewrite_commutative_reductions_out_of_ssa (sese, sbitmap);
void rewrite_reductions_out_of_ssa (scop_p);
void rewrite_cross_bb_scalar_deps_out_of_ssa (scop_p);
void build_scop_bbs (scop_p, sbitmap);
#endif

View File

@ -262,7 +262,6 @@ graphite_transform_loops (void)
bool need_cfg_cleanup_p = false;
VEC (scop_p, heap) *scops = NULL;
htab_t bb_pbb_mapping;
sbitmap reductions;
if (!graphite_initialize ())
return;
@ -276,34 +275,18 @@ graphite_transform_loops (void)
}
bb_pbb_mapping = htab_create (10, bb_pbb_map_hash, eq_bb_pbb_map, free);
reductions = sbitmap_alloc (last_basic_block * 2);
sbitmap_zero (reductions);
FOR_EACH_VEC_ELT (scop_p, scops, i, scop)
if (dbg_cnt (graphite_scop))
rewrite_commutative_reductions_out_of_ssa (SCOP_REGION (scop),
reductions);
FOR_EACH_VEC_ELT (scop_p, scops, i, scop)
if (dbg_cnt (graphite_scop))
{
rewrite_reductions_out_of_ssa (scop);
rewrite_cross_bb_scalar_deps_out_of_ssa (scop);
build_scop_bbs (scop, reductions);
build_poly_scop (scop);
if (POLY_SCOP_P (scop)
&& apply_poly_transforms (scop)
&& gloog (scop, bb_pbb_mapping))
need_cfg_cleanup_p = true;
}
sbitmap_free (reductions);
FOR_EACH_VEC_ELT (scop_p, scops, i, scop)
if (dbg_cnt (graphite_scop))
build_poly_scop (scop);
FOR_EACH_VEC_ELT (scop_p, scops, i, scop)
if (POLY_SCOP_P (scop)
&& apply_poly_transforms (scop)
&& gloog (scop, bb_pbb_mapping))
need_cfg_cleanup_p = true;
htab_delete (bb_pbb_mapping);
free_scops (scops);
graphite_finalize (need_cfg_cleanup_p);

View File

@ -312,6 +312,7 @@ recompute_all_dominators (void)
typedef struct gimple_bb
{
basic_block bb;
struct poly_bb *pbb;
/* Lists containing the restrictions of the conditional statements
dominating this bb. This bb can only be executed, if all conditions
@ -338,10 +339,11 @@ typedef struct gimple_bb
VEC (data_reference_p, heap) *data_refs;
} *gimple_bb_p;
#define GBB_BB(GBB) GBB->bb
#define GBB_DATA_REFS(GBB) GBB->data_refs
#define GBB_CONDITIONS(GBB) GBB->conditions
#define GBB_CONDITION_CASES(GBB) GBB->condition_cases
#define GBB_BB(GBB) (GBB)->bb
#define GBB_PBB(GBB) (GBB)->pbb
#define GBB_DATA_REFS(GBB) (GBB)->data_refs
#define GBB_CONDITIONS(GBB) (GBB)->conditions
#define GBB_CONDITION_CASES(GBB) (GBB)->condition_cases
/* Return the innermost loop that contains the basic block GBB. */

View File

@ -1,3 +1,8 @@
2010-11-29 Sebastian Pop <sebastian.pop@amd.com>
PR middle-end/45297
* gcc.dg/graphite/pr45297.c: New.
2010-12-01 Richard Guenther <rguenther@suse.de>
PR tree-optimization/46730

View File

@ -0,0 +1,9 @@
/* { dg-options "-Os -fgraphite-identity" } */
void
foo (int *p)
{
int *q = p + 1024;
while (q != p)
*--q = *--q;
}