OSDN Git Service

* tree-ssa-loop-im.c (determine_invariantness_stmt): Attempt to
authorrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 27 Apr 2007 08:20:39 +0000 (08:20 +0000)
committerrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 27 Apr 2007 08:20:39 +0000 (08:20 +0000)
transform only GIMPLE_MODIFY_STMTs.
* tree-complex.c (expand_complex_operations_1): Ditto.
(expand_complex_div_wide): Do not create gotos in COND_EXPR branches.
* tree-ssa-loop-manip.c (build_if_stmt): Removed.
(tree_transform_and_unroll_loop): Do not create gotos in COND_EXPR
branches.
* value-prof.c (tree_divmod_fixed_value, tree_mod_pow2,
tree_mod_subtract, tree_ic, tree_stringop_fixed_value): Ditto.
* omp-low.c (expand_parallel_call, expand_omp_for_generic,
expand_omp_for_static_chunk, expand_omp_for_static_nochunk): Ditto.
* tree-vectorizer.c (slpeel_make_loop_iterate_ntimes,
slpeel_add_loop_guard): Ditto.
* tree-mudflap.c (mf_build_check_statement_for): Ditto.
* lambda-code.c (perfect_nestify): Ditto.
* tree-iterator.c (tsi_split_statement_list_before): Fix splitting
before the first statement.
* tree-optimize.c (execute_free_datastructures): Fix comments.
(execute_free_cfg_annotations): Do not call disband_implicit_edges.
* tree-flow.h (disband_implicit_edges): Declaration removed.
* tree-cfg.c (make_cond_expr_edges): Remove gotos from COND_EXPR
branches.
(cleanup_dead_labels, tree_redirect_edge_and_branch): Handle COND_EXPRs
without gotos.
(disband_implicit_edges, has_label_p): Removed.
(tree_verify_flow_info): Verify that COND_EXPR branches are empty.
(tree_lv_add_condition_to_bb): Do not create gotos in COND_EXPR
branches.
* tree.c (build3_stat): Mark COND_EXPRs used as statements as having
side effects.
* tree-pretty-print.c (dump_implicit_edges): Dump implicit edges
also for COND_EXPRs.
* cfgexpand.c (label_rtx_for_bb): New function.
(expand_gimple_cond_expr): Do not expect gotos in COND_EXPR branches.
Use label_rtx_for_bb to find the labels.
(expand_gimple_basic_block): Remove RETURN_EXPR at the end of the
last block.  Detect fallthru edges.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@124214 138bc75d-0d04-0410-961f-82ee72b054a4

16 files changed:
gcc/ChangeLog
gcc/cfgexpand.c
gcc/lambda-code.c
gcc/omp-low.c
gcc/tree-cfg.c
gcc/tree-complex.c
gcc/tree-flow.h
gcc/tree-iterator.c
gcc/tree-mudflap.c
gcc/tree-optimize.c
gcc/tree-pretty-print.c
gcc/tree-ssa-loop-im.c
gcc/tree-ssa-loop-manip.c
gcc/tree-vectorizer.c
gcc/tree.c
gcc/value-prof.c

index 526c390..447dc85 100644 (file)
@@ -1,3 +1,43 @@
+2007-04-27  Zdenek Dvorak  <dvorakz@suse.cz>
+
+       * tree-ssa-loop-im.c (determine_invariantness_stmt): Attempt to
+       transform only GIMPLE_MODIFY_STMTs.
+       * tree-complex.c (expand_complex_operations_1): Ditto.
+       (expand_complex_div_wide): Do not create gotos in COND_EXPR branches.
+       * tree-ssa-loop-manip.c (build_if_stmt): Removed.
+       (tree_transform_and_unroll_loop): Do not create gotos in COND_EXPR
+       branches.
+       * value-prof.c (tree_divmod_fixed_value, tree_mod_pow2,
+       tree_mod_subtract, tree_ic, tree_stringop_fixed_value): Ditto.
+       * omp-low.c (expand_parallel_call, expand_omp_for_generic,
+       expand_omp_for_static_chunk, expand_omp_for_static_nochunk): Ditto.
+       * tree-vectorizer.c (slpeel_make_loop_iterate_ntimes,
+       slpeel_add_loop_guard): Ditto.
+       * tree-mudflap.c (mf_build_check_statement_for): Ditto.
+       * lambda-code.c (perfect_nestify): Ditto.
+       * tree-iterator.c (tsi_split_statement_list_before): Fix splitting
+       before the first statement.
+       * tree-optimize.c (execute_free_datastructures): Fix comments.
+       (execute_free_cfg_annotations): Do not call disband_implicit_edges.
+       * tree-flow.h (disband_implicit_edges): Declaration removed.
+       * tree-cfg.c (make_cond_expr_edges): Remove gotos from COND_EXPR
+       branches.
+       (cleanup_dead_labels, tree_redirect_edge_and_branch): Handle COND_EXPRs
+       without gotos.
+       (disband_implicit_edges, has_label_p): Removed.
+       (tree_verify_flow_info): Verify that COND_EXPR branches are empty.
+       (tree_lv_add_condition_to_bb): Do not create gotos in COND_EXPR
+       branches.
+       * tree.c (build3_stat): Mark COND_EXPRs used as statements as having
+       side effects.
+       * tree-pretty-print.c (dump_implicit_edges): Dump implicit edges
+       also for COND_EXPRs.
+       * cfgexpand.c (label_rtx_for_bb): New function.
+       (expand_gimple_cond_expr): Do not expect gotos in COND_EXPR branches.
+       Use label_rtx_for_bb to find the labels.
+       (expand_gimple_basic_block): Remove RETURN_EXPR at the end of the
+       last block.  Detect fallthru edges.
+
 2007-04-26  Ian Lance Taylor  <iant@google.com>
 
        PR target/28675
index ab2b9d3..643ff20 100644 (file)
@@ -1244,6 +1244,38 @@ maybe_dump_rtl_for_tree_stmt (tree stmt, rtx since)
     }
 }
 
+/* Returns the label_rtx expression for a label starting basic block BB.  */
+
+static rtx
+label_rtx_for_bb (basic_block bb)
+{
+  tree_stmt_iterator tsi;
+  tree lab, lab_stmt;
+
+  if (bb->flags & BB_RTL)
+    return block_label (bb);
+
+  /* We cannot use tree_block_label, as we no longer have stmt annotations.
+     TODO -- avoid creating the new tree labels.  */
+  for (tsi = tsi_start (bb_stmt_list (bb)); !tsi_end_p (tsi); tsi_next (&tsi))
+    {
+      lab_stmt = tsi_stmt (tsi);
+      if (TREE_CODE (lab_stmt) != LABEL_EXPR)
+       break;
+
+      lab = LABEL_EXPR_LABEL (lab_stmt);
+      if (DECL_NONLOCAL (lab))
+       break;
+
+      return label_rtx (lab);
+    }
+
+  lab = create_artificial_label ();
+  lab_stmt = build1 (LABEL_EXPR, void_type_node, lab);
+  tsi_link_before (&tsi, lab_stmt, TSI_NEW_STMT);
+  return label_rtx (lab);
+}
+
 /* A subroutine of expand_gimple_basic_block.  Expand one COND_EXPR.
    Returns a new basic block if we've terminated the current basic
    block and created a new one.  */
@@ -1256,10 +1288,10 @@ expand_gimple_cond_expr (basic_block bb, tree stmt)
   edge true_edge;
   edge false_edge;
   tree pred = COND_EXPR_COND (stmt);
-  tree then_exp = COND_EXPR_THEN (stmt);
-  tree else_exp = COND_EXPR_ELSE (stmt);
   rtx last2, last;
 
+  gcc_assert (COND_EXPR_THEN (stmt) == NULL_TREE);
+  gcc_assert (COND_EXPR_ELSE (stmt) == NULL_TREE);
   last2 = last = get_last_insn ();
 
   extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
@@ -1275,31 +1307,31 @@ expand_gimple_cond_expr (basic_block bb, tree stmt)
 
   /* We can either have a pure conditional jump with one fallthru edge or
      two-way jump that needs to be decomposed into two basic blocks.  */
-  if (TREE_CODE (then_exp) == GOTO_EXPR && IS_EMPTY_STMT (else_exp))
+  if (false_edge->dest == bb->next_bb)
     {
-      jumpif (pred, label_rtx (GOTO_DESTINATION (then_exp)));
+      jumpif (pred, label_rtx_for_bb (true_edge->dest));
       add_reg_br_prob_note (last, true_edge->probability);
       maybe_dump_rtl_for_tree_stmt (stmt, last);
-      if (EXPR_LOCUS (then_exp))
-       emit_line_note (*(EXPR_LOCUS (then_exp)));
+      if (true_edge->goto_locus)
+       emit_line_note (*true_edge->goto_locus);
+      false_edge->flags |= EDGE_FALLTHRU;
       return NULL;
     }
-  if (TREE_CODE (else_exp) == GOTO_EXPR && IS_EMPTY_STMT (then_exp))
+  if (true_edge->dest == bb->next_bb)
     {
-      jumpifnot (pred, label_rtx (GOTO_DESTINATION (else_exp)));
+      jumpifnot (pred, label_rtx_for_bb (false_edge->dest));
       add_reg_br_prob_note (last, false_edge->probability);
       maybe_dump_rtl_for_tree_stmt (stmt, last);
-      if (EXPR_LOCUS (else_exp))
-       emit_line_note (*(EXPR_LOCUS (else_exp)));
+      if (false_edge->goto_locus)
+       emit_line_note (*false_edge->goto_locus);
+      true_edge->flags |= EDGE_FALLTHRU;
       return NULL;
     }
-  gcc_assert (TREE_CODE (then_exp) == GOTO_EXPR
-             && TREE_CODE (else_exp) == GOTO_EXPR);
 
-  jumpif (pred, label_rtx (GOTO_DESTINATION (then_exp)));
+  jumpif (pred, label_rtx_for_bb (true_edge->dest));
   add_reg_br_prob_note (last, true_edge->probability);
   last = get_last_insn ();
-  expand_expr (else_exp, const0_rtx, VOIDmode, 0);
+  emit_jump (label_rtx_for_bb (false_edge->dest));
 
   BB_END (bb) = last;
   if (BARRIER_P (BB_END (bb)))
@@ -1321,8 +1353,8 @@ expand_gimple_cond_expr (basic_block bb, tree stmt)
 
   maybe_dump_rtl_for_tree_stmt (stmt, last2);
 
-  if (EXPR_LOCUS (else_exp))
-    emit_line_note (*(EXPR_LOCUS (else_exp)));
+  if (false_edge->goto_locus)
+    emit_line_note (*false_edge->goto_locus);
 
   return new_bb;
 }
@@ -1457,6 +1489,25 @@ expand_gimple_basic_block (basic_block bb)
   init_rtl_bb_info (bb);
   bb->flags |= BB_RTL;
 
+  /* Remove the RETURN_EXPR if we may fall though to the exit
+     instead.  */
+  tsi = tsi_last (stmts);
+  if (!tsi_end_p (tsi)
+      && TREE_CODE (tsi_stmt (tsi)) == RETURN_EXPR)
+    {
+      tree ret_stmt = tsi_stmt (tsi);
+
+      gcc_assert (single_succ_p (bb));
+      gcc_assert (single_succ (bb) == EXIT_BLOCK_PTR);
+
+      if (bb->next_bb == EXIT_BLOCK_PTR
+         && !TREE_OPERAND (ret_stmt, 0))
+       {
+         tsi_delink (&tsi);
+         single_succ_edge (bb)->flags |= EDGE_FALLTHRU;
+       }
+    }
+
   tsi = tsi_start (stmts);
   if (!tsi_end_p (tsi))
     stmt = tsi_stmt (tsi);
@@ -1546,6 +1597,21 @@ expand_gimple_basic_block (basic_block bb)
        }
     }
 
+  /* Expand implicit goto.  */
+  FOR_EACH_EDGE (e, ei, bb->succs)
+    {
+      if (e->flags & EDGE_FALLTHRU)
+       break;
+    }
+
+  if (e && e->dest != bb->next_bb)
+    {
+      emit_jump (label_rtx_for_bb (e->dest));
+      if (e->goto_locus)
+       emit_line_note (*e->goto_locus);
+      e->flags &= ~EDGE_FALLTHRU;
+    }
+
   do_pending_stack_adjust ();
 
   /* Find the block tail.  The last insn in the block is the insn
index 487c646..ca07bdc 100644 (file)
@@ -2450,7 +2450,7 @@ perfect_nestify (struct loop *loop,
 {
   basic_block *bbs;
   tree exit_condition;
-  tree then_label, else_label, cond_stmt;
+  tree cond_stmt;
   basic_block preheaderbb, headerbb, bodybb, latchbb, olddest;
   int i;
   block_stmt_iterator bsi, firstbsi;
@@ -2498,13 +2498,11 @@ perfect_nestify (struct loop *loop,
   bodybb = create_empty_bb (EXIT_BLOCK_PTR->prev_bb);
   latchbb = create_empty_bb (EXIT_BLOCK_PTR->prev_bb);
   make_edge (headerbb, bodybb, EDGE_FALLTHRU); 
-  then_label = build1 (GOTO_EXPR, void_type_node, tree_block_label (latchbb));
-  else_label = build1 (GOTO_EXPR, void_type_node, tree_block_label (olddest));
   cond_stmt = build3 (COND_EXPR, void_type_node,
                      build2 (NE_EXPR, boolean_type_node, 
                              integer_one_node, 
                              integer_zero_node), 
-                     then_label, else_label);
+                     NULL_TREE, NULL_TREE);
   bsi = bsi_start (bodybb);
   bsi_insert_after (&bsi, cond_stmt, BSI_NEW_STMT);
   e = make_edge (bodybb, olddest, EDGE_FALSE_VALUE);
index ef29e96..234c860 100644 (file)
@@ -2203,7 +2203,7 @@ expand_parallel_call (struct omp_region *region, basic_block bb,
        {
          basic_block cond_bb, then_bb, else_bb;
          edge e;
-         tree t, then_lab, else_lab, tmp;
+         tree t, tmp;
 
          tmp = create_tmp_var (TREE_TYPE (val), NULL);
          e = split_block (bb, NULL);
@@ -2213,26 +2213,18 @@ expand_parallel_call (struct omp_region *region, basic_block bb,
 
          then_bb = create_empty_bb (cond_bb);
          else_bb = create_empty_bb (then_bb);
-         then_lab = create_artificial_label ();
-         else_lab = create_artificial_label ();
 
          t = build3 (COND_EXPR, void_type_node,
-                     cond,
-                     build_and_jump (&then_lab),
-                     build_and_jump (&else_lab));
+                     cond, NULL_TREE, NULL_TREE);
 
          si = bsi_start (cond_bb);
          bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
 
          si = bsi_start (then_bb);
-         t = build1 (LABEL_EXPR, void_type_node, then_lab);
-         bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
          t = build_gimple_modify_stmt (tmp, val);
          bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
 
          si = bsi_start (else_bb);
-         t = build1 (LABEL_EXPR, void_type_node, else_lab);
-         bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
          t = build_gimple_modify_stmt (tmp, 
                                        build_int_cst (unsigned_type_node, 1));
          bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
@@ -2579,7 +2571,6 @@ expand_omp_for_generic (struct omp_region *region,
                        enum built_in_function start_fn,
                        enum built_in_function next_fn)
 {
-  tree l0, l1, l2 = NULL, l3 = NULL;
   tree type, istart0, iend0, iend;
   tree t, list;
   basic_block entry_bb, cont_bb, exit_bb, l0_bb, l1_bb;
@@ -2601,18 +2592,12 @@ expand_omp_for_generic (struct omp_region *region,
   l0_bb = create_empty_bb (entry_bb);
   l1_bb = single_succ (entry_bb);
 
-  l0 = tree_block_label (l0_bb);
-  l1 = tree_block_label (l1_bb);
-
   cont_bb = region->cont;
   exit_bb = region->exit;
   if (cont_bb)
     {
       l2_bb = create_empty_bb (cont_bb);
       l3_bb = single_succ (cont_bb);
-
-      l2 = tree_block_label (l2_bb);
-      l3 = tree_block_label (l3_bb);
     }
 
   si = bsi_last (entry_bb);
@@ -2640,8 +2625,7 @@ expand_omp_for_generic (struct omp_region *region,
       t = get_formal_tmp_var (t, &list);
       if (cont_bb)
        {
-         t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&l0),
-                     build_and_jump (&l3));
+         t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
          append_to_statement_list (t, &list);
        }
       bsi_insert_after (&si, list, BSI_SAME_STMT);
@@ -2682,8 +2666,7 @@ expand_omp_for_generic (struct omp_region *region,
   
   t = build2 (fd->cond_code, boolean_type_node, fd->v, iend);
   t = get_formal_tmp_var (t, &list);
-  t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&l1),
-             build_and_jump (&l2));
+  t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
   append_to_statement_list (t, &list);
 
   si = bsi_last (cont_bb);
@@ -2698,8 +2681,7 @@ expand_omp_for_generic (struct omp_region *region,
                       build_fold_addr_expr (istart0),
                       build_fold_addr_expr (iend0));
   t = get_formal_tmp_var (t, &list);
-  t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&l0),
-             build_and_jump (&l3));
+  t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
   append_to_statement_list (t, &list);
   
   si = bsi_start (l2_bb);
@@ -2768,7 +2750,7 @@ static void
 expand_omp_for_static_nochunk (struct omp_region *region,
                               struct omp_for_data *fd)
 {
-  tree l0, l1, l2, n, q, s0, e0, e, t, nthreads, threadid;
+  tree n, q, s0, e0, e, t, nthreads, threadid;
   tree type, list;
   basic_block entry_bb, exit_bb, seq_start_bb, body_bb, cont_bb;
   basic_block fin_bb;
@@ -2783,10 +2765,6 @@ expand_omp_for_static_nochunk (struct omp_region *region,
   fin_bb = single_succ (cont_bb);
   exit_bb = region->exit;
 
-  l0 = tree_block_label (seq_start_bb);
-  l1 = tree_block_label (body_bb);
-  l2 = tree_block_label (fin_bb);
-
   /* Iteration space partitioning goes in ENTRY_BB.  */
   list = alloc_stmt_list ();
 
