]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/tree-into-ssa.c
Update copyright years.
[thirdparty/gcc.git] / gcc / tree-into-ssa.c
index 9fd698dd63f02e63a23f80da81344b0e84a9cb92..ef99060403039082435c0a6fc6d8922e3b375237 100644 (file)
@@ -1,5 +1,5 @@
 /* Rewrite a program in Normal form into SSA.
-   Copyright (C) 2001-2015 Free Software Foundation, Inc.
+   Copyright (C) 2001-2021 Free Software Foundation, Inc.
    Contributed by Diego Novillo <dnovillo@redhat.com>
 
 This file is part of GCC.
@@ -22,38 +22,26 @@ along with GCC; see the file COPYING3.  If not see
 #include "system.h"
 #include "coretypes.h"
 #include "backend.h"
+#include "rtl.h"
 #include "tree.h"
 #include "gimple.h"
-#include "rtl.h"
+#include "tree-pass.h"
 #include "ssa.h"
-#include "alias.h"
-#include "fold-const.h"
-#include "flags.h"
-#include "tm_p.h"
+#include "gimple-pretty-print.h"
+#include "diagnostic-core.h"
 #include "langhooks.h"
 #include "cfganal.h"
-#include "gimple-pretty-print.h"
-#include "internal-fn.h"
 #include "gimple-iterator.h"
 #include "tree-cfg.h"
 #include "tree-into-ssa.h"
-#include "insn-config.h"
-#include "expmed.h"
-#include "dojump.h"
-#include "explow.h"
-#include "calls.h"
-#include "emit-rtl.h"
-#include "varasm.h"
-#include "stmt.h"
-#include "expr.h"
 #include "tree-dfa.h"
 #include "tree-ssa.h"
-#include "tree-inline.h"
-#include "tree-pass.h"
-#include "cfgloop.h"
 #include "domwalk.h"
-#include "params.h"
-#include "diagnostic-core.h"
+#include "statistics.h"
+#include "stringpool.h"
+#include "attribs.h"
+#include "asan.h"
+#include "attr-fnspec.h"
 
 #define PERCENT(x,y) ((float)(x) * 100.0 / (float)(y))
 
@@ -111,7 +99,7 @@ static sbitmap interesting_blocks;
 /* Set of SSA names that have been marked to be released after they
    were registered in the replacement table.  They will be finally
    released after we finish updating the SSA web.  */
-static bitmap names_to_release;
+bitmap names_to_release;
 
 /* vec of vec of PHIs to rewrite in a basic block.  Element I corresponds
    the to basic block with index I.  Allocated once per compilation, *not*
@@ -336,7 +324,7 @@ get_ssa_name_ann (tree name)
 
   /* Re-allocate the vector at most once per update/into-SSA.  */
   if (ver >= len)
-    info_for_ssa_name.safe_grow_cleared (num_ssa_names);
+    info_for_ssa_name.safe_grow_cleared (num_ssa_names, true);
 
   /* But allocate infos lazily.  */
   info = info_for_ssa_name[ver];
