Commit 30fd2977 by Richard Biener Committed by Richard Biener

re PR tree-optimization/71253 (ICE during loop distribution w/ -O2 -ftree-loop-distribution)

2016-05-24  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/71253
	* cfganal.h (control_dependences): Make robust against edge
	and BB removal.
	(control_dependences::control_dependences): Remove edge_list argument.
	(control_dependences::get_edge): Remove.
	(control_dependences::get_edge_src): Add.
	(control_dependences::get_edge_dest): Likewise.
	(control_dependences::m_el): Make a vector of edge src/dest index.
	* cfganal.c (control_dependences::find_control_dependence): Adjust.
	(control_dependences::control_dependences): Likewise.
	(control_dependences::~control_dependence): Likewise.
	(control_dependences::get_edge): Remove.
	(control_dependences::get_edge_src): Add.
	(control_dependences::get_edge_dest): Likewise.
	* tree-ssa-dce.c (mark_control_dependent_edges_necessary): Use
	get_edge_src.
	(perform_tree_ssa_dce): Adjust.
	* tree-loop-distribution.c (create_edge_for_control_dependence): Use
	get_edge_src.
	(pass_loop_distribution::execute): Adjust.  Do loop destroying
	conditional on changed.

	* gcc.dg/torture/pr71253.c: New testcase.