@@ -2837,8 +2815,7 @@ expand_omp_for_static_nochunk (struct omp_region *region,
   e0 = get_formal_tmp_var (t, &list);
 
   t = build2 (GE_EXPR, boolean_type_node, s0, e0);
-  t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&l2),
-             build_and_jump (&l0));
+  t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
   append_to_statement_list (t, &list);
 
   si = bsi_last (entry_bb);
@@ -2872,8 +2849,7 @@ expand_omp_for_static_nochunk (struct omp_region *region,
 
   t = build2 (fd->cond_code, boolean_type_node, fd->v, e);
   t = get_formal_tmp_var (t, &list);
-  t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&l1),
-             build_and_jump (&l2));
+  t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
   append_to_statement_list (t, &list);
 
   si = bsi_last (cont_bb);
@@ -2937,7 +2913,7 @@ expand_omp_for_static_nochunk (struct omp_region *region,
 static void
 expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
 {
-  tree l0, l1, l2, l3, l4, n, s0, e0, e, t;
+  tree n, s0, e0, e, t;
   tree trip, nthreads, threadid;
   tree type;
   basic_block entry_bb, exit_bb, body_bb, seq_start_bb, iter_part_bb;
@@ -2956,12 +2932,6 @@ expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
   fin_bb = single_succ (cont_bb);
   exit_bb = region->exit;
 
-  l0 = tree_block_label (iter_part_bb);
-  l1 = tree_block_label (seq_start_bb);
-  l2 = tree_block_label (body_bb);
-  l3 = tree_block_label (trip_update_bb);
-  l4 = tree_block_label (fin_bb);
-
   /* Trip and adjustment setup goes in ENTRY_BB.  */
   list = alloc_stmt_list ();
 
@@ -3021,8 +2991,7 @@ expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
   e0 = get_formal_tmp_var (t, &list);
 
   t = build2 (LT_EXPR, boolean_type_node, s0, n);
-  t = build3 (COND_EXPR, void_type_node, t,
-             build_and_jump (&l1), build_and_jump (&l4));
+  t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
   append_to_statement_list (t, &list);
 
   si = bsi_start (iter_part_bb);
@@ -3055,8 +3024,7 @@ expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
 
   t = build2 (fd->cond_code, boolean_type_node, fd->v, e);
   t = get_formal_tmp_var (t, &list);
-  t = build3 (COND_EXPR, void_type_node, t,
-             build_and_jump (&l2), build_and_jump (&l3));
+  t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
   append_to_statement_list (t, &list);
   
   si = bsi_last (cont_bb);
index 878ba6f..59e1cc3 100644 (file)
@@ -615,6 +615,10 @@ make_cond_expr_edges (basic_block bb)
       e->goto_locus = EXPR_LOCUS (COND_EXPR_ELSE (entry));
 #endif
     }
+
+  /* We do not need the gotos anymore.  */
+  COND_EXPR_THEN (entry) = NULL_TREE;
+  COND_EXPR_ELSE (entry) = NULL_TREE;
 }
 
 
@@ -928,10 +932,12 @@ cleanup_dead_labels (void)
            true_branch = COND_EXPR_THEN (stmt);
            false_branch = COND_EXPR_ELSE (stmt);
 
-           GOTO_DESTINATION (true_branch)
-             = main_block_label (GOTO_DESTINATION (true_branch));
-           GOTO_DESTINATION (false_branch)
-             = main_block_label (GOTO_DESTINATION (false_branch));
+           if (true_branch)
+             GOTO_DESTINATION (true_branch)
+                     = main_block_label (GOTO_DESTINATION (true_branch));
+           if (false_branch)
+             GOTO_DESTINATION (false_branch)
+                     = main_block_label (GOTO_DESTINATION (false_branch));
 
            break;
          }
@@ -2522,87 +2528,6 @@ stmt_ends_bb_p (tree t)
   return is_ctrl_stmt (t) || is_ctrl_altering_stmt (t);
 }
 
