OSDN Git Service

Sanitize the behavior of -Wcoverage-mismatch.
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-pre.c
index 684484f..18c75d2 100644 (file)
@@ -1,5 +1,5 @@
 /* SSA-PRE for trees.
-   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
    Contributed by Daniel Berlin <dan@dberlin.org> and Steven Bosscher
    <stevenb@suse.de>
@@ -24,10 +24,11 @@ along with GCC; see the file COPYING3.  If not see
 #include "system.h"
 #include "coretypes.h"
 #include "tm.h"
-#include "ggc.h"
 #include "tree.h"
 #include "basic-block.h"
 #include "diagnostic.h"
+#include "tree-pretty-print.h"
+#include "gimple-pretty-print.h"
 #include "tree-inline.h"
 #include "tree-flow.h"
 #include "gimple.h"
@@ -36,7 +37,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "fibheap.h"
 #include "hashtab.h"
 #include "tree-iterator.h"
-#include "real.h"
 #include "alloc-pool.h"
 #include "obstack.h"
 #include "tree-pass.h"
@@ -1231,49 +1231,11 @@ do_unary:
     case REFERENCE:
       {
        vn_reference_t ref = PRE_EXPR_REFERENCE (e);
-       VEC (vn_reference_op_s, heap) *operands = ref->operands;
-       vn_reference_op_t op;
-
-       /* Try to simplify the translated expression if it is
-          a call to a builtin function with at most two arguments.  */
-       op = VEC_index (vn_reference_op_s, operands, 0);
-       if (op->opcode == CALL_EXPR
-           && TREE_CODE (op->op0) == ADDR_EXPR
-           && TREE_CODE (TREE_OPERAND (op->op0, 0)) == FUNCTION_DECL
-           && DECL_BUILT_IN (TREE_OPERAND (op->op0, 0))
-           && VEC_length (vn_reference_op_s, operands) >= 2
-           && VEC_length (vn_reference_op_s, operands) <= 3)
-         {
-           vn_reference_op_t arg0, arg1 = NULL;
-           bool anyconst = false;
-           arg0 = VEC_index (vn_reference_op_s, operands, 1);
-           if (VEC_length (vn_reference_op_s, operands) > 2)
-             arg1 = VEC_index (vn_reference_op_s, operands, 2);
-           if (TREE_CODE_CLASS (arg0->opcode) == tcc_constant
-               || (arg0->opcode == ADDR_EXPR
-                   && is_gimple_min_invariant (arg0->op0)))
-             anyconst = true;
-           if (arg1
-               && (TREE_CODE_CLASS (arg1->opcode) == tcc_constant
-                   || (arg1->opcode == ADDR_EXPR
-                       && is_gimple_min_invariant (arg1->op0))))
-             anyconst = true;
-           if (anyconst)
-             {
-               tree folded = build_call_expr (TREE_OPERAND (op->op0, 0),
-                                              arg1 ? 2 : 1,
-                                              arg0->op0,
-                                              arg1 ? arg1->op0 : NULL);
-               if (folded
-                   && TREE_CODE (folded) == NOP_EXPR)
-                 folded = TREE_OPERAND (folded, 0);
-               if (folded
-                   && is_gimple_min_invariant (folded))
-                 return get_or_alloc_expr_for_constant (folded);
-             }
-         }
-         return e;
-       }
+       tree folded;
+       if ((folded = fully_constant_vn_reference_p (ref)))
+         return get_or_alloc_expr_for_constant (folded);
+       return e;
+      }
     default:
       return e;
     }
@@ -1445,7 +1407,7 @@ get_representative_for (const pre_expr e)
      that we will return.  */
   if (!pretemp || exprtype != TREE_TYPE (pretemp))
     {
-      pretemp = create_tmp_var (exprtype, "pretmp");
+      pretemp = create_tmp_reg (exprtype, "pretmp");
       get_var_ann (pretemp);
     }
 
@@ -1471,32 +1433,18 @@ get_representative_for (const pre_expr e)
 
 
 
+static pre_expr
+phi_translate (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
+              basic_block pred, basic_block phiblock);
 
 /* Translate EXPR using phis in PHIBLOCK, so that it has the values of
    the phis in PRED.  Return NULL if we can't find a leader for each part
    of the translated expression.  */
 
 static pre_expr
-phi_translate (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
-              basic_block pred, basic_block phiblock)
+phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
+                basic_block pred, basic_block phiblock)
 {
-  pre_expr oldexpr = expr;
-  pre_expr phitrans;
-
-  if (!expr)
-    return NULL;
-
-  /* Constants contain no values that need translation.  */
-  if (expr->kind == CONSTANT)
-    return expr;
-
-  if (value_id_constant_p (get_expr_value_id (expr)))
-    return expr;
-
-  phitrans = phi_trans_lookup (expr, pred);
-  if (phitrans)
-    return phitrans;
-
   switch (expr->kind)
     {
     case NARY:
@@ -1584,7 +1532,6 @@ phi_translate (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
              }
            add_to_value (new_val_id, expr);
          }
-       phi_trans_add (oldexpr, expr, pred);
        return expr;
       }
       break;
@@ -1717,7 +1664,7 @@ phi_translate (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
                                                      ref->type,
                                                      newoperands,
                                                      &newref, true);
-           if (newref)
+           if (result)
              VEC_free (vn_reference_op_s, heap, newoperands);
 
            if (result && is_gimple_min_invariant (result))
@@ -1765,7 +1712,6 @@ phi_translate (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
            add_to_value (new_val_id, expr);
          }
        VEC_free (vn_reference_op_s, heap, newoperands);
-       phi_trans_add (oldexpr, expr, pred);
        return expr;
       }
       break;
@@ -1811,6 +1757,44 @@ phi_translate (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
     }
 }
 
+/* Wrapper around phi_translate_1 providing caching functionality.  */
+
+static pre_expr
+phi_translate (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
+              basic_block pred, basic_block phiblock)
+{
+  pre_expr phitrans;
+
+  if (!expr)
+    return NULL;
+
+  /* Constants contain no values that need translation.  */
+  if (expr->kind == CONSTANT)
+    return expr;
+
+  if (value_id_constant_p (get_expr_value_id (expr)))
+    return expr;
+
+  if (expr->kind != NAME)
+    {
+      phitrans = phi_trans_lookup (expr, pred);
+      if (phitrans)
+       return phitrans;
+    }
+
+  /* Translate.  */
+  phitrans = phi_translate_1 (expr, set1, set2, pred, phiblock);
+
+  /* Don't add empty translations to the cache.  Neither add
+     translations of NAMEs as those are cheap to translate.  */
+  if (phitrans
+      && expr->kind != NAME)
+    phi_trans_add (expr, phitrans, pred);
+
+  return phitrans;
+}
+
+
 /* For each expression in SET, translate the values through phi nodes
    in PHIBLOCK using edge PHIBLOCK->PRED, and store the resulting
    expressions in DEST.  */
@@ -1834,13 +1818,9 @@ phi_translate_set (bitmap_set_t dest, bitmap_set_t set, basic_block pred,
     {
       pre_expr translated;
       translated = phi_translate (expr, set, NULL, pred, phiblock);
-
-      /* Don't add empty translations to the cache  */
       if (!translated)
        continue;
 
-      phi_trans_add (expr, translated, pred);
-
       /* We might end up with multiple expressions from SET being
         translated to the same value.  In this case we do not want
         to retain the NARY or REFERENCE expression but prefer a NAME
@@ -2628,8 +2608,7 @@ can_PRE_operation (tree op)
 /* Inserted expressions are placed onto this worklist, which is used
    for performing quick dead code elimination of insertions we made
    that didn't turn out to be necessary.   */
-static VEC(gimple,heap) *inserted_exprs;
-static bitmap inserted_phi_names;
+static bitmap inserted_exprs;
 
 /* Pool allocated fake store expressions are placed onto this
    worklist, which, after performing dead code elimination, is walked
@@ -2651,31 +2630,46 @@ create_component_ref_by_pieces_1 (basic_block block, vn_reference_t ref,
     {
     case CALL_EXPR:
       {
-       tree folded, sc = currop->op1;
+       tree folded, sc = NULL_TREE;
        unsigned int nargs = 0;
-       tree *args = XNEWVEC (tree, VEC_length (vn_reference_op_s,
-                                               ref->operands) - 1);
+       tree fn, *args;
+       if (TREE_CODE (currop->op0) == FUNCTION_DECL)
+         fn = currop->op0;
+       else
+         {
+           pre_expr op0 = get_or_alloc_expr_for (currop->op0);
+           fn = find_or_generate_expression (block, op0, stmts, domstmt);
+           if (!fn)
+             return NULL_TREE;
+         }
+       if (currop->op1)
+         {
+           pre_expr scexpr = get_or_alloc_expr_for (currop->op1);
+           sc = find_or_generate_expression (block, scexpr, stmts, domstmt);
+           if (!sc)
+             return NULL_TREE;
+         }
+       args = XNEWVEC (tree, VEC_length (vn_reference_op_s,
+                                         ref->operands) - 1);
        while (*operand < VEC_length (vn_reference_op_s, ref->operands))
          {
            args[nargs] = create_component_ref_by_pieces_1 (block, ref,
                                                            operand, stmts,
                                                            domstmt);
+           if (!args[nargs])
+             {
+               free (args);
+               return NULL_TREE;
+             }
            nargs++;
          }
        folded = build_call_array (currop->type,
-                                  TREE_CODE (currop->op0) == FUNCTION_DECL
-                                  ? build_fold_addr_expr (currop->op0)
-                                  : currop->op0,
+                                  (TREE_CODE (fn) == FUNCTION_DECL
+                                   ? build_fold_addr_expr (fn) : fn),
                                   nargs, args);
        free (args);
        if (sc)
-         {
-           pre_expr scexpr = get_or_alloc_expr_for (sc);
-           sc = find_or_generate_expression (block, scexpr, stmts, domstmt);
-           if (!sc)
-             return NULL_TREE;
-           CALL_EXPR_STATIC_CHAIN (folded) = sc;
-         }
+         CALL_EXPR_STATIC_CHAIN (folded) = sc;
        return folded;
       }
       break;
@@ -2799,22 +2793,37 @@ create_component_ref_by_pieces_1 (basic_block block, vn_reference_t ref,
          return NULL_TREE;
        if (genop2)
          {
-           op2expr = get_or_alloc_expr_for (genop2);
-           genop2 = find_or_generate_expression (block, op2expr, stmts,
-                                                 domstmt);
-           if (!genop2)
-             return NULL_TREE;
+           /* Drop zero minimum index.  */
+           if (tree_int_cst_equal (genop2, integer_zero_node))
+             genop2 = NULL_TREE;
+           else
+             {
+               op2expr = get_or_alloc_expr_for (genop2);
+               genop2 = find_or_generate_expression (block, op2expr, stmts,
+                                                     domstmt);
+               if (!genop2)
+                 return NULL_TREE;
+             }
          }
        if (genop3)
          {
            tree elmt_type = TREE_TYPE (TREE_TYPE (genop0));
-           genop3 = size_binop (EXACT_DIV_EXPR, genop3,
-                                size_int (TYPE_ALIGN_UNIT (elmt_type)));
-           op3expr = get_or_alloc_expr_for (genop3);
-           genop3 = find_or_generate_expression (block, op3expr, stmts,
-                                                 domstmt);
-           if (!genop3)
-             return NULL_TREE;
+           /* We can't always put a size in units of the element alignment
+              here as the element alignment may be not visible.  See
+              PR43783.  Simply drop the element size for constant
+              sizes.  */
+           if (tree_int_cst_equal (genop3, TYPE_SIZE_UNIT (elmt_type)))
+             genop3 = NULL_TREE;
+           else
+             {
+               genop3 = size_binop (EXACT_DIV_EXPR, genop3,
+                                    size_int (TYPE_ALIGN_UNIT (elmt_type)));
+               op3expr = get_or_alloc_expr_for (genop3);
+               genop3 = find_or_generate_expression (block, op3expr, stmts,
+                                                     domstmt);
+               if (!genop3)
+                 return NULL_TREE;
+             }
          }
        return build4 (currop->opcode, currop->type, genop0, genop1,
                       genop2, genop3);
@@ -3073,9 +3082,9 @@ create_expression_by_pieces (basic_block block, pre_expr expr,
          tree forcedname = gimple_get_lhs (stmt);
          pre_expr nameexpr;
 
-         VEC_safe_push (gimple, heap, inserted_exprs, stmt);
          if (TREE_CODE (forcedname) == SSA_NAME)
            {
+             bitmap_set_bit (inserted_exprs, SSA_NAME_VERSION (forcedname));
              VN_INFO_GET (forcedname)->valnum = forcedname;
              VN_INFO (forcedname)->value_id = get_next_value_id ();
              nameexpr = get_or_alloc_expr_for_name (forcedname);
@@ -3093,24 +3102,20 @@ create_expression_by_pieces (basic_block block, pre_expr expr,
      that we will return.  */
   if (!pretemp || exprtype != TREE_TYPE (pretemp))
     {
-      pretemp = create_tmp_var (exprtype, "pretmp");
+      pretemp = create_tmp_reg (exprtype, "pretmp");
       get_var_ann (pretemp);
     }
 
   temp = pretemp;
   add_referenced_var (temp);
 
-  if (TREE_CODE (exprtype) == COMPLEX_TYPE
-      || TREE_CODE (exprtype) == VECTOR_TYPE)
-    DECL_GIMPLE_REG_P (temp) = 1;
-
   newstmt = gimple_build_assign (temp, folded);
   name = make_ssa_name (temp, newstmt);
   gimple_assign_set_lhs (newstmt, name);
   gimple_set_plf (newstmt, NECESSARY, false);
 
   gimple_seq_add_stmt (stmts, newstmt);
-  VEC_safe_push (gimple, heap, inserted_exprs, newstmt);
+  bitmap_set_bit (inserted_exprs, SSA_NAME_VERSION (name));
 
   /* All the symbols in NEWEXPR should be put into SSA form.  */
   mark_symbols_for_renaming (newstmt);
@@ -3293,7 +3298,10 @@ insert_into_preds_of_block (basic_block block, unsigned int exprnum,
                          for (; !gsi_end_p (gsi); gsi_next (&gsi))
                            {
                              gimple stmt = gsi_stmt (gsi);
-                             VEC_safe_push (gimple, heap, inserted_exprs, stmt);
+                             tree lhs = gimple_get_lhs (stmt);
+                             if (TREE_CODE (lhs) == SSA_NAME)
+                               bitmap_set_bit (inserted_exprs,
+                                               SSA_NAME_VERSION (lhs));
                              gimple_set_plf (stmt, NECESSARY, false);
                            }
                          gsi_insert_seq_on_edge (pred, stmts);
@@ -3332,7 +3340,9 @@ insert_into_preds_of_block (basic_block block, unsigned int exprnum,
                  for (; !gsi_end_p (gsi); gsi_next (&gsi))
                    {
                      gimple stmt = gsi_stmt (gsi);
-                     VEC_safe_push (gimple, heap, inserted_exprs, stmt);
+                     tree lhs = gimple_get_lhs (stmt);
+                     if (TREE_CODE (lhs) == SSA_NAME)
+                       bitmap_set_bit (inserted_exprs, SSA_NAME_VERSION (lhs));
                      gimple_set_plf (stmt, NECESSARY, false);
                    }
                  gsi_insert_seq_on_edge (pred, stmts);
@@ -3368,9 +3378,7 @@ insert_into_preds_of_block (basic_block block, unsigned int exprnum,
   gimple_set_plf (phi, NECESSARY, false);
   VN_INFO_GET (gimple_phi_result (phi))->valnum = gimple_phi_result (phi);
   VN_INFO (gimple_phi_result (phi))->value_id = val;
-  VEC_safe_push (gimple, heap, inserted_exprs, phi);
-  bitmap_set_bit (inserted_phi_names,
-                 SSA_NAME_VERSION (gimple_phi_result (phi)));
+  bitmap_set_bit (inserted_exprs, SSA_NAME_VERSION (gimple_phi_result (phi)));
   FOR_EACH_EDGE (pred, ei, block->preds)
     {
       pre_expr ae = avail[pred->src->index];
@@ -4303,8 +4311,7 @@ eliminate (void)
             replacing the PHI with a single copy if possible.
             Do not touch inserted, single-argument or virtual PHIs.  */
          if (gimple_phi_num_args (phi) == 1
-             || !is_gimple_reg (res)
-             || bitmap_bit_p (inserted_phi_names, SSA_NAME_VERSION (res)))
+             || !is_gimple_reg (res))
            {
              gsi_next (&gsi);
              continue;
@@ -4340,18 +4347,25 @@ eliminate (void)
 
          remove_phi_node (&gsi, false);
 
+         if (!bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (res))
+             && TREE_CODE (sprime) == SSA_NAME)
+           gimple_set_plf (SSA_NAME_DEF_STMT (sprime), NECESSARY, true);
+
          if (!useless_type_conversion_p (TREE_TYPE (res), TREE_TYPE (sprime)))
            sprime = fold_convert (TREE_TYPE (res), sprime);
          stmt = gimple_build_assign (res, sprime);
          SSA_NAME_DEF_STMT (res) = stmt;
-         if (TREE_CODE (sprime) == SSA_NAME)
-           gimple_set_plf (SSA_NAME_DEF_STMT (sprime),
-                           NECESSARY, true);
+         gimple_set_plf (stmt, NECESSARY, gimple_plf (phi, NECESSARY));
+
          gsi2 = gsi_after_labels (b);
          gsi_insert_before (&gsi2, stmt, GSI_NEW_STMT);
          /* Queue the copy for eventual removal.  */
          VEC_safe_push (gimple, heap, to_remove, stmt);
-         pre_stats.eliminations++;
+         /* If we inserted this PHI node ourself, it's not an elimination.  */
+         if (bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (res)))
+           pre_stats.phis--;
+         else
+           pre_stats.eliminations++;
        }
     }
 
@@ -4361,18 +4375,22 @@ eliminate (void)
   for (i = 0; VEC_iterate (gimple, to_remove, i, stmt); ++i)
     {
       tree lhs = gimple_assign_lhs (stmt);
+      tree rhs = gimple_assign_rhs1 (stmt);
       use_operand_p use_p;
       gimple use_stmt;
 
       /* If there is a single use only, propagate the equivalency
         instead of keeping the copy.  */
       if (TREE_CODE (lhs) == SSA_NAME
+         && TREE_CODE (rhs) == SSA_NAME
          && single_imm_use (lhs, &use_p, &use_stmt)
-         && may_propagate_copy (USE_FROM_PTR (use_p),
-                                gimple_assign_rhs1 (stmt)))
+         && may_propagate_copy (USE_FROM_PTR (use_p), rhs))
        {
-         SET_USE (use_p, gimple_assign_rhs1 (stmt));
+         SET_USE (use_p, rhs);
          update_stmt (use_stmt);
+         if (bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (lhs))
+             && TREE_CODE (rhs) == SSA_NAME)
+           gimple_set_plf (SSA_NAME_DEF_STMT (rhs), NECESSARY, true);
        }
 
       /* If this is a store or a now unused copy, remove it.  */
@@ -4382,6 +4400,8 @@ eliminate (void)
          gsi = gsi_for_stmt (stmt);
          unlink_stmt_vdef (stmt);
          gsi_remove (&gsi, true);
+         if (TREE_CODE (lhs) == SSA_NAME)
+           bitmap_clear_bit (inserted_exprs, SSA_NAME_VERSION (lhs));
          release_defs (stmt);
        }
     }
@@ -4427,19 +4447,23 @@ mark_operand_necessary (tree op)
 static void
 remove_dead_inserted_code (void)
 {
-  VEC(gimple,heap) *worklist = NULL;
-  int i;
+  bitmap worklist;
+  unsigned i;
+  bitmap_iterator bi;
   gimple t;
 
-  worklist = VEC_alloc (gimple, heap, VEC_length (gimple, inserted_exprs));
-  for (i = 0; VEC_iterate (gimple, inserted_exprs, i, t); i++)
+  worklist = BITMAP_ALLOC (NULL);
+  EXECUTE_IF_SET_IN_BITMAP (inserted_exprs, 0, i, bi)
     {
+      t = SSA_NAME_DEF_STMT (ssa_name (i));
       if (gimple_plf (t, NECESSARY))
-       VEC_quick_push (gimple, worklist, t);
+       bitmap_set_bit (worklist, i);
     }
-  while (VEC_length (gimple, worklist) > 0)
+  while (!bitmap_empty_p (worklist))
     {
-      t = VEC_pop (gimple, worklist);
+      i = bitmap_first_set_bit (worklist);
+      bitmap_clear_bit (worklist, i);
+      t = SSA_NAME_DEF_STMT (ssa_name (i));
 
       /* PHI nodes are somewhat special in that each PHI alternative has
         data and control dependencies.  All the statements feeding the
@@ -4448,7 +4472,6 @@ remove_dead_inserted_code (void)
        {
          unsigned k;
 
-         VEC_reserve (gimple, heap, worklist, gimple_phi_num_args (t));
          for (k = 0; k < gimple_phi_num_args (t); k++)
            {
              tree arg = PHI_ARG_DEF (t, k);
@@ -4456,7 +4479,7 @@ remove_dead_inserted_code (void)
                {
                  gimple n = mark_operand_necessary (arg);
                  if (n)
-                   VEC_quick_push (gimple, worklist, n);
+                   bitmap_set_bit (worklist, SSA_NAME_VERSION (arg));
                }
            }
        }
@@ -4477,13 +4500,14 @@ remove_dead_inserted_code (void)
            {
              gimple n = mark_operand_necessary (use);
              if (n)
-               VEC_safe_push (gimple, heap, worklist, n);
+               bitmap_set_bit (worklist, SSA_NAME_VERSION (use));
            }
        }
     }
 
-  for (i = 0; VEC_iterate (gimple, inserted_exprs, i, t); i++)
+  EXECUTE_IF_SET_IN_BITMAP (inserted_exprs, 0, i, bi)
     {
+      t = SSA_NAME_DEF_STMT (ssa_name (i));
       if (!gimple_plf (t, NECESSARY))
        {
          gimple_stmt_iterator gsi;
@@ -4504,7 +4528,7 @@ remove_dead_inserted_code (void)
            }
        }
     }
-  VEC_free (gimple, heap, worklist);
+  BITMAP_FREE (worklist);
 }
 
 /* Compute a reverse post-order in *POST_ORDER.  If INCLUDE_ENTRY_EXIT is
@@ -4518,7 +4542,6 @@ my_rev_post_order_compute (int *post_order, bool include_entry_exit)
   int sp;
   int post_order_num = 0;
   sbitmap visited;
-  int count;
 
   if (include_entry_exit)
     post_order[post_order_num++] = EXIT_BLOCK;
@@ -4573,12 +4596,7 @@ my_rev_post_order_compute (int *post_order, bool include_entry_exit)
     }
 
   if (include_entry_exit)
-    {
-      post_order[post_order_num++] = ENTRY_BLOCK;
-      count = post_order_num;
-    }
-  else
-    count = post_order_num + 2;
+    post_order[post_order_num++] = ENTRY_BLOCK;
 
   free (stack);
   sbitmap_free (visited);
@@ -4603,7 +4621,7 @@ init_pre (bool do_fre)
 
   in_fre = do_fre;
 
-  inserted_exprs = NULL;
+  inserted_exprs = BITMAP_ALLOC (NULL);
   need_creation = NULL;
   pretemp = NULL_TREE;
   storetemp = NULL_TREE;
@@ -4623,7 +4641,6 @@ init_pre (bool do_fre)
   calculate_dominance_info (CDI_DOMINATORS);
 
   bitmap_obstack_initialize (&grand_bitmap_obstack);
-  inserted_phi_names = BITMAP_ALLOC (&grand_bitmap_obstack);
   phi_translate_table = htab_create (5110, expr_pred_trans_hash,
                                     expr_pred_trans_eq, free);
   expression_to_id = htab_create (num_ssa_names * 3,
@@ -4654,7 +4671,7 @@ fini_pre (bool do_fre)
 
   free (postorder);
   VEC_free (bitmap_set_t, heap, value_expressions);
-  VEC_free (gimple, heap, inserted_exprs);
+  BITMAP_FREE (inserted_exprs);
   VEC_free (gimple, heap, need_creation);
   bitmap_obstack_release (&grand_bitmap_obstack);
   free_alloc_pool (bitmap_set_pool);
@@ -4701,17 +4718,14 @@ execute_pre (bool do_fre)
   if (!run_scc_vn (do_fre))
     {
       if (!do_fre)
-       {
-         remove_dead_inserted_code ();
-         loop_optimizer_finalize ();
-       }
+       loop_optimizer_finalize ();
 
       return 0;
     }
+
   init_pre (do_fre);
   scev_initialize ();
 
-
   /* Collect and value number expressions computed in each basic block.  */
   compute_avail ();
 
@@ -4739,6 +4753,12 @@ execute_pre (bool do_fre)
       insert ();
     }
 
+  /* Make sure to remove fake edges before committing our inserts.
+     This makes sure we don't end up with extra critical edges that
+     we would need to split.  */
+  remove_fake_exit_edges ();
+  gsi_commit_edge_inserts ();
+
   /* Remove all the redundant expressions.  */
   todo |= eliminate ();
 
@@ -4748,12 +4768,6 @@ execute_pre (bool do_fre)
   statistics_counter_event (cfun, "Eliminated", pre_stats.eliminations);
   statistics_counter_event (cfun, "Constified", pre_stats.constified);
 
-  /* Make sure to remove fake edges before committing our inserts.
-     This makes sure we don't end up with extra critical edges that
-     we would need to split.  */
-  remove_fake_exit_edges ();
-  gsi_commit_edge_inserts ();
-
   clear_expression_ids ();
   free_scc_vn ();
   if (!do_fre)