@@ -683,6 +671,8 @@ mark_def_sites (basic_block bb, gimple *stmt, bitmap kills)
   FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_ALL_USES)
     {
       tree sym = USE_FROM_PTR (use_p);
+      if (TREE_CODE (sym) == SSA_NAME)
+       continue;
       gcc_checking_assert (DECL_P (sym));
       if (!bitmap_bit_p (kills, DECL_UID (sym)))
        set_livein_block (sym, bb);
@@ -693,6 +683,8 @@ mark_def_sites (basic_block bb, gimple *stmt, bitmap kills)
      each def to the set of killed symbols.  */
   FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS)
     {
+      if (TREE_CODE (def) == SSA_NAME)
+       continue;
       gcc_checking_assert (DECL_P (def));
       set_def_block (def, bb, false);
       bitmap_set_bit (kills, DECL_UID (def));
@@ -949,14 +941,18 @@ mark_phi_for_rewrite (basic_block bb, gphi *phi)
   if (!blocks_with_phis_to_rewrite)
     return;
 
-  bitmap_set_bit (blocks_with_phis_to_rewrite, idx);
-
-  n = (unsigned) last_basic_block_for_fn (cfun) + 1;
-  if (phis_to_rewrite.length () < n)
-    phis_to_rewrite.safe_grow_cleared (n);
+  if (bitmap_set_bit (blocks_with_phis_to_rewrite, idx))
+    {
+      n = (unsigned) last_basic_block_for_fn (cfun) + 1;
+      if (phis_to_rewrite.length () < n)
+       phis_to_rewrite.safe_grow_cleared (n, true);
 
-  phis = phis_to_rewrite[idx];
-  phis.reserve (10);
+      phis = phis_to_rewrite[idx];
+      gcc_assert (!phis.exists ());
+      phis.create (10);
+    }
+  else
+    phis = phis_to_rewrite[idx];
 
   phis.safe_push (phi);
   phis_to_rewrite[idx] = phis;
@@ -1077,6 +1073,59 @@ insert_phi_nodes (bitmap_head *dfs)
 
   timevar_push (TV_TREE_INSERT_PHI_NODES);
 
+  /* When the gimplifier introduces SSA names it cannot easily avoid
+     situations where abnormal edges added by CFG construction break
+     the use-def dominance requirement.  For this case rewrite SSA
+     names with broken use-def dominance out-of-SSA and register them
+     for PHI insertion.  We only need to do this if abnormal edges
+     can appear in the function.  */
+  tree name;
+  if (cfun->calls_setjmp
+      || cfun->has_nonlocal_label)
+    FOR_EACH_SSA_NAME (i, name, cfun)
+      {
+       gimple *def_stmt = SSA_NAME_DEF_STMT (name);
+       if (SSA_NAME_IS_DEFAULT_DEF (name))
+         continue;
+
+       basic_block def_bb = gimple_bb (def_stmt);
+       imm_use_iterator it;
+       gimple *use_stmt;
+       bool need_phis = false;
+       FOR_EACH_IMM_USE_STMT (use_stmt, it, name)
+         {
+           basic_block use_bb = gimple_bb (use_stmt);
+           if (use_bb != def_bb
+               && ! dominated_by_p (CDI_DOMINATORS, use_bb, def_bb))
+             need_phis = true;
+         }
+       if (need_phis)
+         {
+           tree var = create_tmp_reg (TREE_TYPE (name));
+           use_operand_p use_p;
+           FOR_EACH_IMM_USE_STMT (use_stmt, it, name)
+             {
+               basic_block use_bb = gimple_bb (use_stmt);
+               FOR_EACH_IMM_USE_ON_STMT (use_p, it)
+                   SET_USE (use_p, var);
+               update_stmt (use_stmt);
+               set_livein_block (var, use_bb);
+               set_rewrite_uses (use_stmt, true);
+               bitmap_set_bit (interesting_blocks, use_bb->index);
+             }
+           def_operand_p def_p;
+           ssa_op_iter dit;
+           FOR_EACH_SSA_DEF_OPERAND (def_p, def_stmt, dit, SSA_OP_DEF)
+             if (DEF_FROM_PTR (def_p) == name)
+               SET_DEF (def_p, var);
+           update_stmt (def_stmt);
+           set_def_block (var, def_bb, false);
+           set_register_defs (def_stmt, true);
+           bitmap_set_bit (interesting_blocks, def_bb->index);
+           release_ssa_name (name);
+         }
+      }
+
   auto_vec<var_info *> vars (var_infos->elements ());
   FOR_EACH_HASH_TABLE_ELEMENT (*var_infos, info, var_info_p, hi)
     if (info->info.need_phi_state != NEED_PHI_STATE_NO)
@@ -1182,6 +1231,8 @@ get_reaching_def (tree var)
   if (currdef == NULL_TREE)
     {
       tree sym = DECL_P (var) ? var : SSA_NAME_VAR (var);
+      if (! sym)
+       sym = create_tmp_reg (TREE_TYPE (var));
       currdef = get_or_create_ssa_default_def (cfun, sym);
     }
 
@@ -1241,7 +1292,7 @@ rewrite_debug_stmt_uses (gimple *stmt)
                  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);
+                 SET_DECL_MODE (def, DECL_MODE (var));
                  gsi =
                 gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
                  gsi_insert_before (&gsi, def_temp, GSI_SAME_STMT);
@@ -1327,6 +1378,8 @@ rewrite_stmt (gimple_stmt_iterator *si)
        FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_ALL_USES)
          {
            tree var = USE_FROM_PTR (use_p);
+           if (TREE_CODE (var) == SSA_NAME)
+             continue;
            gcc_checking_assert (DECL_P (var));
            SET_USE (use_p, get_reaching_def (var));
          }
@@ -1340,6 +1393,8 @@ rewrite_stmt (gimple_stmt_iterator *si)
        tree name;
        tree tracked_var;
 
+       if (TREE_CODE (var) == SSA_NAME)
+         continue;
        gcc_checking_assert (DECL_P (var));
 
        if (gimple_clobber_p (stmt)
@@ -1347,8 +1402,7 @@ rewrite_stmt (gimple_stmt_iterator *si)
          {
            /* If we rewrite a DECL into SSA form then drop its
               clobber stmts and replace uses with a new default def.  */
-           gcc_checking_assert (TREE_CODE (var) == VAR_DECL
-                                && !gimple_vdef (stmt));
+           gcc_checking_assert (VAR_P (var) && !gimple_vdef (stmt));
            gsi_replace (si, gimple_build_nop (), true);
            register_new_def (get_or_create_ssa_default_def (cfun, var), var);
            break;
@@ -1358,6 +1412,10 @@ rewrite_stmt (gimple_stmt_iterator *si)
        SET_DEF (def_p, name);
        register_new_def (DEF_FROM_PTR (def_p), var);
 
+       /* Do not insert debug stmts if the stmt ends the BB.  */
+       if (stmt_ends_bb_p (stmt))
+         continue;
+       
        tracked_var = target_for_debug_bind (var);
        if (tracked_var)
          {
@@ -1406,9 +1464,10 @@ rewrite_add_phi_arguments (basic_block bb)
 class rewrite_dom_walker : public dom_walker
 {
 public:
-  rewrite_dom_walker (cdi_direction direction) : dom_walker (direction) {}
+  rewrite_dom_walker (cdi_direction direction)
+    : dom_walker (direction, ALL_BLOCKS, NULL) {}
 
-  virtual void before_dom_children (basic_block);
+  virtual edge before_dom_children (basic_block);
   virtual void after_dom_children (basic_block);
 };
 
@@ -1417,7 +1476,7 @@ public:
    (BLOCK_DEFS).  Register new definitions for every PHI node in the
    block.  */
 
-void
+edge
 rewrite_dom_walker::before_dom_children (basic_block bb)
 {
   if (dump_file && (dump_flags & TDF_DETAILS))
@@ -1449,6 +1508,8 @@ rewrite_dom_walker::before_dom_children (basic_block bb)
      reaching definition for the variable and the edge through which that
      definition is reaching the PHI node.  */
   rewrite_add_phi_arguments (bb);
+
+  return NULL;
 }
 
 
@@ -1553,10 +1614,10 @@ dump_defs_stack (FILE *file, int n)
        }
 
       fprintf (file, "    Previous CURRDEF (");
-      print_generic_expr (file, var, 0);
+      print_generic_expr (file, var);
       fprintf (file, ") = ");
       if (name)
-       print_generic_expr (file, name, 0);
+       print_generic_expr (file, name);
       else
        fprintf (file, "<NIL>");
       fprintf (file, "\n");
@@ -1592,10 +1653,10 @@ dump_currdefs (FILE *file)
     {
       common_info *info = get_common_info (var);
       fprintf (file, "CURRDEF (");
-      print_generic_expr (file, var, 0);
+      print_generic_expr (file, var);
       fprintf (file, ") = ");
       if (info->current_def)
-       print_generic_expr (file, info->current_def, 0);
+       print_generic_expr (file, info->current_def);
       else
        fprintf (file, "<NIL>");
       fprintf (file, "\n");
@@ -1806,6 +1867,26 @@ maybe_replace_use_in_debug_stmt (use_operand_p use_p)
 }
 
 
+/* If DEF has x_5 = ASAN_POISON () as its current def, add
+   ASAN_POISON_USE (x_5) stmt before GSI to denote the stmt writes into
+   a poisoned (out of scope) variable.  */
+
+static void
+maybe_add_asan_poison_write (tree def, gimple_stmt_iterator *gsi)
+{
+  tree cdef = get_current_def (def);
+  if (cdef != NULL
+      && TREE_CODE (cdef) == SSA_NAME
+      && gimple_call_internal_p (SSA_NAME_DEF_STMT (cdef), IFN_ASAN_POISON))
+    {
+      gcall *call
+       = gimple_build_call_internal (IFN_ASAN_POISON_USE, 1, cdef);
+      gimple_set_location (call, gimple_location (gsi_stmt (*gsi)));
+      gsi_insert_before (gsi, call, GSI_SAME_STMT);
+    }
+}
+
+
 /* If the operand pointed to by DEF_P is an SSA name in NEW_SSA_NAMES
    or OLD_SSA_NAMES, or if it is a symbol marked for renaming,
    register it as the current definition for the names replaced by
@@ -1827,7 +1908,7 @@ maybe_register_def (def_operand_p def_p, gimple *stmt,
        {
          if (gimple_clobber_p (stmt) && is_gimple_reg (sym))
            {
-             gcc_checking_assert (TREE_CODE (sym) == VAR_DECL);
+             gcc_checking_assert (VAR_P (sym));
              /* Replace clobber stmts with a default def. This new use of a
                 default definition may make it look like SSA_NAMEs have
                 conflicting lifetimes, so we need special code to let them
@@ -1836,7 +1917,11 @@ maybe_register_def (def_operand_p def_p, gimple *stmt,
              def = get_or_create_ssa_default_def (cfun, sym);
            }
          else
-           def = make_ssa_name (def, stmt);
+           {
+             if (asan_sanitize_use_after_scope ())
+               maybe_add_asan_poison_write (def, &gsi);
+             def = make_ssa_name (def, stmt);
+           }
          SET_DEF (def_p, def);
 
          tree tracked_var = target_for_debug_bind (sym);
@@ -2035,7 +2120,7 @@ rewrite_update_phi_arguments (basic_block bb)
           /* Update the argument if there is a reaching def.  */
          if (reaching_def)
            {
-             source_location locus;
+             location_t locus;
              int arg_i = PHI_ARG_INDEX_FROM_USE (arg_p);
 
              SET_USE (arg_p, reaching_def);
@@ -2070,9 +2155,10 @@ rewrite_update_phi_arguments (basic_block bb)
 class rewrite_update_dom_walker : public dom_walker
 {
 public:
-  rewrite_update_dom_walker (cdi_direction direction) : dom_walker (direction) {}
+  rewrite_update_dom_walker (cdi_direction direction)
+    : dom_walker (direction, ALL_BLOCKS, NULL) {}
 
-  virtual void before_dom_children (basic_block);
+  virtual edge before_dom_children (basic_block);
   virtual void after_dom_children (basic_block);
 };
 
@@ -2081,7 +2167,7 @@ public:
    for new SSA names produced in this block (BLOCK_DEFS).  Register
    new definitions for every PHI node in the block.  */
 
-void
+edge
 rewrite_update_dom_walker::before_dom_children (basic_block bb)
 {
   bool is_abnormal_phi;
@@ -2094,7 +2180,7 @@ rewrite_update_dom_walker::before_dom_children (basic_block bb)
   block_defs_stack.safe_push (NULL_TREE);
 
   if (!bitmap_bit_p (blocks_to_update, bb->index))
-    return;
+    return NULL;
 
   /* Mark the LHS if any of the arguments flows through an abnormal
      edge.  */
@@ -2150,6 +2236,8 @@ rewrite_update_dom_walker::before_dom_children (basic_block bb)
 
   /* Step 3.  Update PHI nodes.  */
   rewrite_update_phi_arguments (bb);
+
+  return NULL;
 }
 
 /* Called after visiting block BB.  Unwind BLOCK_DEFS_STACK to restore
@@ -2227,7 +2315,7 @@ public:
   mark_def_dom_walker (cdi_direction direction);
   ~mark_def_dom_walker ();
 
-  virtual void before_dom_children (basic_block);
+  virtual edge before_dom_children (basic_block);
 
 private:
   /* Notice that this bitmap is indexed using variable UIDs, so it must be
@@ -2237,7 +2325,7 @@ private:
 };
 
 mark_def_dom_walker::mark_def_dom_walker (cdi_direction direction)
-  : dom_walker (direction), m_kills (BITMAP_ALLOC (NULL))
+  : dom_walker (direction, ALL_BLOCKS, NULL), m_kills (BITMAP_ALLOC (NULL))
 {
 }
 
@@ -2249,7 +2337,7 @@ mark_def_dom_walker::~mark_def_dom_walker ()
 /* Block processing routine for mark_def_sites.  Clear the KILLS bitmap
    at the start of each block, and call mark_def_sites for each statement.  */
 
-void
+edge
 mark_def_dom_walker::before_dom_children (basic_block bb)
 {
   gimple_stmt_iterator gsi;
@@ -2257,6 +2345,7 @@ mark_def_dom_walker::before_dom_children (basic_block bb)
   bitmap_clear (m_kills);
   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
     mark_def_sites (bb, gsi_stmt (gsi), m_kills);
+  return NULL;
 }
 
 /* Initialize internal data needed during renaming.  */
@@ -2344,7 +2433,11 @@ pass_build_ssa::execute (function *fun)
 {
   bitmap_head *dfs;
   basic_block bb;
-  unsigned i;
+
+  /* Increase the set of variables we can rewrite into SSA form
+     by clearing TREE_ADDRESSABLE and transform the IL to support this.  */
+  if (optimize)
+    execute_update_addresses_taken ();
 
   /* Initialize operand data structures.  */
   init_ssa_operands (fun);
@@ -2388,20 +2481,43 @@ pass_build_ssa::execute (function *fun)
   /* Try to get rid of all gimplifier generated temporaries by making
      its SSA names anonymous.  This way we can garbage collect them
      all after removing unused locals which we do in our TODO.  */
-  for (i = 1; i < num_ssa_names; ++i)
+  unsigned i;
+  tree name;
+
+  FOR_EACH_SSA_NAME (i, name, cfun)
     {
-      tree decl, name = ssa_name (i);
-      if (!name
-         || SSA_NAME_IS_DEFAULT_DEF (name))
+      if (SSA_NAME_IS_DEFAULT_DEF (name))
        continue;
-      decl = SSA_NAME_VAR (name);
+      tree decl = SSA_NAME_VAR (name);
       if (decl
-         && TREE_CODE (decl) == VAR_DECL
+         && VAR_P (decl)
          && !VAR_DECL_IS_VIRTUAL_OPERAND (decl)
          && DECL_IGNORED_P (decl))
        SET_SSA_NAME_VAR_OR_IDENTIFIER (name, DECL_NAME (decl));
     }
 
+  /* Initialize SSA_NAME_POINTS_TO_READONLY_MEMORY.  */
+  tree fnspec_tree
+        = lookup_attribute ("fn spec",
+                            TYPE_ATTRIBUTES (TREE_TYPE (fun->decl)));
+  if (fnspec_tree)
+    {
+      attr_fnspec fnspec (TREE_VALUE (TREE_VALUE (fnspec_tree)));
+      unsigned i = 0;
+      for (tree arg = DECL_ARGUMENTS (cfun->decl);
+          arg; arg = DECL_CHAIN (arg), ++i)
+       {
+         if (!fnspec.arg_specified_p (i))
+          break;
+         if (fnspec.arg_readonly_p (i))
+           {
+             tree name = ssa_default_def (fun, arg);
+             if (name)
+               SSA_NAME_POINTS_TO_READONLY_MEMORY (name) = 1;
+           }
+       }
+    }
+
   return 0;
 }
 
@@ -2481,11 +2597,9 @@ mark_use_interesting (tree var, gimple *stmt, basic_block bb,
     }
 }
 
-
-/* Do a dominator walk starting at BB processing statements that
-   reference symbols in SSA operands.  This is very similar to
-   mark_def_sites, but the scan handles statements whose operands may
-   already be SSA names.
+/* Processing statements in BB that reference symbols in SSA operands.
+   This is very similar to mark_def_sites, but the scan handles
+   statements whose operands may already be SSA names.
 
    If INSERT_PHI_P is true, mark those uses as live in the
    corresponding block.  This is later used by the PHI placement
@@ -2498,9 +2612,8 @@ mark_use_interesting (tree var, gimple *stmt, basic_block bb,
           that.  */
 
 static void
-prepare_block_for_update (basic_block bb, bool insert_phi_p)
+prepare_block_for_update_1 (basic_block bb, bool insert_phi_p)
 {
-  basic_block son;
   edge e;
   edge_iterator ei;
 
@@ -2582,13 +2695,51 @@ prepare_block_for_update (basic_block bb, bool insert_phi_p)
        }
     }
 
-  /* Now visit all the blocks dominated by BB.  */
-  for (son = first_dom_son (CDI_DOMINATORS, bb);
-       son;
-       son = next_dom_son (CDI_DOMINATORS, son))
-    prepare_block_for_update (son, insert_phi_p);
 }
 
+/* Do a dominator walk starting at BB processing statements that
+   reference symbols in SSA operands.  This is very similar to
+   mark_def_sites, but the scan handles statements whose operands may
+   already be SSA names.
+
+   If INSERT_PHI_P is true, mark those uses as live in the
+   corresponding block.  This is later used by the PHI placement
+   algorithm to make PHI pruning decisions.
+
+   FIXME.  Most of this would be unnecessary if we could associate a
+          symbol to all the SSA names that reference it.  But that
+          sounds like it would be expensive to maintain.  Still, it
+          would be interesting to see if it makes better sense to do
+          that.  */
+static void
+prepare_block_for_update (basic_block bb, bool insert_phi_p)
+{
+  size_t sp = 0;
+  basic_block *worklist;
+
+  /* Allocate the worklist.  */
+  worklist = XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun));
+  /* Add the BB to the worklist.  */
+  worklist[sp++] = bb;
+
+  while (sp)
+    {
+      basic_block bb;
+      basic_block son;
+
+      /* Pick a block from the worklist.  */
+      bb = worklist[--sp];
+
+      prepare_block_for_update_1 (bb, insert_phi_p);
+
+      /* Now add all the blocks dominated by BB to the worklist.  */
+      for (son = first_dom_son (CDI_DOMINATORS, bb);
+          son;
+          son = next_dom_son (CDI_DOMINATORS, son))
+       worklist[sp++] = son;
+    }
+  free (worklist);
+}
 
 /* Helper for prepare_names_to_update.  Mark all the use sites for
    NAME as interesting.  BLOCKS and INSERT_PHI_P are as in
@@ -2600,6 +2751,11 @@ prepare_use_sites_for (tree name, bool insert_phi_p)
   use_operand_p use_p;
   imm_use_iterator iter;
 
+  /* If we rename virtual operands do not update them.  */
+  if (virtual_operand_p (name)
+      && cfun->gimple_df->rename_vops)
+    return;
+
   FOR_EACH_IMM_USE_FAST (use_p, iter, name)
     {
       gimple *stmt = USE_STMT (use_p);
@@ -2635,6 +2791,11 @@ prepare_def_site_for (tree name, bool insert_phi_p)
                       || !bitmap_bit_p (names_to_release,
                                         SSA_NAME_VERSION (name)));
 
+  /* If we rename virtual operands do not update them.  */
+  if (virtual_operand_p (name)
+      && cfun->gimple_df->rename_vops)
+    return;
+
   stmt = SSA_NAME_DEF_STMT (name);
   bb = gimple_bb (stmt);
   if (bb)
@@ -2692,13 +2853,13 @@ dump_names_replaced_by (FILE *file, tree name)
   bitmap old_set;
   bitmap_iterator bi;
 
-  print_generic_expr (file, name, 0);
+  print_generic_expr (file, name);
   fprintf (file, " -> { ");
 
   old_set = names_replaced_by (name);
   EXECUTE_IF_SET_IN_BITMAP (old_set, 0, i, bi)
     {
-      print_generic_expr (file, ssa_name (i), 0);
+      print_generic_expr (file, ssa_name (i));
       fprintf (file, " ");
     }
 
@@ -2750,7 +2911,7 @@ dump_update_ssa (FILE *file)
       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);
+         print_generic_expr (file, ssa_name (i));
          fprintf (file, " ");
        }
       fprintf (file, "\n");
@@ -2819,11 +2980,7 @@ delete_update_ssa (void)
 
   if (blocks_with_phis_to_rewrite)
     EXECUTE_IF_SET_IN_BITMAP (blocks_with_phis_to_rewrite, 0, i, bi)