-
-/* Add gotos that used to be represented implicitly in the CFG.  */
-
-void
-disband_implicit_edges (void)
-{
-  basic_block bb;
-  block_stmt_iterator last;
-  edge e;
-  edge_iterator ei;
-  tree stmt, label;
-
-  FOR_EACH_BB (bb)
-    {
-      last = bsi_last (bb);
-      stmt = last_stmt (bb);
-
-      if (stmt && TREE_CODE (stmt) == COND_EXPR)
-       {
-         /* Remove superfluous gotos from COND_EXPR branches.  Moved
-            from cfg_remove_useless_stmts here since it violates the
-            invariants for tree--cfg correspondence and thus fits better
-            here where we do it anyway.  */
-         e = find_edge (bb, bb->next_bb);
-         if (e)
-           {
-             if (e->flags & EDGE_TRUE_VALUE)
-               COND_EXPR_THEN (stmt) = build_empty_stmt ();
-             else if (e->flags & EDGE_FALSE_VALUE)
-               COND_EXPR_ELSE (stmt) = build_empty_stmt ();
-             else
-               gcc_unreachable ();
-             e->flags |= EDGE_FALLTHRU;
-           }
-
-         continue;
-       }
-
-      if (stmt && TREE_CODE (stmt) == RETURN_EXPR)
-       {
-         /* Remove the RETURN_EXPR if we may fall though to the exit
-            instead.  */
-         gcc_assert (single_succ_p (bb));
-         gcc_assert (single_succ (bb) == EXIT_BLOCK_PTR);
-
-         if (bb->next_bb == EXIT_BLOCK_PTR
-             && !TREE_OPERAND (stmt, 0))
-           {
-             bsi_remove (&last, true);
-             single_succ_edge (bb)->flags |= EDGE_FALLTHRU;
-           }
-         continue;
-       }
-
-      /* There can be no fallthru edge if the last statement is a control
-        one.  */
-      if (stmt && is_ctrl_stmt (stmt))
-       continue;
-
-      /* Find a fallthru edge and emit the goto if necessary.  */
-      FOR_EACH_EDGE (e, ei, bb->succs)
-       if (e->flags & EDGE_FALLTHRU)
-         break;
-
-      if (!e || e->dest == bb->next_bb)
-       continue;
-
-      gcc_assert (e->dest != EXIT_BLOCK_PTR);
-      label = tree_block_label (e->dest);
-
-      stmt = build1 (GOTO_EXPR, void_type_node, label);
-#ifdef USE_MAPPED_LOCATION
-      SET_EXPR_LOCATION (stmt, e->goto_locus);
-#else
-      SET_EXPR_LOCUS (stmt, e->goto_locus);
-#endif
-      bsi_insert_after (&last, stmt, BSI_NEW_STMT);
-      e->flags &= ~EDGE_FALLTHRU;
-    }
-}
-
 /* Remove block annotations and other datastructures.  */
 
 void
@@ -3136,27 +3061,6 @@ tree_split_edge (edge edge_in)
   return new_bb;
 }
 
-
-/* Return true when BB has label LABEL in it.  */
-
-static bool
-has_label_p (basic_block bb, tree label)
-{
-  block_stmt_iterator bsi;
-
-  for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
-    {
-      tree stmt = bsi_stmt (bsi);
-
-      if (TREE_CODE (stmt) != LABEL_EXPR)
-       return false;
-      if (LABEL_EXPR_LABEL (stmt) == label)
-       return true;
-    }
-  return false;
-}
-
-
 /* Callback for walk_tree, check that all elements with address taken are
    properly noticed as such.  The DATA is an int* that is 1 if TP was seen
    inside a PHI node.  */
@@ -3789,10 +3693,12 @@ tree_verify_flow_info (void)
          {
            edge true_edge;
            edge false_edge;
-           if (TREE_CODE (COND_EXPR_THEN (stmt)) != GOTO_EXPR
-               || TREE_CODE (COND_EXPR_ELSE (stmt)) != GOTO_EXPR)
+  
+           if (COND_EXPR_THEN (stmt) != NULL_TREE
+               || COND_EXPR_ELSE (stmt) != NULL_TREE)
              {
-               error ("structured COND_EXPR at the end of bb %d", bb->index);
+               error ("COND_EXPR with code in branches at the end of bb %d",
+                      bb->index);
                err = 1;
              }
 
@@ -3809,22 +3715,6 @@ tree_verify_flow_info (void)
                       bb->index);
                err = 1;
              }
-
-           if (!has_label_p (true_edge->dest,
-                             GOTO_DESTINATION (COND_EXPR_THEN (stmt))))
-             {
-               error ("%<then%> label does not match edge at end of bb %d",
-                      bb->index);
-               err = 1;
-             }
-
-           if (!has_label_p (false_edge->dest,
-                             GOTO_DESTINATION (COND_EXPR_ELSE (stmt))))
-             {
-               error ("%<else%> label does not match edge at end of bb %d",
-                      bb->index);
-               err = 1;
-             }
          }
          break;
 
