From: Richard Biener Date: Tue, 24 May 2016 12:40:01 +0000 (+0000) Subject: re PR tree-optimization/71253 (ICE during loop distribution w/ -O2 -ftree-loop-distri... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=30fd2977745d53f282d1560212e3bea07943a937;p=gcc.git re PR tree-optimization/71253 (ICE during loop distribution w/ -O2 -ftree-loop-distribution) 2016-05-24 Richard Biener 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 433493df542..cd557fbdffa 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,27 @@ +2016-05-24 Richard Biener + + 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 PR target/69857 diff --git a/gcc/cfganal.c b/gcc/cfganal.c index a4bdef60305..aabc065ca35 100644 --- a/gcc/cfganal.c +++ b/gcc/cfganal.c @@ -408,43 +408,54 @@ control_dependences::find_control_dependence (int edge_index) basic_block current_block; basic_block ending_block; - gcc_assert (INDEX_EDGE_PRED_BB (m_el, edge_index) - != EXIT_BLOCK_PTR_FOR_FN (cfun)); + gcc_assert (get_edge_src (edge_index) != 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)); 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 != EXIT_BLOCK_PTR_FOR_FN (cfun); current_block = find_pdom (current_block)) - { - 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); - } + set_control_dependence_map_bit (current_block, edge_index); } /* Record all blocks' control dependences on all edges in the edge list EL, ala Morgan, Section 3.6. */ -control_dependences::control_dependences (struct edge_list *edges) - : m_el (edges) +control_dependences::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)); for (int i = 0; i < last_basic_block_for_fn (cfun); ++i) 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); + timevar_pop (TV_CONTROL_DEPENDENCES); } @@ -455,7 +466,7 @@ control_dependences::~control_dependences () for (unsigned i = 0; i < control_dependence_map.length (); ++i) BITMAP_FREE (control_dependence_map[i]); control_dependence_map.release (); - free_edge_list (m_el); + m_el.release (); } /* Returns the bitmap of edges the basic-block I is dependent on. */ @@ -466,12 +477,20 @@ control_dependences::get_edges_dependent_on (int 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 -control_dependences::get_edge (int i) +basic_block +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); } diff --git a/gcc/cfganal.h b/gcc/cfganal.h index 8dc2fcf0cf5..ea7ed7a425f 100644 --- a/gcc/cfganal.h +++ b/gcc/cfganal.h @@ -34,17 +34,18 @@ struct edge_list class control_dependences { public: - control_dependences (edge_list *); + control_dependences (); ~control_dependences (); bitmap get_edges_dependent_on (int); - edge get_edge (int); + basic_block get_edge_src (int); + basic_block get_edge_dest (int); private: void set_control_dependence_map_bit (basic_block, int); void clear_control_dependence_bitmap (basic_block); void find_control_dependence (int); vec control_dependence_map; - edge_list *m_el; + vec > m_el; }; extern bool mark_dfs_back_edges (void); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 47ddcf0bd58..586202e9fa0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-05-24 Richard Biener + + PR tree-optimization/71253 + * gcc.dg/torture/pr71253.c: New testcase. + 2016-05-24 Kugan Vivekanandarajah PR middle-end/71252 diff --git a/gcc/testsuite/gcc.dg/torture/pr71253.c b/gcc/testsuite/gcc.dg/torture/pr71253.c new file mode 100644 index 00000000000..ecbba77dca7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr71253.c @@ -0,0 +1,35 @@ +/* { 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 = ⁡ + } +} diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c index dbc8e3cdbdc..e4163b274ff 100644 --- a/gcc/tree-loop-distribution.c +++ b/gcc/tree-loop-distribution.c @@ -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), 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); if (stmt && is_ctrl_stmt (stmt)) { @@ -1789,7 +1789,7 @@ out: { calculate_dominance_info (CDI_DOMINATORS); calculate_dominance_info (CDI_POST_DOMINATORS); - cd = new control_dependences (create_edge_list ()); + cd = new control_dependences (); free_dominance_info (CDI_POST_DOMINATORS); } bool destroy_p; @@ -1815,14 +1815,14 @@ out: if (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) { + /* 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 loops. */ scev_reset_htab (); diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c index 75aaee97123..954fc67ee0d 100644 --- a/gcc/tree-ssa-dce.c +++ b/gcc/tree-ssa-dce.c @@ -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), 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) { @@ -1577,7 +1577,7 @@ perform_tree_ssa_dce (bool aggressive) { /* Compute control dependence. */ calculate_dominance_info (CDI_POST_DOMINATORS); - cd = new control_dependences (create_edge_list ()); + cd = new control_dependences (); visited_control_parents = sbitmap_alloc (last_basic_block_for_fn (cfun));