OSDN Git Service

PR middle-end/52419
[pf3gnuchains/gcc-fork.git] / gcc / tree-into-ssa.c
index 031e50e..6ca52c1 100644 (file)
@@ -1,5 +1,5 @@
 /* Rewrite a program in Normal form into SSA.
-   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
+   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
    Contributed by Diego Novillo <dnovillo@redhat.com>
 
@@ -25,27 +25,23 @@ along with GCC; see the file COPYING3.  If not see
 #include "tm.h"
 #include "tree.h"
 #include "flags.h"
-#include "rtl.h"
 #include "tm_p.h"
 #include "langhooks.h"
-#include "hard-reg-set.h"
 #include "basic-block.h"
 #include "output.h"
-#include "expr.h"
 #include "function.h"
-#include "diagnostic.h"
+#include "tree-pretty-print.h"
+#include "gimple-pretty-print.h"
 #include "bitmap.h"
 #include "tree-flow.h"
 #include "gimple.h"
 #include "tree-inline.h"
-#include "varray.h"
 #include "timevar.h"
 #include "hashtab.h"
 #include "tree-dump.h"
 #include "tree-pass.h"
 #include "cfgloop.h"
 #include "domwalk.h"
-#include "ggc.h"
 #include "params.h"
 #include "vecprim.h"
 
@@ -456,9 +452,8 @@ static void
 mark_block_for_update (basic_block bb)
 {
   gcc_assert (blocks_to_update != NULL);
-  if (bitmap_bit_p (blocks_to_update, bb->index))
+  if (!bitmap_set_bit (blocks_to_update, bb->index))
     return;
-  bitmap_set_bit (blocks_to_update, bb->index);
   initialize_flags_in_bb (bb);
 }
 
@@ -561,7 +556,7 @@ set_livein_block (tree var, basic_block bb)
 
 /* Return true if symbol SYM is marked for renaming.  */
 
-static inline bool
+bool
 symbol_marked_for_renaming (tree sym)
 {
   return bitmap_bit_p (SYMS_TO_RENAME (cfun), DECL_UID (sym));
@@ -750,7 +745,17 @@ mark_def_sites (basic_block bb, gimple stmt, bitmap kills)
   set_rewrite_uses (stmt, false);
 
   if (is_gimple_debug (stmt))
-    return;
+    {
+      FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
+       {
+         tree sym = USE_FROM_PTR (use_p);
+         gcc_assert (DECL_P (sym));
+         set_rewrite_uses (stmt, true);
+       }
+      if (rewrite_uses_p (stmt))
+       SET_BIT (interesting_blocks, bb->index);
+      return;
+    }
 
   /* If a variable is used before being set, then the variable is live
      across a block boundary, so mark it live-on-entry to BB.  */
@@ -762,7 +767,7 @@ mark_def_sites (basic_block bb, gimple stmt, bitmap kills)
        set_livein_block (sym, bb);
       set_rewrite_uses (stmt, true);
     }
-  
+
   /* Now process the defs.  Mark BB as the definition block and add
      each def to the set of killed symbols.  */
   FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF)
@@ -866,7 +871,7 @@ prune_unused_phi_nodes (bitmap phis, bitmap kills, bitmap uses)
      then for each of them find the nearest def that dominates them.  If this
      def is a phi node, we mark it live, and if it was not live before, we
      add the predecessors of its basic block to the worklist.
-   
+
      To quickly locate the nearest def that dominates use, we use dfs numbering
      of the dominance tree (that is already available in order to speed up
      queries).  For each def, we have the interval given by the dfs number on
@@ -965,11 +970,10 @@ prune_unused_phi_nodes (bitmap phis, bitmap kills, bitmap uses)
        }
 
       /* If the phi node is already live, there is nothing to do.  */
-      if (bitmap_bit_p (live_phis, p))
+      if (!bitmap_set_bit (live_phis, p))
        continue;
 