@@ -4103,10 +3993,7 @@ tree_redirect_edge_and_branch (edge e, basic_block dest)
   switch (stmt ? TREE_CODE (stmt) : ERROR_MARK)
     {
     case COND_EXPR:
-      stmt = (e->flags & EDGE_TRUE_VALUE
-             ? COND_EXPR_THEN (stmt)
-             : COND_EXPR_ELSE (stmt));
-      GOTO_DESTINATION (stmt) = label;
+      /* For COND_EXPR, we only need to redirect the edge.  */
       break;
 
     case GOTO_EXPR:
@@ -5676,20 +5563,18 @@ tree_lv_adjust_loop_header_phi (basic_block first, basic_block second,
    SECOND_HEAD is the destination of the THEN and FIRST_HEAD is
    the destination of the ELSE part.  */
 static void
-tree_lv_add_condition_to_bb (basic_block first_head, basic_block second_head,
-                            basic_block cond_bb, void *cond_e)
+tree_lv_add_condition_to_bb (basic_block first_head ATTRIBUTE_UNUSED,
+                            basic_block second_head ATTRIBUTE_UNUSED,
+                            basic_block cond_bb, void *cond_e)
 {
   block_stmt_iterator bsi;
-  tree goto1 = NULL_TREE;
-  tree goto2 = NULL_TREE;
   tree new_cond_expr = NULL_TREE;
   tree cond_expr = (tree) cond_e;
   edge e0;
 
   /* Build new conditional expr */
-  goto1 = build1 (GOTO_EXPR, void_type_node, tree_block_label (first_head));
-  goto2 = build1 (GOTO_EXPR, void_type_node, tree_block_label (second_head));
-  new_cond_expr = build3 (COND_EXPR, void_type_node, cond_expr, goto1, goto2);
+  new_cond_expr = build3 (COND_EXPR, void_type_node, cond_expr,
+                         NULL_TREE, NULL_TREE);
 
   /* Add new cond in cond_bb.  */
   bsi = bsi_start (cond_bb);
index 3f479ed..71ebeac 100644 (file)
@@ -1060,11 +1060,6 @@ expand_complex_div_wide (block_stmt_iterator *bsi, tree inner_type,
       bb_true = create_empty_bb (bb_cond);
       bb_false = create_empty_bb (bb_true);
 
-      t1 = build1 (GOTO_EXPR, void_type_node, tree_block_label (bb_true));
-      t2 = build1 (GOTO_EXPR, void_type_node, tree_block_label (bb_false));
-      COND_EXPR_THEN (cond) = t1;
-      COND_EXPR_ELSE (cond) = t2;
-
       /* Wire the blocks together.  */
       e->flags = EDGE_TRUE_VALUE;
       redirect_edge_succ (e, bb_true);
@@ -1377,8 +1372,15 @@ expand_complex_operations_1 (block_stmt_iterator *bsi)
 
     default:
       {
-       tree lhs = GENERIC_TREE_OPERAND (stmt, 0);
-       tree rhs = GENERIC_TREE_OPERAND (stmt, 1);
+       tree lhs, rhs;
+
+       /* COND_EXPR may also fallthru here, but we do not need to do anything
+          with it.  */
+       if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+         return;
+
+       lhs = GIMPLE_STMT_OPERAND (stmt, 0);
+       rhs = GIMPLE_STMT_OPERAND (stmt, 1);
 
        if (TREE_CODE (type) == COMPLEX_TYPE)
          expand_complex_move (bsi, stmt, type, lhs, rhs);
index b7f6585..d308299 100644 (file)
@@ -722,7 +722,6 @@ extern void free_omp_regions (void);
 #define PENDING_STMT(e)        ((e)->insns.t)
 
 extern void delete_tree_cfg_annotations (void);
-extern void disband_implicit_edges (void);
 extern bool stmt_ends_bb_p (tree);
 extern bool is_ctrl_stmt (tree);
 extern bool is_ctrl_altering_stmt (tree);
index 77e2345..ac033ae 100644 (file)
@@ -291,6 +291,8 @@ tsi_split_statement_list_before (tree_stmt_iterator *i)
   cur->prev = NULL;
   if (prev)
     prev->next = NULL;
+  else
+    STATEMENT_LIST_HEAD (old_sl) = NULL;
 
   return new_sl;
 }
index 698114e..72e53e6 100644 (file)
@@ -630,9 +630,7 @@ mf_build_check_statement_for (tree base, tree limit,
 
   /* Build the conditional jump.  'cond' is just a temporary so we can
      simply build a void COND_EXPR.  We do need labels in both arms though.  */
-  t = build3 (COND_EXPR, void_type_node, cond,
-              build1 (GOTO_EXPR, void_type_node, tree_block_label (then_bb)),
-              build1 (GOTO_EXPR, void_type_node, tree_block_label (join_bb)));
+  t = build3 (COND_EXPR, void_type_node, cond, NULL_TREE, NULL_TREE);
   SET_EXPR_LOCUS (t, locus);
   tsi_link_after (&tsi, t, TSI_CONTINUE_LINKING);
 
@@ -685,7 +683,6 @@ mf_build_check_statement_for (tree base, tree limit,
     bsi_insert_after (&bsi, tsi_stmt (tsi), BSI_CONTINUE_LINKING);
 
   *instr_bsi = bsi_start (join_bb);
-  bsi_next (instr_bsi);
 }
 
 
index e122f48..c9f24cb 100644 (file)
@@ -208,13 +208,10 @@ struct tree_opt_pass pass_cleanup_cfg_post_optimizing =
 static unsigned int
 execute_free_datastructures (void)
 {
-  /* ??? This isn't the right place for this.  Worse, it got computed
-     more or less at random in various passes.  */
   free_dominance_info (CDI_DOMINATORS);
   free_dominance_info (CDI_POST_DOMINATORS);
 
-  /* Remove the ssa structures.  Do it here since this includes statement
-     annotations that need to be intact during disband_implicit_edges.  */
+  /* Remove the ssa structures.  */
   if (cfun->gimple_df)
     delete_tree_ssa ();
   return 0;
@@ -241,9 +238,6 @@ struct tree_opt_pass pass_free_datastructures =
 static unsigned int
 execute_free_cfg_annotations (void)
 {
-  /* Emit gotos for implicit jumps.  */
-  disband_implicit_edges ();
-
   /* And get rid of annotations we no longer need.  */
   delete_tree_cfg_annotations ();
 
index 32f8ac0..09d203f 100644 (file)
@@ -2958,6 +2958,29 @@ dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
 {
   edge e;
   edge_iterator ei;
+  tree stmt;
+
+  stmt = last_stmt (bb);
+  if (stmt && TREE_CODE (stmt) == COND_EXPR)
+    {
+      edge true_edge, false_edge;
+
+      /* When we are emitting the code or changing CFG, it is possible that
+        the edges are not yet created.  When we are using debug_bb in such
+        a situation, we do not want it to crash.  */
+      if (EDGE_COUNT (bb->succs) != 2)
+       return;
+      extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
+
+      INDENT (indent + 2);
+      pp_cfg_jump (buffer, true_edge->dest);
+      newline_and_indent (buffer, indent);
+      pp_string (buffer, "else");
+      newline_and_indent (buffer, indent + 2);
+      pp_cfg_jump (buffer, false_edge->dest);
+      pp_newline (buffer);
+      return;
+    }
 
   /* If there is a fallthru edge, we may need to add an artificial goto to the
      dump.  */
index 1e36fae..c5578cf 100644 (file)
@@ -731,29 +731,32 @@ determine_invariantness_stmt (struct dom_walk_data *dw_data ATTRIBUTE_UNUSED,
          continue;
        }
 
-      rhs = GENERIC_TREE_OPERAND (stmt, 1);
-
-      /* If divisor is invariant, convert a/b to a*(1/b), allowing reciprocal
-        to be hoisted out of loop, saving expensive divide.  */
-      if (pos == MOVE_POSSIBLE
-         && TREE_CODE (rhs) == RDIV_EXPR
-         && flag_unsafe_math_optimizations
-         && !flag_trapping_math
-         && outermost_invariant_loop_expr (TREE_OPERAND (rhs, 1),
-                                           loop_containing_stmt (stmt)) != NULL
-         && outermost_invariant_loop_expr (rhs,
-                                           loop_containing_stmt (stmt)) == NULL)
-       stmt = rewrite_reciprocal (&bsi);
-
-      /* If the shift count is invariant, convert (A >> B) & 1 to
-        A & (1 << B) allowing the bit mask to be hoisted out of the loop
-        saving an expensive shift.  */
-      if (pos == MOVE_POSSIBLE
-         && TREE_CODE (rhs) == BIT_AND_EXPR
-         && integer_onep (TREE_OPERAND (rhs, 1))
-         && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME
-         && has_single_use (TREE_OPERAND (rhs, 0)))
-       stmt = rewrite_bittest (&bsi);
+      if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
+       {
+         rhs = GIMPLE_STMT_OPERAND (stmt, 1);
+
+         /* If divisor is invariant, convert a/b to a*(1/b), allowing reciprocal
+            to be hoisted out of loop, saving expensive divide.  */
+         if (pos == MOVE_POSSIBLE
+             && TREE_CODE (rhs) == RDIV_EXPR
+             && flag_unsafe_math_optimizations
+             && !flag_trapping_math
+             && outermost_invariant_loop_expr (TREE_OPERAND (rhs, 1),
+                                               loop_containing_stmt (stmt)) != NULL
+             && outermost_invariant_loop_expr (rhs,
+                                               loop_containing_stmt (stmt)) == NULL)
+           stmt = rewrite_reciprocal (&bsi);
+
+         /* If the shift count is invariant, convert (A >> B) & 1 to
+            A & (1 << B) allowing the bit mask to be hoisted out of the loop
+            saving an expensive shift.  */
+         if (pos == MOVE_POSSIBLE
+             && TREE_CODE (rhs) == BIT_AND_EXPR
+             && integer_onep (TREE_OPERAND (rhs, 1))
+             && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME
+             && has_single_use (TREE_OPERAND (rhs, 0)))
+           stmt = rewrite_bittest (&bsi);
+       }
 
       stmt_ann (stmt)->common.aux = xcalloc (1, sizeof (struct lim_aux_data));
       LIM_DATA (stmt)->always_executed_in = outermost;
index 30f8534..7611a6f 100644 (file)
@@ -604,17 +604,6 @@ tree_duplicate_loop_to_header_edge (struct loop *loop, edge e,
   return true;
 }
 
-/* Build if (COND) goto THEN_LABEL; else goto ELSE_LABEL;  */
-
-static tree
-build_if_stmt (tree cond, tree then_label, tree else_label)
-{
-  return build3 (COND_EXPR, void_type_node,
-                cond,
-                build1 (GOTO_EXPR, void_type_node, then_label),
-                build1 (GOTO_EXPR, void_type_node, else_label));
-}
-
 /* Returns true if we can unroll LOOP FACTOR times.  Number
    of iterations of the loop is returned in NITER.  */
 
@@ -932,9 +921,9 @@ tree_transform_and_unroll_loop (struct loop *loop, unsigned factor,
                                  REG_BR_PROB_BASE - exit->probability);
 
   bsi = bsi_last (exit_bb);
-  exit_if = build_if_stmt (boolean_true_node,
-                          tree_block_label (loop->latch),
-                          tree_block_label (rest));
+  exit_if = build3 (COND_EXPR, void_type_node, boolean_true_node,
+                   NULL_TREE, NULL_TREE);
+
   bsi_insert_after (&bsi, exit_if, BSI_NEW_STMT);
   new_exit = make_edge (exit_bb, rest, EDGE_FALSE_VALUE | irr);
   rescan_loop_exit (new_exit, true, false);
index 3c41c5c..d235a49 100644 (file)
@@ -767,12 +767,8 @@ slpeel_make_loop_iterate_ntimes (struct loop *loop, tree niters)
   block_stmt_iterator loop_cond_bsi;
   block_stmt_iterator incr_bsi;
   bool insert_after;
-  tree begin_label = tree_block_label (loop->latch);
-  tree exit_label = tree_block_label (single_exit (loop)->dest);
   tree init = build_int_cst (TREE_TYPE (niters), 0);
   tree step = build_int_cst (TREE_TYPE (niters), 1);
-  tree then_label;
-  tree else_label;
   LOC loop_loc;
 
   orig_cond = get_loop_exit_condition (loop);
@@ -784,20 +780,12 @@ slpeel_make_loop_iterate_ntimes (struct loop *loop, tree niters)
              &incr_bsi, insert_after, &indx_before_incr, &indx_after_incr);
 
   if (exit_edge->flags & EDGE_TRUE_VALUE) /* 'then' edge exits the loop.  */
-    {
-      cond = build2 (GE_EXPR, boolean_type_node, indx_after_incr, niters);
-      then_label = build1 (GOTO_EXPR, void_type_node, exit_label);
-      else_label = build1 (GOTO_EXPR, void_type_node, begin_label);
-    }
+    cond = build2 (GE_EXPR, boolean_type_node, indx_after_incr, niters);
   else /* 'then' edge loops back.  */
-    {
-      cond = build2 (LT_EXPR, boolean_type_node, indx_after_incr, niters);
-      then_label = build1 (GOTO_EXPR, void_type_node, begin_label);
-      else_label = build1 (GOTO_EXPR, void_type_node, exit_label);
-    }
+    cond = build2 (LT_EXPR, boolean_type_node, indx_after_incr, niters);
 
   cond_stmt = build3 (COND_EXPR, TREE_TYPE (orig_cond), cond,
-                    then_label, else_label);
+                     NULL_TREE, NULL_TREE);
   bsi_insert_before (&loop_cond_bsi, cond_stmt, BSI_SAME_STMT);
 
   /* Remove old loop exit test:  */
@@ -935,19 +923,15 @@ slpeel_add_loop_guard (basic_block guard_bb, tree cond, basic_block exit_bb,
 {
   block_stmt_iterator bsi;
   edge new_e, enter_e;
-  tree cond_stmt, then_label, else_label;
+  tree cond_stmt;
 
   enter_e = EDGE_SUCC (guard_bb, 0);
   enter_e->flags &= ~EDGE_FALLTHRU;
   enter_e->flags |= EDGE_FALSE_VALUE;
   bsi = bsi_last (guard_bb);
 
-  then_label = build1 (GOTO_EXPR, void_type_node,
-                       tree_block_label (exit_bb));
-  else_label = build1 (GOTO_EXPR, void_type_node,
-                       tree_block_label (enter_e->dest));
   cond_stmt = build3 (COND_EXPR, void_type_node, cond,
-                    then_label, else_label);
+                     NULL_TREE, NULL_TREE);
   bsi_insert_after (&bsi, cond_stmt, BSI_NEW_STMT);
   /* Add new edge to connect guard block to the merge/loop-exit block.  */
   new_e = make_edge (guard_bb, exit_bb, EDGE_TRUE_VALUE);
index 0ea18b2..1f2e919 100644 (file)
@@ -3128,7 +3128,16 @@ build3_stat (enum tree_code code, tree tt, tree arg0, tree arg1,
   t = make_node_stat (code PASS_MEM_STAT);
   TREE_TYPE (t) = tt;
 
-  side_effects = TREE_SIDE_EFFECTS (t);
+  /* As a special exception, if COND_EXPR has NULL branches, we
+     assume that it is a gimple statement and always consider
+     it to have side effects.  */
+  if (code == COND_EXPR
+      && tt == void_type_node
+      && arg1 == NULL_TREE
+      && arg2 == NULL_TREE)
+    side_effects = true;
+  else
+    side_effects = TREE_SIDE_EFFECTS (t);
 
   PROCESS_ARG(0);
   PROCESS_ARG(1);
index 24a2171..e015855 100644 (file)
@@ -527,8 +527,7 @@ tree_divmod_fixed_value (tree stmt, tree operation,
   stmt2 = build_gimple_modify_stmt (tmp1, op2);
   stmt3 = build3 (COND_EXPR, void_type_node,
            build2 (NE_EXPR, boolean_type_node, tmp1, tmpv),
-           build1 (GOTO_EXPR, void_type_node, label_decl2),
-           build1 (GOTO_EXPR, void_type_node, label_decl1));
+           NULL_TREE, NULL_TREE);
   bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
   bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT);
   bsi_insert_before (&bsi, stmt3, BSI_SAME_STMT);
@@ -689,8 +688,7 @@ tree_mod_pow2 (tree stmt, tree operation, tree op1, tree op2, int prob,
   stmt4 = build3 (COND_EXPR, void_type_node,
                  build2 (NE_EXPR, boolean_type_node,
                          tmp3, build_int_cst (optype, 0)),
-                 build1 (GOTO_EXPR, void_type_node, label_decl2),
-                 build1 (GOTO_EXPR, void_type_node, label_decl1));
+                 NULL_TREE, NULL_TREE);
   bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT);
   bsi_insert_before (&bsi, stmt3, BSI_SAME_STMT);
   bsi_insert_before (&bsi, stmt4, BSI_SAME_STMT);
@@ -845,9 +843,7 @@ tree_mod_subtract (tree stmt, tree operation, tree op1, tree op2,
   stmt2 = build_gimple_modify_stmt (tmp1, op2);
   stmt3 = build3 (COND_EXPR, void_type_node,
            build2 (LT_EXPR, boolean_type_node, result, tmp1),
-           build1 (GOTO_EXPR, void_type_node, label_decl3),
-           build1 (GOTO_EXPR, void_type_node, 
-                   ncounts ? label_decl1 : label_decl2));
+           NULL_TREE, NULL_TREE);
   bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
   bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT);
   bsi_insert_before (&bsi, stmt3, BSI_SAME_STMT);
@@ -861,8 +857,7 @@ tree_mod_subtract (tree stmt, tree operation, tree op1, tree op2,
                                                result, tmp1));
       stmt2 = build3 (COND_EXPR, void_type_node,
                build2 (LT_EXPR, boolean_type_node, result, tmp1),
-               build1 (GOTO_EXPR, void_type_node, label_decl3),
-               build1 (GOTO_EXPR, void_type_node, label_decl2));
+               NULL_TREE, NULL_TREE);
       bsi_insert_before (&bsi, label1, BSI_SAME_STMT);
       bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
       bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT);
@@ -1084,8 +1079,7 @@ tree_ic (tree stmt, tree call, struct cgraph_node* direct_call,
   stmt2 = build_gimple_modify_stmt (tmp1, tmp);
   stmt3 = build3 (COND_EXPR, void_type_node,
                  build2 (NE_EXPR, boolean_type_node, tmp1, tmpv),
-                 build1 (GOTO_EXPR, void_type_node, label_decl2),
-                 build1 (GOTO_EXPR, void_type_node, label_decl1));
+                 NULL_TREE, NULL_TREE);
   bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
   bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT);
   bsi_insert_before (&bsi, stmt3, BSI_SAME_STMT);
@@ -1288,8 +1282,7 @@ tree_stringop_fixed_value (tree stmt, tree value, int prob, gcov_type count,
   stmt2 = build_gimple_modify_stmt (tmp1, blck_size);
   stmt3 = build3 (COND_EXPR, void_type_node,
            build2 (NE_EXPR, boolean_type_node, tmp1, tmpv),
-           build1 (GOTO_EXPR, void_type_node, label_decl2),
-           build1 (GOTO_EXPR, void_type_node, label_decl1));
+           NULL_TREE, NULL_TREE);
   bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
   bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT);
   bsi_insert_before (&bsi, stmt3, BSI_SAME_STMT);