aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2016-05-24 12:40:01 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2016-05-24 12:40:01 +0000
commit30fd2977745d53f282d1560212e3bea07943a937 (patch)
tree38872e66995c95e8cbb549b062945e2448f38ed6
parent37923729c5ab013459a7eeeba5ce53fca75759fe (diff)
downloadgcc-30fd2977745d53f282d1560212e3bea07943a937.zip
gcc-30fd2977745d53f282d1560212e3bea07943a937.tar.gz
gcc-30fd2977745d53f282d1560212e3bea07943a937.tar.bz2
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
-rw-r--r--gcc/ChangeLog24
-rw-r--r--gcc/cfganal.c67
-rw-r--r--gcc/cfganal.h7
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr71253.c35
-rw-r--r--gcc/tree-loop-distribution.c16
-rw-r--r--gcc/tree-ssa-dce.c4
7 files changed, 121 insertions, 37 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 433493d..cd557fb 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,27 @@
+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>
PR target/69857
diff --git a/gcc/cfganal.c b/gcc/cfganal.c
index a4bdef6..aabc065 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 8dc2fcf..ea7ed7a 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<bitmap> control_dependence_map;
- edge_list *m_el;
+ vec<std::pair<int, int> > m_el;
};
extern bool mark_dfs_back_edges (void);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 47ddcf0..586202e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+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>
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 0000000..ecbba77
--- /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 = &af;
+ }
+}
diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c
index dbc8e3c..e4163b2 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 75aaee9..954fc67 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));