-      /* Mark the phi as live, and add the new uses to the worklist.  */
-      bitmap_set_bit (live_phis, p);
+      /* Add the new uses to the worklist.  */
       def_bb = BASIC_BLOCK (p);
       FOR_EACH_EDGE (e, ei, def_bb->preds)
        {
@@ -1121,9 +1125,12 @@ insert_phi_nodes_for (tree var, bitmap phi_insertion_points, bool update_p)
       else
        {
          tree tracked_var;
+
          gcc_assert (DECL_P (var));
          phi = create_phi_node (var, bb);
-         if (!update_p && (tracked_var = target_for_debug_bind (var)))
+
+         tracked_var = target_for_debug_bind (var);
+         if (tracked_var)
            {
              gimple note = gimple_build_debug_bind (tracked_var,
                                                     PHI_RESULT (phi),
@@ -1145,30 +1152,46 @@ insert_phi_nodes_for (tree var, bitmap phi_insertion_points, bool update_p)
    the flowgraph.  */
 
 static void
-insert_phi_nodes (bitmap *dfs)
+insert_phi_nodes (bitmap_head *dfs)
 {
   referenced_var_iterator rvi;
+  bitmap_iterator bi;
   tree var;
+  bitmap vars;
+  unsigned uid;
 
   timevar_push (TV_TREE_INSERT_PHI_NODES);
-  
-  FOR_EACH_REFERENCED_VAR (var, rvi)
+
+  /* Do two stages to avoid code generation differences for UID
+     differences but no UID ordering differences.  */
+
+  vars = BITMAP_ALLOC (NULL);
+  FOR_EACH_REFERENCED_VAR (cfun, var, rvi)
     {
       struct def_blocks_d *def_map;
-      bitmap idf;
 
       def_map = find_def_blocks_for (var);
       if (def_map == NULL)
        continue;
 
       if (get_phi_state (var) != NEED_PHI_STATE_NO)
-       {
-         idf = compute_idf (def_map->def_blocks, dfs);
-         insert_phi_nodes_for (var, idf, false);
-         BITMAP_FREE (idf);
-       }
+       bitmap_set_bit (vars, DECL_UID (var));
     }
 
+  EXECUTE_IF_SET_IN_BITMAP (vars, 0, uid, bi)
+    {
+      tree var = referenced_var (uid);
+      struct def_blocks_d *def_map;
+      bitmap idf;
+
+      def_map = find_def_blocks_for (var);
+      idf = compute_idf (def_map->def_blocks, dfs);
+      insert_phi_nodes_for (var, idf, false);
+      BITMAP_FREE (idf);
+    }
+
+  BITMAP_FREE (vars);
+
   timevar_pop (TV_TREE_INSERT_PHI_NODES);
 }
 
@@ -1180,7 +1203,7 @@ static void
 register_new_def (tree def, tree sym)
 {
   tree currdef;
-   
+
   /* If this variable is set in a single basic block and all uses are
      dominated by the set(s) in that single basic block, then there is
      no reason to record anything for this variable in the block local
@@ -1227,7 +1250,7 @@ register_new_def (tree def, tree sym)
    2- Every statement in BB is rewritten.  USE and VUSE operands are
       rewritten with their corresponding reaching definition.  DEF and
       VDEF targets are registered as new definitions.
-      
+
    3- All the PHI nodes in successor blocks of BB are visited.  The
       argument corresponding to BB is replaced with its current reaching
       definition.
@@ -1247,7 +1270,7 @@ static tree
 get_reaching_def (tree var)
 {
   tree currdef;
-  
+
   /* Lookup the current reaching definition for VAR.  */
   currdef = get_current_def (var);
 
@@ -1266,6 +1289,107 @@ get_reaching_def (tree var)
 }
 
 
+/* Helper function for rewrite_stmt.  Rewrite uses in a debug stmt.  */
+
+static void
+rewrite_debug_stmt_uses (gimple stmt)
+{
+  use_operand_p use_p;
+  ssa_op_iter iter;
+  bool update = false;
+
+  FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
+    {
+      tree var = USE_FROM_PTR (use_p), def = NULL_TREE;
+      gcc_assert (DECL_P (var));
+      if (var_ann (var) == NULL)
+       {
+         if (TREE_CODE (var) == PARM_DECL && single_succ_p (ENTRY_BLOCK_PTR))
+           {
+             gimple_stmt_iterator gsi
+               = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR));
+             int lim;
+             /* Search a few source bind stmts at the start of first bb to
+                see if a DEBUG_EXPR_DECL can't be reused.  */
+             for (lim = 32;
+                  !gsi_end_p (gsi) && lim > 0;
+                  gsi_next (&gsi), lim--)
+               {
+                 gimple gstmt = gsi_stmt (gsi);
+                 if (!gimple_debug_source_bind_p (gstmt))
+                   break;
+                 if (gimple_debug_source_bind_get_value (gstmt) == var)
+                   {
+                     def = gimple_debug_source_bind_get_var (gstmt);
+                     if (TREE_CODE (def) == DEBUG_EXPR_DECL)
+                       break;
+                     else
+                       def = NULL_TREE;
+                   }
+               }
+             /* If not, add a new source bind stmt.  */
+             if (def == NULL_TREE)
+               {
+                 gimple def_temp;
+                 def = make_node (DEBUG_EXPR_DECL);
+                 def_temp = gimple_build_debug_source_bind (def, var, NULL);
+                 DECL_ARTIFICIAL (def) = 1;
+                 TREE_TYPE (def) = TREE_TYPE (var);
+                 DECL_MODE (def) = DECL_MODE (var);
+                 gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR));
+                 gsi_insert_before (&gsi, def_temp, GSI_SAME_STMT);
+               }
+             update = true;
+           }
+       }
+      else
+       {
+         def = get_current_def (var);
+         /* Check if get_current_def can be trusted.  */
+         if (def)
+           {
+             basic_block bb = gimple_bb (stmt);
+             basic_block def_bb
+               = SSA_NAME_IS_DEFAULT_DEF (def)
+                 ? NULL : gimple_bb (SSA_NAME_DEF_STMT (def));
+
+             /* If definition is in current bb, it is fine.  */
+             if (bb == def_bb)
+               ;
+             /* If definition bb doesn't dominate the current bb,
+                it can't be used.  */
+             else if (def_bb && !dominated_by_p (CDI_DOMINATORS, bb, def_bb))
+               def = NULL;
+             /* If there is just one definition and dominates the current
+                bb, it is fine.  */
+             else if (get_phi_state (var) == NEED_PHI_STATE_NO)
+               ;
+             else
+               {
+                 struct def_blocks_d *db_p = get_def_blocks_for (var);
+
+                 /* If there are some non-debug uses in the current bb,
+                    it is fine.  */
+                 if (bitmap_bit_p (db_p->livein_blocks, bb->index))
+                   ;
+                 /* Otherwise give up for now.  */
+                 else
+                   def = NULL;
+               }
+           }
+       }
+      if (def == NULL)
+       {
+         gimple_debug_bind_reset_value (stmt);
+         update_stmt (stmt);
+         return;
+       }
+      SET_USE (use_p, def);
+    }
+  if (update)
+    update_stmt (stmt);
+}
+
 /* SSA Rewriting Step 2.  Rewrite every variable used in each statement in
    the block with its immediate reaching definitions.  Update the current
    definition of a variable when a new real or virtual definition is found.  */
@@ -1293,12 +1417,17 @@ rewrite_stmt (gimple_stmt_iterator si)
 
   /* Step 1.  Rewrite USES in the statement.  */
   if (rewrite_uses_p (stmt))
-    FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
-      {
-       tree var = USE_FROM_PTR (use_p);
-       gcc_assert (DECL_P (var));
-       SET_USE (use_p, get_reaching_def (var));
-      }
+    {
+      if (is_gimple_debug (stmt))
+       rewrite_debug_stmt_uses (stmt);
+      else
+       FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
+         {
+           tree var = USE_FROM_PTR (use_p);
+           gcc_assert (DECL_P (var));
+           SET_USE (use_p, get_reaching_def (var));
+         }
+    }
 
   /* Step 2.  Register the statement's DEF operands.  */
   if (register_defs_p (stmt))
@@ -1436,7 +1565,7 @@ rewrite_leave_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
          saved_def = NULL;
          var = tmp;
        }
-                                                                                
+
       set_current_def (var, saved_def);
     }
 }
@@ -1456,7 +1585,11 @@ dump_decl_set (FILE *file, bitmap set)
 
       EXECUTE_IF_SET_IN_BITMAP (set, 0, i, bi)
        {
-         print_generic_expr (file, referenced_var (i), 0);
+         tree var = referenced_var_lookup (cfun, i);
+         if (var)
+           print_generic_expr (file, var, 0);
+         else
+           fprintf (file, "D.%u", i);
          fprintf (file, " ");
        }
 
@@ -1469,7 +1602,7 @@ dump_decl_set (FILE *file, bitmap set)
 
 /* Dump bitmap SET (assumed to contain VAR_DECLs) to FILE.  */
 
-void
+DEBUG_FUNCTION void
 debug_decl_set (bitmap set)
 {
   dump_decl_set (stderr, set);
@@ -1497,7 +1630,7 @@ dump_defs_stack (FILE *file, int n)
   for (j = (int) VEC_length (tree, block_defs_stack) - 1; j >= 0; j--)
     {
       tree name, var;
-      
+
       name = VEC_index (tree, block_defs_stack, j);
       if (name == NULL_TREE)
        {
@@ -1540,7 +1673,7 @@ dump_defs_stack (FILE *file, int n)
    dumped.  New levels are created when the dominator tree traversal
    used for renaming enters a new sub-tree.  */
 
-void
+DEBUG_FUNCTION void
 debug_defs_stack (int n)
 {
   dump_defs_stack (stderr, n);
@@ -1556,7 +1689,7 @@ dump_currdefs (FILE *file)
   tree var;
 
   fprintf (file, "\n\nCurrent reaching definitions\n\n");
-  FOR_EACH_REFERENCED_VAR (var, i)
+  FOR_EACH_REFERENCED_VAR (cfun, var, i)
     if (SYMS_TO_RENAME (cfun) == NULL
        || bitmap_bit_p (SYMS_TO_RENAME (cfun), DECL_UID (var)))
       {
@@ -1574,7 +1707,7 @@ dump_currdefs (FILE *file)
 
 /* Dump the current reaching definition of every symbol to stderr.  */
 
-void
+DEBUG_FUNCTION void
 debug_currdefs (void)
 {
   dump_currdefs (stderr);
@@ -1600,7 +1733,7 @@ dump_tree_ssa (FILE *file)
 
 /* Dump SSA information to stderr.  */
 
-void
+DEBUG_FUNCTION void
 debug_tree_ssa (void)
 {
   dump_tree_ssa (stderr);
@@ -1646,7 +1779,7 @@ dump_tree_ssa_stats (FILE *file)
 
 /* Dump SSA statistics on stderr.  */
 
-void
+DEBUG_FUNCTION void
 debug_tree_ssa_stats (void)
 {
   dump_tree_ssa_stats (stderr);
@@ -1690,7 +1823,7 @@ debug_def_blocks_r (void **slot, void *data)
 {
   FILE *file = (FILE *) data;
   struct def_blocks_d *db_p = (struct def_blocks_d *) *slot;
-  
+
   fprintf (file, "VAR: ");
   print_generic_expr (file, db_p->var, dump_flags);
   bitmap_print (file, db_p->def_blocks, ", DEF_BLOCKS: { ", "}");
@@ -1714,7 +1847,7 @@ dump_def_blocks (FILE *file)
 
 /* Dump the DEF_BLOCKS hash table on stderr.  */
 
-void
+DEBUG_FUNCTION void
 debug_def_blocks (void)
 {
   dump_def_blocks (stderr);
@@ -1818,7 +1951,8 @@ maybe_replace_use_in_debug_stmt (use_operand_p use_p)
    DEF_P.  */
 
 static inline void
-maybe_register_def (def_operand_p def_p, gimple stmt)
+maybe_register_def (def_operand_p def_p, gimple stmt,
+                   gimple_stmt_iterator gsi)
 {
   tree def = DEF_FROM_PTR (def_p);
   tree sym = DECL_P (def) ? def : SSA_NAME_VAR (def);
@@ -1829,8 +1963,53 @@ maybe_register_def (def_operand_p def_p, gimple stmt)
     {
       if (DECL_P (def))
        {
+         tree tracked_var;
+
          def = make_ssa_name (def, stmt);
          SET_DEF (def_p, def);
+
+         tracked_var = target_for_debug_bind (sym);
+         if (tracked_var)
+           {
+             gimple note = gimple_build_debug_bind (tracked_var, def, stmt);
+             /* If stmt ends the bb, insert the debug stmt on the single
+                non-EH edge from the stmt.  */
+             if (gsi_one_before_end_p (gsi) && stmt_ends_bb_p (stmt))
+               {
+                 basic_block bb = gsi_bb (gsi);
+                 edge_iterator ei;
+                 edge e, ef = NULL;
+                 FOR_EACH_EDGE (e, ei, bb->succs)
+                   if (!(e->flags & EDGE_EH))
+                     {
+                       gcc_assert (!ef);
+                       ef = e;
+                     }
+                 /* If there are other predecessors to ef->dest, then
+                    there must be PHI nodes for the modified
+                    variable, and therefore there will be debug bind
+                    stmts after the PHI nodes.  The debug bind notes
+                    we'd insert would force the creation of a new
+                    block (diverging codegen) and be redundant with
+                    the post-PHI bind stmts, so don't add them.
+
+                    As for the exit edge, there wouldn't be redundant
+                    bind stmts, but there wouldn't be a PC to bind
+                    them to either, so avoid diverging the CFG.  */
+                 if (ef && single_pred_p (ef->dest)
+                     && ef->dest != EXIT_BLOCK_PTR)
+                   {
+                     /* If there were PHI nodes in the node, we'd
+                        have to make sure the value we're binding
+                        doesn't need rewriting.  But there shouldn't
+                        be PHI nodes in a single-predecessor block,
+                        so we just add the note.  */
+                     gsi_insert_on_edge_immediate (ef, note);
+                   }
+               }
+             else
+               gsi_insert_after (&gsi, note, GSI_SAME_STMT);
+           }
        }
 
       register_new_update_single (def, sym);
@@ -1858,7 +2037,7 @@ maybe_register_def (def_operand_p def_p, gimple stmt)
    in OLD_SSA_NAMES.  */
 
 static void
-rewrite_update_stmt (gimple stmt)
+rewrite_update_stmt (gimple stmt, gimple_stmt_iterator gsi)
 {
   use_operand_p use_p;
   def_operand_p def_p;
@@ -1872,7 +2051,6 @@ rewrite_update_stmt (gimple stmt)
     {
       fprintf (dump_file, "Updating SSA information for statement ");
       print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
-      fprintf (dump_file, "\n");
     }
 
   /* Rewrite USES included in OLD_SSA_NAMES and USES whose underlying
@@ -1920,7 +2098,7 @@ rewrite_update_stmt (gimple stmt)
      marked for renaming.  */
   if (register_defs_p (stmt))
     FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, iter, SSA_OP_ALL_DEFS)
-      maybe_register_def (def_p, stmt);
+      maybe_register_def (def_p, stmt, gsi);
 }
 
 
@@ -1943,9 +2121,9 @@ rewrite_update_phi_arguments (basic_block bb)
 
       if (!bitmap_bit_p (blocks_with_phis_to_rewrite, e->dest->index))
        continue;
-     
+
       phis = VEC_index (gimple_vec, phis_to_rewrite, e->dest->index);
-      for (i = 0; VEC_iterate (gimple, phis, i, phi); i++)
+      FOR_EACH_VEC_ELT (gimple, phis, i, phi)
        {
          tree arg, lhs_sym, reaching_def = NULL;
          use_operand_p arg_p;
@@ -1988,9 +2166,9 @@ rewrite_update_phi_arguments (basic_block bb)
              SET_USE (arg_p, reaching_def);
              stmt = SSA_NAME_DEF_STMT (reaching_def);
 
-             /* Single element PHI nodes  behave like copies, so get the 
+             /* Single element PHI nodes  behave like copies, so get the
                 location from the phi argument.  */
-             if (gimple_code (stmt) == GIMPLE_PHI && 
+             if (gimple_code (stmt) == GIMPLE_PHI &&
                  gimple_phi_num_args (stmt) == 1)
                locus = gimple_phi_arg_location (stmt, 0);
              else
@@ -2016,13 +2194,11 @@ static void
 rewrite_update_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
                            basic_block bb)
 {
-  edge e;
-  edge_iterator ei;
   bool is_abnormal_phi;
   gimple_stmt_iterator gsi;
 
   if (dump_file && (dump_flags & TDF_DETAILS))
-    fprintf (dump_file, "\n\nRegistering new PHI nodes in block #%d\n\n",
+    fprintf (dump_file, "Registering new PHI nodes in block #%d\n",
             bb->index);
 
   /* Mark the unwind point for this block.  */
@@ -2033,13 +2209,7 @@ rewrite_update_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
 
   /* Mark the LHS if any of the arguments flows through an abnormal
      edge.  */
-  is_abnormal_phi = false;
-  FOR_EACH_EDGE (e, ei, bb->preds)
-    if (e->flags & EDGE_ABNORMAL)
-      {
-       is_abnormal_phi = true;
-       break;
-      }
+  is_abnormal_phi = bb_has_abnormal_pred (bb);
 
   /* If any of the PHI nodes is a replacement for a name in
      OLD_SSA_NAMES or it's one of the names in NEW_SSA_NAMES, then
@@ -2053,7 +2223,7 @@ rewrite_update_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
 
       if (!register_defs_p (phi))
        continue;
-      
+
       lhs = gimple_phi_result (phi);
       lhs_sym = SSA_NAME_VAR (lhs);
 
@@ -2066,7 +2236,7 @@ rewrite_update_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
             the names replaced by LHS.  */
          if (is_new_name (lhs))
            register_new_update_set (lhs, names_replaced_by (lhs));
-         
+
          /* If LHS is an OLD name, register it as a new definition
             for itself.  */
          if (is_old_name (lhs))
@@ -2079,11 +2249,11 @@ rewrite_update_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
 
   /* Step 2.  Rewrite every variable used in each statement in the block.  */
   if (TEST_BIT (interesting_blocks, bb->index))
-   {
-     gcc_assert (bitmap_bit_p (blocks_to_update, bb->index));
+    {
+      gcc_assert (bitmap_bit_p (blocks_to_update, bb->index));
       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
-        rewrite_update_stmt (gsi_stmt (gsi));
-   }
+        rewrite_update_stmt (gsi_stmt (gsi), gsi);
+    }
 
   /* Step 3.  Update PHI nodes.  */
   rewrite_update_phi_arguments (bb);
@@ -2103,7 +2273,7 @@ rewrite_update_leave_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
     {
       tree var = VEC_pop (tree, block_defs_stack);
       tree saved_def;
-      
+
       /* NULL indicates the unwind stop point for this block (see
         rewrite_update_enter_block).  */
       if (var == NULL)
@@ -2116,7 +2286,7 @@ rewrite_update_leave_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
 
 
 /* Rewrite the actual blocks, statements, and PHI arguments, to be in SSA
-   form.  
+   form.
 
    ENTRY indicates the block where to start.  Every block dominated by
       ENTRY will be rewritten.
@@ -2133,7 +2303,7 @@ static void
 rewrite_blocks (basic_block entry, enum rewrite_mode what)
 {
   struct dom_walk_data walk_data;
-  
+
   /* Rewrite all the basic blocks in the program.  */
   timevar_push (TV_TREE_SSA_REWRITE_BLOCKS);
 
@@ -2174,7 +2344,7 @@ rewrite_blocks (basic_block entry, enum rewrite_mode what)
       if (def_blocks)
        dump_tree_ssa_stats (dump_file);
     }
-  
+
   VEC_free (tree, heap, block_defs_stack);
 
   timevar_pop (TV_TREE_SSA_REWRITE_BLOCKS);
@@ -2258,7 +2428,7 @@ init_ssa_renamer (void)
   def_blocks = htab_create (num_referenced_vars, def_blocks_hash,
                             def_blocks_eq, def_blocks_free);
 
-  FOR_EACH_REFERENCED_VAR(var, rvi)
+  FOR_EACH_REFERENCED_VAR (cfun, var, rvi)
     set_current_def (var, NULL_TREE);
 }
 
@@ -2297,10 +2467,8 @@ fini_ssa_renamer (void)
 static unsigned int
 rewrite_into_ssa (void)
 {
-  bitmap *dfs;
+  bitmap_head *dfs;
   basic_block bb;
-  
-  timevar_push (TV_TREE_SSA_OTHER);
 
   /* Initialize operand data structures.  */
   init_ssa_operands ();
@@ -2315,9 +2483,9 @@ rewrite_into_ssa (void)
   sbitmap_zero (interesting_blocks);
 
   /* Initialize dominance frontier.  */
-  dfs = XNEWVEC (bitmap, last_basic_block);
+  dfs = XNEWVEC (bitmap_head, last_basic_block);
   FOR_EACH_BB (bb)
-    dfs[bb->index] = BITMAP_ALLOC (NULL);
+    bitmap_initialize (&dfs[bb->index], &bitmap_default_obstack);
 
   /* 1- Compute dominance frontiers.  */
   calculate_dominance_info (CDI_DOMINATORS);
@@ -2334,19 +2502,18 @@ rewrite_into_ssa (void)
 
   /* Free allocated memory.  */
   FOR_EACH_BB (bb)
-    BITMAP_FREE (dfs[bb->index]);
+    bitmap_clear (&dfs[bb->index]);
   free (dfs);
 
   sbitmap_free (interesting_blocks);
 
   fini_ssa_renamer ();
 
-  timevar_pop (TV_TREE_SSA_OTHER);
   return 0;
 }
 
 
-struct gimple_opt_pass pass_build_ssa = 
+struct gimple_opt_pass pass_build_ssa =
 {
  {
   GIMPLE_PASS,
@@ -2356,13 +2523,12 @@ struct gimple_opt_pass pass_build_ssa =
   NULL,                                        /* sub */
   NULL,                                        /* next */
   0,                                   /* static_pass_number */
-  TV_NONE,                             /* tv_id */
+  TV_TREE_SSA_OTHER,                   /* tv_id */
   PROP_cfg | PROP_referenced_vars,     /* properties_required */
   PROP_ssa,                            /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
-  TODO_dump_func
-    | TODO_update_ssa_only_virtuals
+  TODO_update_ssa_only_virtuals
     | TODO_verify_ssa
     | TODO_remove_unused_locals                /* todo_flags_finish */
  }
@@ -2492,7 +2658,7 @@ prepare_block_for_update (basic_block bb, bool insert_phi_p)
       ssa_op_iter i;
       use_operand_p use_p;
       def_operand_p def_p;
-      
+
       stmt = gsi_stmt (si);
 
       FOR_EACH_SSA_USE_OPERAND (use_p, stmt, i, SSA_OP_ALL_USES)
@@ -2637,7 +2803,7 @@ dump_names_replaced_by (FILE *file, tree name)
 
 /* Dump all the names replaced by NAME to stderr.  */
 
-void
+DEBUG_FUNCTION void
 debug_names_replaced_by (tree name)
 {
   dump_names_replaced_by (stderr, name);
@@ -2681,28 +2847,27 @@ dump_update_ssa (FILE *file)
 
   if (!bitmap_empty_p (SYMS_TO_RENAME (cfun)))
     {
-      fprintf (file, "\n\nSymbols to be put in SSA form\n\n");
+      fprintf (file, "\nSymbols to be put in SSA form\n");
       dump_decl_set (file, SYMS_TO_RENAME (cfun));
       fprintf (file, "\n");
     }
 
   if (names_to_release && !bitmap_empty_p (names_to_release))
     {
-      fprintf (file, "\n\nSSA names to release after updating the SSA web\n\n");
+      fprintf (file, "\nSSA names to release after updating the SSA web\n\n");
       EXECUTE_IF_SET_IN_BITMAP (names_to_release, 0, i, bi)
        {
          print_generic_expr (file, ssa_name (i), 0);
          fprintf (file, " ");
        }
+      fprintf (file, "\n");
     }
-
-  fprintf (file, "\n\n");
 }
 
 
 /* Dump SSA update information to stderr.  */
 
-void
+DEBUG_FUNCTION void
 debug_update_ssa (void)
 {
   dump_update_ssa (stderr);
@@ -2791,17 +2956,10 @@ create_new_def_for (tree old_name, gimple stmt, def_operand_p def)
 
   if (gimple_code (stmt) == GIMPLE_PHI)
     {
-      edge e;
-      edge_iterator ei;
       basic_block bb = gimple_bb (stmt);
 
       /* If needed, mark NEW_NAME as occurring in an abnormal PHI node. */
-      FOR_EACH_EDGE (e, ei, bb->preds)
-       if (e->flags & EDGE_ABNORMAL)
-         {
-           SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new_name) = 1;
-           break;
-         }
+      SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new_name) = bb_has_abnormal_pred (bb);
     }
 
   register_new_name_mapping (new_name, old_name);
@@ -2903,7 +3061,7 @@ ssa_names_to_replace (void)
   unsigned i = 0;
   bitmap ret;
   sbitmap_iterator sbi;
-  
+
   gcc_assert (update_ssa_initialized_fn == NULL
              || update_ssa_initialized_fn == cfun);
 
@@ -2935,7 +3093,7 @@ release_ssa_name_after_update_ssa (tree name)
    This is slightly different than the regular PHI insertion
    algorithm.  The value of UPDATE_FLAGS controls how PHI nodes for
    real names (i.e., GIMPLE registers) are inserted:
+
    - If UPDATE_FLAGS == TODO_update_ssa, we are only interested in PHI
      nodes inside the region affected by the block that defines VAR
      and the blocks that define all its replacements.  All these
@@ -2953,7 +3111,7 @@ release_ssa_name_after_update_ssa (tree name)
      names is not pruned.  PHI nodes are inserted at every IDF block.  */
 
 static void
-insert_updated_phi_nodes_for (tree var, bitmap *dfs, bitmap blocks,
+insert_updated_phi_nodes_for (tree var, bitmap_head *dfs, bitmap blocks,
                               unsigned update_flags)
 {
   basic_block entry;
@@ -2962,12 +3120,10 @@ insert_updated_phi_nodes_for (tree var, bitmap *dfs, bitmap blocks,
   bitmap_iterator bi;
   unsigned i;
 
-#if defined ENABLE_CHECKING
   if (TREE_CODE (var) == SSA_NAME)
-    gcc_assert (is_old_name (var));
+    gcc_checking_assert (is_old_name (var));
   else
-    gcc_assert (symbol_marked_for_renaming (var));
-#endif
+    gcc_checking_assert (symbol_marked_for_renaming (var));
 
   /* Get all the definition sites for VAR.  */
   db = find_def_blocks_for (var);
@@ -3184,6 +3340,9 @@ update_ssa (unsigned update_flags)
 
   timevar_push (TV_TREE_SSA_INCREMENTAL);
 
+  if (dump_file && (dump_flags & TDF_DETAILS))
+    fprintf (dump_file, "\nUpdating SSA:\n");
+
   if (!update_ssa_initialized_fn)
     init_update_ssa (cfun);
   gcc_assert (update_ssa_initialized_fn == cfun);
@@ -3280,13 +3439,13 @@ update_ssa (unsigned update_flags)
      and for symbols in SYMS_TO_RENAME.  */
   if (insert_phi_p)
     {
-      bitmap *dfs;
+      bitmap_head *dfs;
 
       /* If the caller requested PHI nodes to be added, compute
         dominance frontiers.  */
-      dfs = XNEWVEC (bitmap, last_basic_block);
+      dfs = XNEWVEC (bitmap_head, last_basic_block);
       FOR_EACH_BB (bb)
-       dfs[bb->index] = BITMAP_ALLOC (NULL);
+       bitmap_initialize (&dfs[bb->index], &bitmap_default_obstack);
       compute_dominance_frontiers (dfs);
 
       if (sbitmap_first_set_bit (old_ssa_names) >= 0)
@@ -3311,7 +3470,7 @@ update_ssa (unsigned update_flags)
                                      update_flags);
 
       FOR_EACH_BB (bb)
-       BITMAP_FREE (dfs[bb->index]);
+       bitmap_clear (&dfs[bb->index]);
       free (dfs);
 
       /* Insertion of PHI nodes may have added blocks to the region.
@@ -3348,21 +3507,21 @@ update_ssa (unsigned update_flags)
 
       dump_update_ssa (dump_file);
 
-      fprintf (dump_file, "Incremental SSA update started at block: %d\n\n",
+      fprintf (dump_file, "Incremental SSA update started at block: %d\n",
               start_bb->index);
 
       c = 0;
       EXECUTE_IF_SET_IN_BITMAP (blocks_to_update, 0, i, bi)
        c++;
       fprintf (dump_file, "Number of blocks in CFG: %d\n", last_basic_block);
-      fprintf (dump_file, "Number of blocks to update: %d (%3.0f%%)\n\n",
+      fprintf (dump_file, "Number of blocks to update: %d (%3.0f%%)\n",
               c, PERCENT (c, last_basic_block));
 
       if (dump_flags & TDF_DETAILS)
        {
-         fprintf (dump_file, "Affected blocks: ");
+         fprintf (dump_file, "Affected blocks:");
          EXECUTE_IF_SET_IN_BITMAP (blocks_to_update, 0, i, bi)
-           fprintf (dump_file, "%u ", i);
+           fprintf (dump_file, " %u", i);
          fprintf (dump_file, "\n");
        }