From-SVN: r236636
parent 37923729
2016-05-24 Richard Biener <rguenther@suse.de>
PR tree-optimization/71253
* cfganal.h (control_dependences): Make robust against edge
and BB removal.
(control_dependences::control_dependences): Remove edge_list argument.
(control_dependences::get_edge): Remove.
(control_dependences::get_edge_src): Add.
(control_dependences::get_edge_dest): Likewise.
(control_dependences::m_el): Make a vector of edge src/dest index.
* cfganal.c (control_dependences::find_control_dependence): Adjust.
(control_dependences::control_dependences): Likewise.
(control_dependences::~control_dependence): Likewise.
(control_dependences::get_edge): Remove.
(control_dependences::get_edge_src): Add.
(control_dependences::get_edge_dest): Likewise.
* tree-ssa-dce.c (mark_control_dependent_edges_necessary): Use
get_edge_src.
(perform_tree_ssa_dce): Adjust.
* tree-loop-distribution.c (create_edge_for_control_dependence): Use
get_edge_src.
(pass_loop_distribution::execute): Adjust. Do loop destroying
conditional on changed.
2016-05-24 Kyrylo Tkachov <kyrylo.tkachov@arm.com> 2016-05-24 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
PR target/69857 PR target/69857
......
...@@ -408,43 +408,54 @@ control_dependences::find_control_dependence (int edge_index) ...@@ -408,43 +408,54 @@ control_dependences::find_control_dependence (int edge_index)
basic_block current_block; basic_block current_block;
basic_block ending_block; basic_block ending_block;
gcc_assert (INDEX_EDGE_PRED_BB (m_el, edge_index) gcc_assert (get_edge_src (edge_index) != EXIT_BLOCK_PTR_FOR_FN (cfun));
!= EXIT_BLOCK_PTR_FOR_FN (cfun));
if (INDEX_EDGE_PRED_BB (m_el, edge_index) == ENTRY_BLOCK_PTR_FOR_FN (cfun)) /* For abnormal edges, we don't make current_block control
dependent because instructions that throw are always necessary
anyway. */
edge e = find_edge (get_edge_src (edge_index), get_edge_dest (edge_index));
if (e->flags & EDGE_ABNORMAL)
return;
if (get_edge_src (edge_index) == ENTRY_BLOCK_PTR_FOR_FN (cfun))
ending_block = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)); ending_block = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
else else
ending_block = find_pdom (INDEX_EDGE_PRED_BB (m_el, edge_index)); ending_block = find_pdom (get_edge_src (edge_index));
for (current_block = INDEX_EDGE_SUCC_BB (m_el, edge_index); for (current_block = get_edge_dest (edge_index);
current_block != ending_block current_block != ending_block
&& current_block != EXIT_BLOCK_PTR_FOR_FN (cfun); && current_block != EXIT_BLOCK_PTR_FOR_FN (cfun);
current_block = find_pdom (current_block)) current_block = find_pdom (current_block))
{ set_control_dependence_map_bit (current_block, edge_index);
edge e = INDEX_EDGE (m_el, edge_index);
/* For abnormal edges, we don't make current_block control
dependent because instructions that throw are always necessary
anyway. */
if (e->flags & EDGE_ABNORMAL)
continue;
set_control_dependence_map_bit (current_block, edge_index);
}
} }
/* Record all blocks' control dependences on all edges in the edge /* Record all blocks' control dependences on all edges in the edge
list EL, ala Morgan, Section 3.6. */ list EL, ala Morgan, Section 3.6. */
control_dependences::control_dependences (struct edge_list *edges) control_dependences::control_dependences ()
: m_el (edges)
{ {
timevar_push (TV_CONTROL_DEPENDENCES); timevar_push (TV_CONTROL_DEPENDENCES);
/* Initialize the edge list. */
int num_edges = 0;
basic_block bb;
FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun),
EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb)
num_edges += EDGE_COUNT (bb->succs);
m_el.create (num_edges);
edge e;
edge_iterator ei;
FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun),
EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb)
FOR_EACH_EDGE (e, ei, bb->succs)
m_el.quick_push (std::make_pair (e->src->index, e->dest->index));
control_dependence_map.create (last_basic_block_for_fn (cfun)); control_dependence_map.create (last_basic_block_for_fn (cfun));
for (int i = 0; i < last_basic_block_for_fn (cfun); ++i) for (int i = 0; i < last_basic_block_for_fn (cfun); ++i)
control_dependence_map.quick_push (BITMAP_ALLOC (NULL)); control_dependence_map.quick_push (BITMAP_ALLOC (NULL));
for (int i = 0; i < NUM_EDGES (m_el); ++i) for (int i = 0; i < num_edges; ++i)
find_control_dependence (i); find_control_dependence (i);
timevar_pop (TV_CONTROL_DEPENDENCES); timevar_pop (TV_CONTROL_DEPENDENCES);
} }
...@@ -455,7 +466,7 @@ control_dependences::~control_dependences () ...@@ -455,7 +466,7 @@ control_dependences::~control_dependences ()
for (unsigned i = 0; i < control_dependence_map.length (); ++i) for (unsigned i = 0; i < control_dependence_map.length (); ++i)
BITMAP_FREE (control_dependence_map[i]); BITMAP_FREE (control_dependence_map[i]);
control_dependence_map.release (); control_dependence_map.release ();
free_edge_list (m_el); m_el.release ();
} }
/* Returns the bitmap of edges the basic-block I is dependent on. */ /* Returns the bitmap of edges the basic-block I is dependent on. */
...@@ -466,12 +477,20 @@ control_dependences::get_edges_dependent_on (int i) ...@@ -466,12 +477,20 @@ control_dependences::get_edges_dependent_on (int i)
return control_dependence_map[i]; return control_dependence_map[i];
} }
/* Returns the edge with index I from the edge list. */ /* Returns the edge source with index I from the edge list. */
edge basic_block
control_dependences::get_edge (int i) control_dependences::get_edge_src (int i)
{
return BASIC_BLOCK_FOR_FN (cfun, m_el[i].first);
}
/* Returns the edge destination with index I from the edge list. */
basic_block
control_dependences::get_edge_dest (int i)
{ {
return INDEX_EDGE (m_el, i); return BASIC_BLOCK_FOR_FN (cfun, m_el[i].second);
} }
......
...@@ -34,17 +34,18 @@ struct edge_list ...@@ -34,17 +34,18 @@ struct edge_list
class control_dependences class control_dependences
{ {
public: public:
control_dependences (edge_list *); control_dependences ();
~control_dependences (); ~control_dependences ();
bitmap get_edges_dependent_on (int); bitmap get_edges_dependent_on (int);
edge get_edge (int); basic_block get_edge_src (int);
basic_block get_edge_dest (int);
private: private:
void set_control_dependence_map_bit (basic_block, int); void set_control_dependence_map_bit (basic_block, int);
void clear_control_dependence_bitmap (basic_block); void clear_control_dependence_bitmap (basic_block);
void find_control_dependence (int); void find_control_dependence (int);
vec<bitmap> control_dependence_map; vec<bitmap> control_dependence_map;
edge_list *m_el; vec<std::pair<int, int> > m_el;
}; };
extern bool mark_dfs_back_edges (void); extern bool mark_dfs_back_edges (void);
......
2016-05-24 Richard Biener <rguenther@suse.de>
PR tree-optimization/71253
* gcc.dg/torture/pr71253.c: New testcase.
2016-05-24 Kugan Vivekanandarajah <kuganv@linaro.org> 2016-05-24 Kugan Vivekanandarajah <kuganv@linaro.org>
PR middle-end/71252 PR middle-end/71252
......
/* { dg-do compile } */
/* { dg-additional-options "-ftree-loop-distribution" } */
int jo, af, yb;
long int wt;
void
nr (void)
{
int *bf = &yb;
for (;;)
{
while (jo != 0)
{
long int *ad = (long int *) &yb;
for (;;)
{
int fv;
for (*ad = 1; *ad < 3; ++(*ad))
{
af = *bf;
fv = wt;
}
bf = (int *) &wt;
ad = &wt;
do
{
jo = wt = ((wt != 0) ? 1 : fv);
}
while (jo != 0);
}
}
bf = &af;
}
}
...@@ -278,7 +278,7 @@ create_edge_for_control_dependence (struct graph *rdg, basic_block bb, ...@@ -278,7 +278,7 @@ create_edge_for_control_dependence (struct graph *rdg, basic_block bb,
EXECUTE_IF_SET_IN_BITMAP (cd->get_edges_dependent_on (bb->index), EXECUTE_IF_SET_IN_BITMAP (cd->get_edges_dependent_on (bb->index),
0, edge_n, bi) 0, edge_n, bi)
{ {
basic_block cond_bb = cd->get_edge (edge_n)->src; basic_block cond_bb = cd->get_edge_src (edge_n);
gimple *stmt = last_stmt (cond_bb); gimple *stmt = last_stmt (cond_bb);
if (stmt && is_ctrl_stmt (stmt)) if (stmt && is_ctrl_stmt (stmt))
{ {
...@@ -1789,7 +1789,7 @@ out: ...@@ -1789,7 +1789,7 @@ out:
{ {
calculate_dominance_info (CDI_DOMINATORS); calculate_dominance_info (CDI_DOMINATORS);
calculate_dominance_info (CDI_POST_DOMINATORS); calculate_dominance_info (CDI_POST_DOMINATORS);
cd = new control_dependences (create_edge_list ()); cd = new control_dependences ();
free_dominance_info (CDI_POST_DOMINATORS); free_dominance_info (CDI_POST_DOMINATORS);
} }
bool destroy_p; bool destroy_p;
...@@ -1815,14 +1815,14 @@ out: ...@@ -1815,14 +1815,14 @@ out:
if (cd) if (cd)
delete cd; delete cd;
/* Destroy loop bodies that could not be reused. Do this late as we
otherwise can end up refering to stale data in control dependences. */
unsigned i;
FOR_EACH_VEC_ELT (loops_to_be_destroyed, i, loop)
destroy_loop (loop);
if (changed) if (changed)
{ {
/* Destroy loop bodies that could not be reused. Do this late as we
otherwise can end up refering to stale data in control dependences. */
unsigned i;
FOR_EACH_VEC_ELT (loops_to_be_destroyed, i, loop)
destroy_loop (loop);
/* Cached scalar evolutions now may refer to wrong or non-existing /* Cached scalar evolutions now may refer to wrong or non-existing
loops. */ loops. */
scev_reset_htab (); scev_reset_htab ();
......
...@@ -339,7 +339,7 @@ mark_control_dependent_edges_necessary (basic_block bb, bool ignore_self) ...@@ -339,7 +339,7 @@ mark_control_dependent_edges_necessary (basic_block bb, bool ignore_self)
EXECUTE_IF_SET_IN_BITMAP (cd->get_edges_dependent_on (bb->index), EXECUTE_IF_SET_IN_BITMAP (cd->get_edges_dependent_on (bb->index),
0, edge_number, bi) 0, edge_number, bi)
{ {
basic_block cd_bb = cd->get_edge (edge_number)->src; basic_block cd_bb = cd->get_edge_src (edge_number);
if (ignore_self && cd_bb == bb) if (ignore_self && cd_bb == bb)
{ {
...@@ -1577,7 +1577,7 @@ perform_tree_ssa_dce (bool aggressive) ...@@ -1577,7 +1577,7 @@ perform_tree_ssa_dce (bool aggressive)
{ {
/* Compute control dependence. */ /* Compute control dependence. */
calculate_dominance_info (CDI_POST_DOMINATORS); calculate_dominance_info (CDI_POST_DOMINATORS);
cd = new control_dependences (create_edge_list ()); cd = new control_dependences ();
visited_control_parents = visited_control_parents =
sbitmap_alloc (last_basic_block_for_fn (cfun)); sbitmap_alloc (last_basic_block_for_fn (cfun));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment