re PR tree-optimization/71253 (ICE during loop distribution w/ -O2 -ftree-loop-distri...
authorRichard Biener <rguenther@suse.de>
Tue, 24 May 2016 12:40:01 +0000 (12:40 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 24 May 2016 12:40:01 +0000 (12:40 +0000)
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

gcc/ChangeLog
gcc/cfganal.c
gcc/cfganal.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr71253.c [new file with mode: 0644]
gcc/tree-loop-distribution.c
gcc/tree-ssa-dce.c

index 433493df5423962ca8b1f7582a66c9ee09a13977..cd557fbdffa12c822a78b3090750f292583f42a5 100644 (file)
@@ -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
index a4bdef603052c9927b9d7158d740e9ebb26ae044..aabc065ca3521bd893616db51c54ed414d5abc71 100644 (file)
@@ -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);
 }
 
 
index 8dc2fcf0cf5645b04fdb3e076be363f3e00403cb..ea7ed7a425f257540cb9e2eed7e4f2f05cfdba1f 100644 (file)
@@ -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);
index 47ddcf0bd58662b0ce02be57be59ca8e7a260bb6..586202e9fa0700b1f11706d4934b3a8ed824f91a 100644 (file)
@@ -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 (file)
index 0000000..ecbba77
--- /dev/null
@@ -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;
+    }
+}
index dbc8e3cdbdc8a3f69813384798b8c583f030ebd8..e4163b274ffde9b1dad255f12b552f08a014703c 100644 (file)
@@ -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 ();
index 75aaee97123d3677454c10bab328bd57d50e2b38..954fc67ee0da83b936415cfcf8cc6dfbe5ff1f7b 100644 (file)
@@ -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));