-      {
-       vec<gphi *> phis = phis_to_rewrite[i];
-       phis.release ();
-       phis_to_rewrite[i].create (0);
-      }
+      phis_to_rewrite[i].release ();
 
   BITMAP_FREE (blocks_with_phis_to_rewrite);
   BITMAP_FREE (blocks_to_update);
@@ -3169,44 +3326,45 @@ update_ssa (unsigned update_flags)
   if (!need_ssa_update_p (cfun))
     return;
 
-#ifdef ENABLE_CHECKING
-  timevar_push (TV_TREE_STMT_VERIFY);
+  if (flag_checking)
+    {
+      timevar_push (TV_TREE_STMT_VERIFY);
 
-  bool err = false;
+      bool err = false;
 
-  FOR_EACH_BB_FN (bb, cfun)
-    {
-      gimple_stmt_iterator gsi;
-      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+      FOR_EACH_BB_FN (bb, cfun)
        {
-         gimple *stmt = gsi_stmt (gsi);
-
-         ssa_op_iter i;
-         use_operand_p use_p;
-         FOR_EACH_SSA_USE_OPERAND (use_p, stmt, i, SSA_OP_ALL_USES)
+         gimple_stmt_iterator gsi;
+         for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
            {
-             tree use = USE_FROM_PTR (use_p);
-             if (TREE_CODE (use) != SSA_NAME)
-               continue;
+             gimple *stmt = gsi_stmt (gsi);
 
-             if (SSA_NAME_IN_FREE_LIST (use))
+             ssa_op_iter i;
+             use_operand_p use_p;
+             FOR_EACH_SSA_USE_OPERAND (use_p, stmt, i, SSA_OP_ALL_USES)
                {
-                 error ("statement uses released SSA name:");
-                 debug_gimple_stmt (stmt);
-                 fprintf (stderr, "The use of ");
-                 print_generic_expr (stderr, use, 0);
-                 fprintf (stderr," should have been replaced\n");
-                 err = true;
+                 tree use = USE_FROM_PTR (use_p);
+                 if (TREE_CODE (use) != SSA_NAME)
+                   continue;
+
+                 if (SSA_NAME_IN_FREE_LIST (use))
+                   {
+                     error ("statement uses released SSA name");
+                     debug_gimple_stmt (stmt);
+                     fprintf (stderr, "The use of ");
+                     print_generic_expr (stderr, use);
+                     fprintf (stderr," should have been replaced\n");
+                     err = true;
+                   }
                }
            }
        }
-    }
 
-  if (err)
-    internal_error ("cannot update SSA form");
+      if (err)
+       internal_error ("cannot update SSA form");
 
-  timevar_pop (TV_TREE_STMT_VERIFY);
-#endif
+      timevar_pop (TV_TREE_STMT_VERIFY);
+    }
 
   timevar_push (TV_TREE_SSA_INCREMENTAL);
 
@@ -3241,6 +3399,8 @@ update_ssa (unsigned update_flags)
      OLD_SSA_NAMES.  */
   if (bitmap_first_set_bit (new_ssa_names) >= 0)
     {
+      statistics_counter_event (cfun, "Incremental SSA update", 1);
+
       prepare_names_to_update (insert_phi_p);
 
       /* If all the names in NEW_SSA_NAMES had been marked for
@@ -3254,6 +3414,8 @@ update_ssa (unsigned update_flags)
   /* Next, determine the block at which to start the renaming process.  */
   if (cfun->gimple_df->ssa_renaming_needed)
     {
+      statistics_counter_event (cfun, "Symbol to SSA rewrite", 1);
+
       /* If we rename bare symbols initialize the mapping to
          auxiliar info we need to keep track of.  */
       var_infos = new hash_table<var_info_hasher> (47);
@@ -3271,29 +3433,28 @@ update_ssa (unsigned update_flags)
         placement heuristics.  */
       prepare_block_for_update (start_bb, insert_phi_p);
 
-#ifdef ENABLE_CHECKING
-      for (i = 1; i < num_ssa_names; ++i)
-       {
-         tree name = ssa_name (i);
-         if (!name
-             || virtual_operand_p (name))
-           continue;
+      tree name;
 
-         /* For all but virtual operands, which do not have SSA names
-            with overlapping life ranges, ensure that symbols marked
-            for renaming do not have existing SSA names associated with
-            them as we do not re-write them out-of-SSA before going
-            into SSA for the remaining symbol uses.  */
-         if (marked_for_renaming (SSA_NAME_VAR (name)))
-           {
-             fprintf (stderr, "Existing SSA name for symbol marked for "
-                      "renaming: ");
-             print_generic_expr (stderr, name, TDF_SLIM);
-             fprintf (stderr, "\n");
-             internal_error ("SSA corruption");
-           }
-       }
-#endif
+      if (flag_checking)
+       FOR_EACH_SSA_NAME (i, name, cfun)
+         {
+           if (virtual_operand_p (name))
+             continue;
+
+           /* For all but virtual operands, which do not have SSA names
+              with overlapping life ranges, ensure that symbols marked
+              for renaming do not have existing SSA names associated with
+              them as we do not re-write them out-of-SSA before going
+              into SSA for the remaining symbol uses.  */
+           if (marked_for_renaming (SSA_NAME_VAR (name)))
+             {
+               fprintf (stderr, "Existing SSA name for symbol marked for "
+                        "renaming: ");
+               print_generic_expr (stderr, name, TDF_SLIM);
+               fprintf (stderr, "\n");
+               internal_error ("SSA corruption");
+             }
+         }
     }
   else
     {
@@ -3326,12 +3487,11 @@ update_ssa (unsigned update_flags)
             will grow while we are traversing it (but it will not
             gain any new members).  Copy OLD_SSA_NAMES to a temporary
             for traversal.  */
-         sbitmap tmp = sbitmap_alloc (SBITMAP_SIZE (old_ssa_names));
+         auto_sbitmap tmp (SBITMAP_SIZE (old_ssa_names));
          bitmap_copy (tmp, old_ssa_names);
          EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, sbi)
            insert_updated_phi_nodes_for (ssa_name (i), dfs, blocks_to_update,
                                          update_flags);
-         sbitmap_free (tmp);
        }
 
       symbols_to_rename.qsort (insert_updated_phi_nodes_compare_uids);