PR c++/68795: fix uninitialized close_paren_loc in cp_parser_postfix_expression
[gcc.git] / gcc / cfganal.c
index 9900d823e36bf99119e77c639066be25f56456ca..bf9866b21d5f76c06014cdb009a047a178c281e2 100644 (file)
@@ -1,5 +1,5 @@
 /* Control flow graph analysis code for GNU compiler.
-   Copyright (C) 1987-2013 Free Software Foundation, Inc.
+   Copyright (C) 1987-2016 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -22,14 +22,13 @@ along with GCC; see the file COPYING3.  If not see
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
-#include "basic-block.h"
-#include "vec.h"
-#include "bitmap.h"
-#include "sbitmap.h"
+#include "backend.h"
+#include "cfghooks.h"
 #include "timevar.h"
+#include "cfganal.h"
 
 /* Store the data structures necessary for depth-first search.  */
-struct depth_first_search_dsS {
+struct depth_first_search_ds {
   /* stack for backtracking during the algorithm */
   basic_block *stack;
 
@@ -40,14 +39,13 @@ struct depth_first_search_dsS {
   /* record of basic blocks already seen by depth-first search */
   sbitmap visited_blocks;
 };
-typedef struct depth_first_search_dsS *depth_first_search_ds;
 
-static void flow_dfs_compute_reverse_init (depth_first_search_ds);
-static void flow_dfs_compute_reverse_add_bb (depth_first_search_ds,
+static void flow_dfs_compute_reverse_init (depth_first_search_ds *);
+static void flow_dfs_compute_reverse_add_bb (depth_first_search_ds *,
                                             basic_block);
-static basic_block flow_dfs_compute_reverse_execute (depth_first_search_ds,
+static basic_block flow_dfs_compute_reverse_execute (depth_first_search_ds *,
                                                     basic_block);
-static void flow_dfs_compute_reverse_finish (depth_first_search_ds);
+static void flow_dfs_compute_reverse_finish (depth_first_search_ds *);
 \f
 /* Mark the back edges in DFS traversal.
    Return nonzero if a loop (natural or otherwise) is present.
@@ -159,7 +157,7 @@ find_unreachable_blocks (void)
 
   /* Clear all the reachability flags.  */
 
-  FOR_EACH_BB (bb)
+  FOR_EACH_BB_FN (bb, cfun)
     bb->flags &= ~BB_REACHABLE;
 
   /* Add our starting points to the worklist.  Almost always there will
@@ -194,6 +192,19 @@ find_unreachable_blocks (void)
 
   free (worklist);
 }
+
+/* Verify that there are no unreachable blocks in the current function.  */
+
+void
+verify_no_unreachable_blocks (void)
+{
+  find_unreachable_blocks ();
+
+  basic_block bb;
+  FOR_EACH_BB_FN (bb, cfun)
+    gcc_assert ((bb->flags & BB_REACHABLE) != 0);
+}
+
 \f
 /* Functions to access an edge list with a vector representation.
    Enough data is kept such that given an index number, the
@@ -554,7 +565,7 @@ add_noreturn_fake_exit_edges (void)
 {
   basic_block bb;
 
-  FOR_EACH_BB (bb)
+  FOR_EACH_BB_FN (bb, cfun)
     if (EDGE_COUNT (bb->succs) == 0)
       make_single_succ_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun), EDGE_FAKE);
 }
@@ -575,7 +586,7 @@ connect_infinite_loops_to_exit (void)
 {
   basic_block unvisited_block = EXIT_BLOCK_PTR_FOR_FN (cfun);
   basic_block deadend_block;
-  struct depth_first_search_dsS dfs_ds;
+  depth_first_search_ds dfs_ds;
 
   /* Perform depth-first search in the reverse graph to find nodes
      reachable from the exit block.  */
@@ -748,6 +759,9 @@ dfs_find_deadend (basic_block bb)
    (from successors to predecessors).
    This ordering can be used for forward dataflow problems among others.
 
+   Optionally if START_POINTS is specified, start from exit block and all
+   basic blocks in START_POINTS.  This is used by CD-DCE.
+
    This function assumes that all blocks in the CFG are reachable
    from the ENTRY (but not necessarily from EXIT).
 
@@ -765,7 +779,8 @@ dfs_find_deadend (basic_block bb)
    and do another inverted traversal from that block.  */
 
 int
-inverted_post_order_compute (int *post_order)
+inverted_post_order_compute (int *post_order,
+                            sbitmap *start_points)
 {
   basic_block bb;
   edge_iterator *stack;
@@ -773,6 +788,9 @@ inverted_post_order_compute (int *post_order)
   int post_order_num = 0;
   sbitmap visited;
 
+  if (flag_checking)
+    verify_no_unreachable_blocks ();
+
   /* Allocate stack for back-tracking up CFG.  */
   stack = XNEWVEC (edge_iterator, n_basic_blocks_for_fn (cfun) + 1);
   sp = 0;
@@ -783,8 +801,24 @@ inverted_post_order_compute (int *post_order)
   /* None of the nodes in the CFG have been visited yet.  */
   bitmap_clear (visited);
 
+  if (start_points)
+    {
+      FOR_ALL_BB_FN (bb, cfun)
+        if (bitmap_bit_p (*start_points, bb->index)
+           && EDGE_COUNT (bb->preds) > 0)
+         {
+            stack[sp++] = ei_start (bb->preds);
+            bitmap_set_bit (visited, bb->index);
+         }
+      if (EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds))
+       {
+          stack[sp++] = ei_start (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds);
+          bitmap_set_bit (visited, EXIT_BLOCK_PTR_FOR_FN (cfun)->index);
+       }
+    }
+  else
   /* Put all blocks that have no successor into the initial work list.  */
-  FOR_ALL_BB (bb)
+  FOR_ALL_BB_FN (bb, cfun)
     if (EDGE_COUNT (bb->succs) == 0)
       {
         /* Push the initial edge on to the stack.  */
@@ -925,7 +959,7 @@ pre_and_rev_post_order_compute_fn (struct function *fn,
        pre_order[pre_order_num] = ENTRY_BLOCK;
       pre_order_num++;
       if (rev_post_order)
-       rev_post_order[rev_post_order_num--] = ENTRY_BLOCK;
+       rev_post_order[rev_post_order_num--] = EXIT_BLOCK;
     }
   else
     rev_post_order_num -= NUM_FIXED_BLOCKS;
@@ -996,7 +1030,7 @@ pre_and_rev_post_order_compute_fn (struct function *fn,
        pre_order[pre_order_num] = EXIT_BLOCK;
       pre_order_num++;
       if (rev_post_order)
-       rev_post_order[rev_post_order_num--] = EXIT_BLOCK;
+       rev_post_order[rev_post_order_num--] = ENTRY_BLOCK;
     }
 
   return pre_order_num;
@@ -1055,7 +1089,7 @@ pre_and_rev_post_order_compute (int *pre_order, int *rev_post_order,
    element on the stack.  */
 
 static void
-flow_dfs_compute_reverse_init (depth_first_search_ds data)
+flow_dfs_compute_reverse_init (depth_first_search_ds *data)
 {
   /* Allocate stack for back-tracking up CFG.  */
   data->stack = XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun));
@@ -1075,7 +1109,7 @@ flow_dfs_compute_reverse_init (depth_first_search_ds data)
    block.  */
 
 static void
-flow_dfs_compute_reverse_add_bb (depth_first_search_ds data, basic_block bb)
+flow_dfs_compute_reverse_add_bb (depth_first_search_ds *data, basic_block bb)
 {
   data->stack[data->sp++] = bb;
   bitmap_set_bit (data->visited_blocks, bb->index);
@@ -1087,7 +1121,7 @@ flow_dfs_compute_reverse_add_bb (depth_first_search_ds data, basic_block bb)
    available.  */
 
 static basic_block
-flow_dfs_compute_reverse_execute (depth_first_search_ds data,
+flow_dfs_compute_reverse_execute (depth_first_search_ds *data,
                                  basic_block last_unvisited)
 {
   basic_block bb;
@@ -1116,7 +1150,7 @@ flow_dfs_compute_reverse_execute (depth_first_search_ds data,
    reverse graph.  */
 
 static void
-flow_dfs_compute_reverse_finish (depth_first_search_ds data)
+flow_dfs_compute_reverse_finish (depth_first_search_ds *data)
 {
   free (data->stack);
   sbitmap_free (data->visited_blocks);
@@ -1236,7 +1270,7 @@ compute_dominance_frontiers_1 (bitmap_head *frontiers)
   edge p;
   edge_iterator ei;
   basic_block b;
-  FOR_EACH_BB (b)
+  FOR_EACH_BB_FN (b, cfun)
     {
       if (EDGE_COUNT (b->preds) >= 2)
        {
@@ -1517,7 +1551,7 @@ single_pred_before_succ_order (void)
   bitmap_clear (visited);
 
   MARK_VISITED (ENTRY_BLOCK_PTR_FOR_FN (cfun));
-  FOR_EACH_BB (x)
+  FOR_EACH_BB_FN (x, cfun)
     {
       if (VISITED_P (x))
        continue;