OSDN Git Service

* c-pretty-print.c (pp_c_specifier_qualifier_list) [VECTOR_TYPE]:
[pf3gnuchains/gcc-fork.git] / gcc / tree-cfg.c
index b6e9006..01fefc3 100644 (file)
@@ -1,6 +1,6 @@
 /* Control flow functions for trees.
-   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
-   Free Software Foundation, Inc.
+   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
+   2010  Free Software Foundation, Inc.
    Contributed by Diego Novillo <dnovillo@redhat.com>
 
 This file is part of GCC.
@@ -1438,27 +1438,12 @@ gimple_can_merge_blocks_p (basic_block a, basic_block b)
     return false;
 
   /* It must be possible to eliminate all phi nodes in B.  If ssa form
-     is not up-to-date, we cannot eliminate any phis; however, if only
-     some symbols as whole are marked for renaming, this is not a problem,
-     as phi nodes for those symbols are irrelevant in updating anyway.  */
+     is not up-to-date and a name-mapping is registered, we cannot eliminate
+     any phis.  Symbols marked for renaming are never a problem though.  */
   phis = phi_nodes (b);
-  if (!gimple_seq_empty_p (phis))
-    {
-      gimple_stmt_iterator i;
-
-      if (name_mappings_registered_p ())
-       return false;
-
-      for (i = gsi_start (phis); !gsi_end_p (i); gsi_next (&i))
-       {
-         gimple phi = gsi_stmt (i);
-
-         if (!is_gimple_reg (gimple_phi_result (phi))
-             && !may_propagate_copy (gimple_phi_result (phi),
-                                     gimple_phi_arg_def (phi, 0)))
-           return false;
-       }
-    }
+  if (!gimple_seq_empty_p (phis)
+      && name_mappings_registered_p ())
+    return false;
 
   return true;
 }
@@ -1632,6 +1617,9 @@ gimple_merge_blocks (basic_block a, basic_block b)
              FOR_EACH_IMM_USE_STMT (stmt, iter, def)
                FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
                  SET_USE (use_p, use);
+
+             if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def))
+               SSA_NAME_OCCURS_IN_ABNORMAL_PHI (use) = 1;
            }
          else
             replace_uses_by (def, use);
@@ -3287,13 +3275,13 @@ verify_gimple_assign_binary (gimple stmt)
        if ((!INTEGRAL_TYPE_P (rhs1_type)
             && !FIXED_POINT_TYPE_P (rhs1_type)
             && !(TREE_CODE (rhs1_type) == VECTOR_TYPE
-                 && TREE_CODE (TREE_TYPE (rhs1_type)) == INTEGER_TYPE))
+                 && INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type))))
            || (!INTEGRAL_TYPE_P (rhs2_type)
                /* Vector shifts of vectors are also ok.  */
                && !(TREE_CODE (rhs1_type) == VECTOR_TYPE
-                    && TREE_CODE (TREE_TYPE (rhs1_type)) == INTEGER_TYPE
+                    && INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type))
                     && TREE_CODE (rhs2_type) == VECTOR_TYPE
-                    && TREE_CODE (TREE_TYPE (rhs2_type)) == INTEGER_TYPE))
+                    && INTEGRAL_TYPE_P (TREE_TYPE (rhs2_type))))
            || !useless_type_conversion_p (lhs_type, rhs1_type))
          {
            error ("type mismatch in shift expression");
@@ -4268,6 +4256,15 @@ gimple_verify_flow_info (void)
              err = 1;
            }
 
+         if (prev_stmt && EH_LANDING_PAD_NR (label) != 0)
+           {
+             error ("EH landing pad label ");
+             print_generic_expr (stderr, label, 0);
+             fprintf (stderr, " is not first in a sequence of labels in bb %d",
+                      bb->index);
+             err = 1;
+           }
+
          if (label_to_block (label) != bb)
            {
              error ("label ");
@@ -4918,31 +4915,6 @@ gimple_duplicate_bb (basic_block bb)
   return new_bb;
 }
 
-/* Add phi arguments to the phi nodes in E_COPY->dest according to
-   the phi arguments coming from the equivalent edge at
-   the phi nodes of DEST.  */
-
-static void
-add_phi_args_after_redirect (edge e_copy, edge orig_e)
-{
-   gimple_stmt_iterator psi, psi_copy;
-   gimple phi, phi_copy;
-   tree def;
-
-    for (psi = gsi_start_phis (orig_e->dest),
-       psi_copy = gsi_start_phis (e_copy->dest);
-       !gsi_end_p (psi);
-       gsi_next (&psi), gsi_next (&psi_copy))
-    {
-
-      phi = gsi_stmt (psi);
-      phi_copy = gsi_stmt (psi_copy);
-      def = PHI_ARG_DEF_FROM_EDGE (phi, orig_e);
-      add_phi_arg (phi_copy, def, e_copy,
-                   gimple_phi_arg_location_from_edge (phi, orig_e));
-    }
-}
-
 /* Adds phi node arguments for edge E_COPY after basic block duplication.  */
 
 static void
@@ -5226,12 +5198,13 @@ gimple_duplicate_sese_tail (edge entry ATTRIBUTE_UNUSED, edge exit ATTRIBUTE_UNU
   edge exits[2], nexits[2], e;
   gimple_stmt_iterator gsi,gsi1;
   gimple cond_stmt;
-  edge sorig, snew, orig_e;
+  edge sorig, snew;
   basic_block exit_bb;
-  edge_iterator ei;
-  VEC (edge, heap) *redirect_edges;
-  basic_block iters_bb, orig_src;
+  basic_block iters_bb;
   tree new_rhs;
+  gimple_stmt_iterator psi;
+  gimple phi;
+  tree def;
 
   gcc_assert (EDGE_COUNT (exit->src->succs) == 2);
   exits[0] = exit;
@@ -5240,17 +5213,6 @@ gimple_duplicate_sese_tail (edge entry ATTRIBUTE_UNUSED, edge exit ATTRIBUTE_UNU
   if (!can_copy_bbs_p (region, n_region))
     return false;
 
-  /* Some sanity checking.  Note that we do not check for all possible
-     missuses of the functions.  I.e. if you ask to copy something weird
-     (e.g., in the example, if there is a jump from inside to the middle
-     of some_code, or come_code defines some of the values used in cond)
-     it will work, but the resulting code will not be correct.  */
-  for (i = 0; i < n_region; i++)
-    {
-      if (region[i] == orig_loop->latch)
-       return false;
-    }
-
   initialize_original_copy_tables ();
   set_loop_copy (orig_loop, loop);
   duplicate_subloops (orig_loop, loop);
@@ -5368,72 +5330,30 @@ gimple_duplicate_sese_tail (edge entry ATTRIBUTE_UNUSED, edge exit ATTRIBUTE_UNU
   e = redirect_edge_and_branch (exits[0], exits[1]->dest);
   PENDING_STMT (e) = NULL;
 
-  /* If the block consisting of the exit condition has the latch as
-     successor, then the body of the loop is executed before
-     the exit condition is tested.
-
-     { body  }
-     { cond  } (exit[0])  -> { latch }
-        |
-       V (exit[1])
-
-     { exit_bb }
-
-
-     In such case, the equivalent copied edge nexits[1]
-     (for the peeled iteration) needs to be redirected to exit_bb.
-
-     Otherwise,
-
-     { cond  } (exit[0])  -> { body }
-        |
-       V (exit[1])
-
-     { exit_bb }
-
-
-     exit[0] is pointing to the body of the loop,
-     and the equivalent nexits[0] needs to be redirected to
-     the copied body (of the peeled iteration).  */
-
-  if (exits[1]->dest == orig_loop->latch)
-    e = redirect_edge_and_branch (nexits[1], nexits[0]->dest);
-  else
-    e = redirect_edge_and_branch (nexits[0], nexits[1]->dest);
-  PENDING_STMT (e) = NULL;
-
-  redirect_edges = VEC_alloc (edge, heap, 10);
-
+  /* The latch of ORIG_LOOP was copied, and so was the backedge 
+     to the original header.  We redirect this backedge to EXIT_BB.  */
   for (i = 0; i < n_region; i++)
-    region_copy[i]->flags |= BB_DUPLICATED;
-
-  /* Iterate all incoming edges to latch.  All those coming from
-     copied bbs will be redirected to exit_bb.  */
-  FOR_EACH_EDGE (e, ei, orig_loop->latch->preds)
-    {
-      if (e->src->flags & BB_DUPLICATED)
-        VEC_safe_push (edge, heap, redirect_edges, e);
-    }
-
-  for (i = 0; i < n_region; i++)
-    region_copy[i]->flags &= ~BB_DUPLICATED;
-
-  for (i = 0; VEC_iterate (edge, redirect_edges, i, e); ++i)
-    {
-      e = redirect_edge_and_branch (e, exit_bb);
-      PENDING_STMT (e) = NULL;
-      orig_src = get_bb_original (e->src);
-      orig_e = find_edge (orig_src, orig_loop->latch);
-      add_phi_args_after_redirect (e, orig_e);
-    }
-
-  VEC_free (edge, heap, redirect_edges);
-
+    if (get_bb_original (region_copy[i]) == orig_loop->latch)
+      {
+       gcc_assert (single_succ_edge (region_copy[i]));
+       e = redirect_edge_and_branch (single_succ_edge (region_copy[i]), exit_bb);
+       PENDING_STMT (e) = NULL;
+       for (psi = gsi_start_phis (exit_bb);
+            !gsi_end_p (psi);
+            gsi_next (&psi))
+         {
+           phi = gsi_stmt (psi);
+           def = PHI_ARG_DEF (phi, nexits[0]->dest_idx);
+           add_phi_arg (phi, def, e, gimple_phi_arg_location_from_edge (phi, e));
+         }
+      }
+  e = redirect_edge_and_branch (nexits[0], nexits[1]->dest);
+  PENDING_STMT (e) = NULL;
+  
   /* Anything that is outside of the region, but was dominated by something
      inside needs to update dominance info.  */
   iterate_fix_dominators (CDI_DOMINATORS, doms, false);
   VEC_free (basic_block, heap, doms);
-
   /* Update the SSA web.  */
   update_ssa (TODO_update_ssa);
 
@@ -6928,7 +6848,7 @@ gimple_execute_on_growing_pred (edge e)
 {
   basic_block bb = e->dest;
 
-  if (phi_nodes (bb))
+  if (!gimple_seq_empty_p (phi_nodes (bb)))
     reserve_phi_args_for_new_edge (bb);
 }
 
@@ -6938,7 +6858,7 @@ gimple_execute_on_growing_pred (edge e)
 static void
 gimple_execute_on_shrinking_pred (edge e)
 {
-  if (phi_nodes (e->dest))
+  if (!gimple_seq_empty_p (phi_nodes (e->dest)))
     remove_phi_args (e);
 }