OSDN Git Service

2008-01-17 H.J. Lu <hongjiu.lu@intel.com>
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-pre.c
index 059a2ad..6a06b2a 100644 (file)
@@ -8,7 +8,7 @@ This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GCC is distributed in the hope that it will be useful,
@@ -17,9 +17,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to
-the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
 #include "system.h"
@@ -46,6 +45,7 @@ Boston, MA 02110-1301, USA.  */
 #include "langhooks.h"
 #include "cfgloop.h"
 #include "tree-ssa-sccvn.h"
+#include "params.h"
 
 /* TODO:
 
@@ -112,7 +112,7 @@ Boston, MA 02110-1301, USA.  */
 
    Fourth, we eliminate fully redundant expressions.
    This is a simple statement walk that replaces redundant
-   calculations  with the now available values.  */
+   calculations with the now available values.  */
 
 /* Representations of value numbers:
 
@@ -185,6 +185,12 @@ Boston, MA 02110-1301, USA.  */
 /* Next global expression id number.  */
 static unsigned int next_expression_id;
 
+typedef VEC(tree, gc) *vuse_vec;
+DEF_VEC_P (vuse_vec);
+DEF_VEC_ALLOC_P (vuse_vec, heap);
+
+static VEC(vuse_vec, heap) *expression_vuses;
+
 /* Mapping from expression to id number we can use in bitmap sets.  */
 static VEC(tree, heap) *expressions;
 
@@ -203,6 +209,7 @@ alloc_expression_id (tree expr)
   ann->aux = XNEW (unsigned int);
   * ((unsigned int *)ann->aux) = next_expression_id++;
   VEC_safe_push (tree, heap, expressions, expr);
+  VEC_safe_push (vuse_vec, heap, expression_vuses, NULL);
   return next_expression_id - 1;
 }
 
@@ -240,6 +247,25 @@ expression_for_id (unsigned int id)
   return VEC_index (tree, expressions, id);
 }
 
+/* Return the expression vuses for EXPR, if there are any.  */
+
+static inline vuse_vec
+get_expression_vuses (tree expr)
+{
+  unsigned int expr_id = get_or_alloc_expression_id (expr);
+  return VEC_index (vuse_vec, expression_vuses, expr_id);
+}
+
+/* Set the expression vuses for EXPR to VUSES.  */
+
+static inline void
+set_expression_vuses (tree expr, vuse_vec vuses)
+{
+  unsigned int expr_id = get_or_alloc_expression_id (expr);
+  VEC_replace (vuse_vec, expression_vuses, expr_id, vuses);
+}
+
+
 /* Free the expression id field in all of our expressions,
    and then destroy the expressions array.  */
 
@@ -255,6 +281,7 @@ clear_expression_ids (void)
       tree_common_ann (expr)->aux = NULL;
     }
   VEC_free (tree, heap, expressions);
+  VEC_free (vuse_vec, heap, expression_vuses);
 }
 
 static bool in_fre = false;
@@ -302,10 +329,6 @@ typedef struct bb_bitmap_sets
      the current iteration.  */
   bitmap_set_t new_sets;
 
-  /* These are the loads that will be ANTIC_IN at the top of the
-     block, and are actually generated in the block.  */
-  bitmap_set_t antic_safe_loads;
-
   /* True if we have visited this block during ANTIC calculation.  */
   unsigned int visited:1;
 
@@ -321,7 +344,6 @@ typedef struct bb_bitmap_sets
 #define ANTIC_IN(BB)   ((bb_value_sets_t) ((BB)->aux))->antic_in
 #define PA_IN(BB)      ((bb_value_sets_t) ((BB)->aux))->pa_in
 #define NEW_SETS(BB)   ((bb_value_sets_t) ((BB)->aux))->new_sets
-#define ANTIC_SAFE_LOADS(BB) ((bb_value_sets_t) ((BB)->aux))->antic_safe_loads
 #define BB_VISITED(BB) ((bb_value_sets_t) ((BB)->aux))->visited
 #define BB_DEFERRED(BB) ((bb_value_sets_t) ((BB)->aux))->deferred
 
@@ -361,7 +383,6 @@ static void bitmap_set_copy (bitmap_set_t, bitmap_set_t);
 static bool bitmap_set_contains_value (bitmap_set_t, tree);
 static void bitmap_insert_into_set (bitmap_set_t, tree);
 static bitmap_set_t bitmap_set_new (void);
-static bool is_undefined_value (tree);
 static tree create_expression_by_pieces (basic_block, tree, tree);
 static tree find_or_generate_expression (basic_block, tree, tree);
 
@@ -423,13 +444,14 @@ typedef struct expr_pred_trans_d
      speed reasons.  */
   hashval_t hashcode;
 } *expr_pred_trans_t;
+typedef const struct expr_pred_trans_d *const_expr_pred_trans_t;
 
 /* Return the hash value for a phi translation table entry.  */
 
 static hashval_t
 expr_pred_trans_hash (const void *p)
 {
-  const expr_pred_trans_t ve = (expr_pred_trans_t) p;
+  const_expr_pred_trans_t const ve = (const_expr_pred_trans_t) p;
   return ve->hashcode;
 }
 
@@ -439,8 +461,8 @@ expr_pred_trans_hash (const void *p)
 static int
 expr_pred_trans_eq (const void *p1, const void *p2)
 {
-  const expr_pred_trans_t ve1 = (expr_pred_trans_t) p1;
-  const expr_pred_trans_t ve2 = (expr_pred_trans_t) p2;
+  const_expr_pred_trans_t const ve1 = (const_expr_pred_trans_t) p1;
+  const_expr_pred_trans_t const ve2 = (const_expr_pred_trans_t) p2;
   basic_block b1 = ve1->pred;
   basic_block b2 = ve2->pred;
   int i;
@@ -523,7 +545,7 @@ phi_trans_add (tree e, tree v, basic_block pred, VEC (tree, gc) *vuses)
 static inline bool
 constant_expr_p (tree v)
 {
-  return TREE_CODE (v) != VALUE_HANDLE && 
+  return TREE_CODE (v) != VALUE_HANDLE &&
     (TREE_CODE (v) == FIELD_DECL || is_gimple_min_invariant (v));
 }
 
@@ -943,7 +965,7 @@ find_leader_in_sets (tree expr, bitmap_set_t set1, bitmap_set_t set2)
    the phis in PRED.  SEEN is a bitmap saying which expression we have
    translated since we started translation of the toplevel expression.
    Return NULL if we can't find a leader for each part of the
-   translated expression.  */  
+   translated expression.  */
 
 static tree
 phi_translate_1 (tree expr, bitmap_set_t set1, bitmap_set_t set2,
@@ -961,13 +983,7 @@ phi_translate_1 (tree expr, bitmap_set_t set1, bitmap_set_t set2,
   /* Phi translations of a given expression don't change.  */
   if (EXPR_P (expr) || GIMPLE_STMT_P (expr))
     {
-      tree vh;
-
-      vh = get_value_handle (expr);
-      if (vh && TREE_CODE (vh) == VALUE_HANDLE)
-       phitrans = phi_trans_lookup (expr, pred, VALUE_HANDLE_VUSES (vh));
-      else
-       phitrans = phi_trans_lookup (expr, pred, NULL);
+      phitrans = phi_trans_lookup (expr, pred, get_expression_vuses (expr));
     }
   else
     phitrans = phi_trans_lookup (expr, pred, NULL);
@@ -1000,10 +1016,9 @@ phi_translate_1 (tree expr, bitmap_set_t set1, bitmap_set_t set2,
            tree oldsc = CALL_EXPR_STATIC_CHAIN (expr);
            tree newfn, newsc = NULL;
            tree newexpr = NULL_TREE;
-           tree vh = get_value_handle (expr);
            bool invariantarg = false;
            int i, nargs;
-           VEC (tree, gc) *vuses = VALUE_HANDLE_VUSES (vh);
+           VEC (tree, gc) *vuses = get_expression_vuses (expr);
            VEC (tree, gc) *tvuses;
 
            newfn = phi_translate_1 (find_leader_in_sets (oldfn, set1, set2),
@@ -1089,6 +1104,7 @@ phi_translate_1 (tree expr, bitmap_set_t set1, bitmap_set_t set2,
                newexpr->base.ann = NULL;
                vn_lookup_or_add_with_vuses (newexpr, tvuses);
                expr = newexpr;
+               set_expression_vuses (newexpr, tvuses);
              }
            phi_trans_add (oldexpr, expr, pred, tvuses);
          }
@@ -1100,14 +1116,16 @@ phi_translate_1 (tree expr, bitmap_set_t set1, bitmap_set_t set2,
        VEC (tree, gc) * oldvuses = NULL;
        VEC (tree, gc) * newvuses = NULL;
 
-       oldvuses = VALUE_HANDLE_VUSES (get_value_handle (expr));
+       oldvuses = get_expression_vuses (expr);
        if (oldvuses)
          newvuses = translate_vuses_through_block (oldvuses, phiblock,
                                                    pred);
 
        if (oldvuses != newvuses)
-         vn_lookup_or_add_with_vuses (expr, newvuses);
-
+         {
+           vn_lookup_or_add_with_vuses (expr, newvuses);
+           set_expression_vuses (expr, newvuses);
+         }
        phi_trans_add (oldexpr, expr, pred, newvuses);
       }
       return expr;
@@ -1165,7 +1183,7 @@ phi_translate_1 (tree expr, bitmap_set_t set1, bitmap_set_t set2,
              }
          }
 
-       oldvuses = VALUE_HANDLE_VUSES (get_value_handle (expr));
+       oldvuses = get_expression_vuses (expr);
        if (oldvuses)
          newvuses = translate_vuses_through_block (oldvuses, phiblock,
                                                    pred);
@@ -1200,6 +1218,7 @@ phi_translate_1 (tree expr, bitmap_set_t set1, bitmap_set_t set2,
              {
                newexpr->base.ann = NULL;
                vn_lookup_or_add_with_vuses (newexpr, newvuses);
+               set_expression_vuses (newexpr, newvuses);
              }
            expr = newexpr;
          }
@@ -1304,13 +1323,13 @@ phi_translate_1 (tree expr, bitmap_set_t set1, bitmap_set_t set2,
          {
            tree val;
            tree def = PHI_ARG_DEF (phi, e->dest_idx);
-           
+
            if (is_gimple_min_invariant (def))
              return def;
-           
-           if (is_undefined_value (def))
+
+           if (TREE_CODE (def) == SSA_NAME && ssa_undefined_value_p (def))
              return NULL;
-           
+
            val = get_value_handle (def);
            gcc_assert (val);
            return def;
@@ -1324,9 +1343,9 @@ phi_translate_1 (tree expr, bitmap_set_t set1, bitmap_set_t set2,
 }
 
 /* Translate EXPR using phis in PHIBLOCK, so that it has the values of
-   the phis in PRED. 
+   the phis in PRED.
    Return NULL if we can't find a leader for each part of the
-   translated expression.  */  
+   translated expression.  */
 
 static tree
 phi_translate (tree expr, bitmap_set_t set1, bitmap_set_t set2,
@@ -1365,14 +1384,8 @@ phi_translate_set (bitmap_set_t dest, bitmap_set_t set, basic_block pred,
         we won't look them up that way, or use the result, anyway.  */
       if (translated && !is_gimple_min_invariant (translated))
        {
-         tree vh = get_value_handle (translated);
-         VEC (tree, gc) *vuses;
-
-         /* The value handle itself may also be an invariant, in
-            which case, it has no vuses.  */
-         vuses = !is_gimple_min_invariant (vh)
-           ? VALUE_HANDLE_VUSES (vh) : NULL;
-         phi_trans_add (expr, translated, pred, vuses);
+         phi_trans_add (expr, translated, pred,
+                        get_expression_vuses (translated));
        }
 
       if (translated != NULL)
@@ -1418,7 +1431,7 @@ bitmap_find_leader (bitmap_set_t set, tree val)
   return NULL;
 }
 
-/* Determine if VALUE, a memory operation, is ANTIC_IN at the top of
+/* Determine if EXPR, a memory expression, is ANTIC_IN at the top of
    BLOCK by seeing if it is not killed in the block.  Note that we are
    only determining whether there is a store that kills it.  Because
    of the order in which clean iterates over values, we are guaranteed
@@ -1426,11 +1439,11 @@ bitmap_find_leader (bitmap_set_t set, tree val)
    ANTIC_IN set already.  */
 
 static bool
-value_dies_in_block_x (tree vh, basic_block block)
+value_dies_in_block_x (tree expr, basic_block block)
 {
   int i;
   tree vuse;
-  VEC (tree, gc) *vuses = VALUE_HANDLE_VUSES (vh);
+  VEC (tree, gc) *vuses = get_expression_vuses (expr);
 
   /* Conservatively, a value dies if it's vuses are defined in this
      block, unless they come from phi nodes (which are merge operations,
@@ -1467,7 +1480,6 @@ static bool
 valid_in_sets (bitmap_set_t set1, bitmap_set_t set2, tree expr,
               basic_block block)
 {
- tree vh = get_value_handle (expr);
  switch (TREE_CODE_CLASS (TREE_CODE (expr)))
     {
     case tcc_binary:
@@ -1509,7 +1521,7 @@ valid_in_sets (bitmap_set_t set1, bitmap_set_t set2, tree expr,
                if (!union_contains_value (set1, set2, arg))
                  return false;
              }
-           return !value_dies_in_block_x (vh, block);
+           return !value_dies_in_block_x (expr, block);
          }
        return false;
       }
@@ -1545,9 +1557,7 @@ valid_in_sets (bitmap_set_t set1, bitmap_set_t set2, tree expr,
                    && !union_contains_value (set1, set2, op3))
                  return false;
            }
-         return bitmap_set_contains_value (ANTIC_SAFE_LOADS (block),
-                                           vh)
-           || !value_dies_in_block_x (vh, block);
+           return !value_dies_in_block_x (expr, block);
          }
       }
       return false;
@@ -1559,7 +1569,7 @@ valid_in_sets (bitmap_set_t set1, bitmap_set_t set2, tree expr,
       }
 
     case tcc_declaration:
-      return !value_dies_in_block_x (vh, block);
+      return !value_dies_in_block_x (expr, block);
 
     default:
       /* No other cases should be encountered.  */
@@ -1786,9 +1796,6 @@ compute_antic_aux (basic_block block, bool block_has_abnormal_pred_edge)
          if (ANTIC_OUT)
            print_bitmap_set (dump_file, ANTIC_OUT, "ANTIC_OUT", block->index);
 
-         if (ANTIC_SAFE_LOADS (block))
-           print_bitmap_set (dump_file, ANTIC_SAFE_LOADS (block),
-                             "ANTIC_SAFE_LOADS", block->index);
          print_bitmap_set (dump_file, ANTIC_IN (block), "ANTIC_IN",
                            block->index);
 
@@ -1832,6 +1839,7 @@ compute_partial_antic_aux (basic_block block,
   bitmap_set_t PA_OUT;
   edge e;
   edge_iterator ei;
+  unsigned long max_pa = PARAM_VALUE (PARAM_MAX_PARTIAL_ANTIC_LENGTH);
 
   old_PA_IN = PA_OUT = NULL;
 
@@ -1840,6 +1848,14 @@ compute_partial_antic_aux (basic_block block,
   if (block_has_abnormal_pred_edge)
     goto maybe_dump_sets;
 
+  /* If there are too many partially anticipatable values in the
+     block, phi_translate_set can take an exponential time: stop
+     before the translation starts.  */
+  if (max_pa
+      && single_succ_p (block)
+      && bitmap_count_bits (PA_IN (single_succ (block))->values) > max_pa)
+    goto maybe_dump_sets;
+
   old_PA_IN = PA_IN (block);
   PA_OUT = bitmap_set_new ();
 
@@ -2042,74 +2058,6 @@ compute_antic (void)
   sbitmap_free (changed_blocks);
 }
 
-/*
-   ANTIC_SAFE_LOADS are those loads generated in a block that actually
-   occur before any kill to their vuses in the block, and thus, are
-   safe at the top of the block.  This function computes the set by
-   walking the EXP_GEN set for the block, and checking the VUSES.
-
-   This set could be computed as ANTIC calculation is proceeding, but
-   but because it does not actually change during that computation, it is
-   quicker to pre-calculate the results and use them than to do it on
-   the fly (particularly in the presence of multiple iteration).  */
-
-static void
-compute_antic_safe (void)
-{
-  basic_block bb;
-  bitmap_iterator bi;
-  unsigned int i;
-
-  FOR_EACH_BB (bb)
-    {
-      FOR_EACH_EXPR_ID_IN_SET (EXP_GEN (bb), i, bi)
-       {
-         tree expr = expression_for_id (i);
-         if (REFERENCE_CLASS_P (expr))
-           {
-             tree vh = get_value_handle (expr);
-             tree maybe = bitmap_find_leader (AVAIL_OUT (bb), vh);
-             ssa_op_iter i;
-             tree vuse;
-             tree stmt;
-             bool okay = true;
-
-             if (!maybe)
-               continue;
-             stmt = SSA_NAME_DEF_STMT (maybe);
-             if (TREE_CODE (stmt) == PHI_NODE)
-               continue;
-             
-             FOR_EACH_SSA_TREE_OPERAND (vuse, stmt, i,
-                                        SSA_OP_VIRTUAL_USES)
-               {
-                 tree def = SSA_NAME_DEF_STMT (vuse);
-
-                 if (bb_for_stmt (def) != bb)
-                   continue;
-
-                 /* See if the vuse is defined by a statement that
-                    comes before us in the block.  Phi nodes are not
-                    stores, so they do not count.  */
-                 if (TREE_CODE (def) != PHI_NODE
-                     && stmt_ann (def)->uid < stmt_ann (stmt)->uid)
-                   {
-                     okay = false;
-                     break;
-                   }
-               }
-             if (okay)
-               {
-                 if (ANTIC_SAFE_LOADS (bb) == NULL)
-                   ANTIC_SAFE_LOADS (bb) = bitmap_set_new ();
-                 bitmap_value_insert_into_set (ANTIC_SAFE_LOADS (bb),
-                                               expr);
-               }
-           }
-       }
-    }
-}
-
 /* Return true if we can value number the call in STMT.  This is true
    if we have a pure or constant call.  */
 
@@ -2124,7 +2072,7 @@ can_value_number_call (tree stmt)
 }
 
 /* Return true if OP is an exception handler related operation, such as
-   FILTER_EXPRor EXC_PTR_EXPR.  */
+   FILTER_EXPR or EXC_PTR_EXPR.  */
 
 static bool
 is_exception_related (tree op)
@@ -2138,7 +2086,7 @@ is_exception_related (tree op)
 static bool
 can_value_number_operation (tree op)
 {
-  return (UNARY_CLASS_P (op) 
+  return (UNARY_CLASS_P (op)
          && !is_exception_related (TREE_OPERAND (op, 0)))
     || BINARY_CLASS_P (op)
     || COMPARISON_CLASS_P (op)
@@ -2584,7 +2532,7 @@ insert_into_preds_of_block (basic_block block, unsigned int exprnum,
 
   NECESSARY (temp) = 0;
   VN_INFO_GET (PHI_RESULT (temp))->valnum = PHI_RESULT (temp);
-  
+
   VEC_safe_push (tree, heap, inserted_exprs, temp);
   FOR_EACH_EDGE (pred, ei, block->preds)
     add_phi_arg (temp, avail[pred->src->index], pred);
@@ -2940,20 +2888,8 @@ insert (void)
 }
 
 
-/* Return true if VAR is an SSA variable with no defining statement in
-   this procedure, *AND* isn't a live-on-entry parameter.  */
-
-static bool
-is_undefined_value (tree expr)
-{
-  return (TREE_CODE (expr) == SSA_NAME
-         && IS_EMPTY_STMT (SSA_NAME_DEF_STMT (expr))
-         /* PARM_DECLs and hard registers are always defined.  */
-         && TREE_CODE (SSA_NAME_VAR (expr)) != PARM_DECL);
-}
-
 /* Add OP to EXP_GEN (block), and possibly to the maximal set if it is
-   not defined by a phi node.   
+   not defined by a phi node.
    PHI nodes can't go in the maximal sets because they are not in
    TMP_GEN, so it is possible to get into non-monotonic situations
    during ANTIC calculation, because it will *add* bits.  */
@@ -2963,7 +2899,7 @@ add_to_exp_gen (basic_block block, tree op)
 {
   if (!in_fre)
     {
-      if (TREE_CODE (op) == SSA_NAME && is_undefined_value (op))
+      if (TREE_CODE (op) == SSA_NAME && ssa_undefined_value_p (op))
        return;
       bitmap_value_insert_into_set (EXP_GEN (block), op);
       if (TREE_CODE (op) != SSA_NAME
@@ -2983,11 +2919,11 @@ add_to_exp_gen (basic_block block, tree op)
    any).  */
 
 static inline void
-add_to_sets (tree var, tree expr, tree stmt, bitmap_set_t s1,
+add_to_sets (tree var, tree expr, VEC(tree, gc) *vuses, bitmap_set_t s1,
             bitmap_set_t s2)
 {
   tree val;
-  val = vn_lookup_or_add_with_stmt (expr, stmt);
+  val = vn_lookup_or_add_with_vuses (expr, vuses);
 
   /* VAR and EXPR may be the same when processing statements for which
      we are not computing value numbers (e.g., non-assignments, or
@@ -3006,7 +2942,7 @@ add_to_sets (tree var, tree expr, tree stmt, bitmap_set_t s1,
    and return it if it exists.  */
 
 static inline tree
-find_existing_value_expr (tree t, tree stmt)
+find_existing_value_expr (tree t, VEC (tree, gc) *vuses)
 {
   bitmap_iterator bi;
   unsigned int bii;
@@ -3014,10 +2950,10 @@ find_existing_value_expr (tree t, tree stmt)
   bitmap_set_t exprset;
 
   if (REFERENCE_CLASS_P (t) || TREE_CODE (t) == CALL_EXPR || DECL_P (t))
-    vh = vn_lookup_with_stmt (t, stmt);
+    vh = vn_lookup_with_vuses (t, vuses);
   else
     vh = vn_lookup (t);
-  
+
   if (!vh)
     return NULL;
   exprset = VALUE_HANDLE_EXPR_SET (vh);
@@ -3038,7 +2974,7 @@ find_existing_value_expr (tree t, tree stmt)
    any). Insert EXPR's operands into the EXP_GEN set for BLOCK. */
 
 static inline tree
-create_value_expr_from (tree expr, basic_block block, tree stmt)
+create_value_expr_from (tree expr, basic_block block, VEC (tree, gc) *vuses)
 {
   int i;
   enum tree_code code = TREE_CODE (expr);
@@ -3086,9 +3022,10 @@ create_value_expr_from (tree expr, basic_block block, tree stmt)
       /* Recursively value-numberize reference ops and tree lists.  */
       if (REFERENCE_CLASS_P (op))
        {
-         tree tempop = create_value_expr_from (op, block, stmt);
+         tree tempop = create_value_expr_from (op, block, vuses);
          op = tempop ? tempop : op;
-         val = vn_lookup_or_add_with_stmt (op, stmt);
+         val = vn_lookup_or_add_with_vuses (op, vuses);
+         set_expression_vuses (op, vuses);
        }
       else
        {
@@ -3096,13 +3033,13 @@ create_value_expr_from (tree expr, basic_block block, tree stmt)
        }
       if (TREE_CODE (op) != TREE_LIST)
        add_to_exp_gen (block, op);
-      
+
       if (TREE_CODE (val) == VALUE_HANDLE)
        TREE_TYPE (val) = TREE_TYPE (TREE_OPERAND (vexpr, i));
 
       TREE_OPERAND (vexpr, i) = val;
     }
-  efi = find_existing_value_expr (vexpr, stmt);
+  efi = find_existing_value_expr (vexpr, vuses);
   if (efi)
     return efi;
   get_or_alloc_expression_id (vexpr);
@@ -3141,6 +3078,7 @@ poolify_tree (tree node)
     case INTEGER_CST:
     case STRING_CST:
     case REAL_CST:
+    case FIXED_CST:
     case PARM_DECL:
     case VAR_DECL:
     case RESULT_DECL:
@@ -3233,7 +3171,7 @@ insert_fake_stores (void)
 
              lhs = make_ssa_name (storetemp, new_tree);
              GIMPLE_STMT_OPERAND (new_tree, 0) = lhs;
-             create_ssa_artificial_load_stmt (new_tree, stmt);
+             create_ssa_artificial_load_stmt (new_tree, stmt, false);
 
              NECESSARY (new_tree) = 0;
              VEC_safe_push (tree, heap, inserted_exprs, new_tree);
@@ -3306,7 +3244,7 @@ get_sccvn_value (tree name)
       if (!valvh && !is_invariant)
        {
          tree defstmt = SSA_NAME_DEF_STMT (val);
-         
+
          gcc_assert (VN_INFO (val)->valnum == val);
          /* PHI nodes can't have vuses and attempts to iterate over
             their VUSE operands will crash.  */
@@ -3320,7 +3258,7 @@ get_sccvn_value (tree name)
          }
          valvh = vn_lookup_or_add_with_stmt (val, defstmt);
        }
-      
+
       if (dump_file && (dump_flags & TDF_DETAILS))
        {
          fprintf (dump_file, "SCCVN says ");
@@ -3334,7 +3272,7 @@ get_sccvn_value (tree name)
              fprintf (dump_file, ")\n");
            }
          else
-           print_generic_stmt (dump_file, val, 0);  
+           print_generic_stmt (dump_file, val, 0);
        }
       if (valvh)
        return valvh;
@@ -3367,7 +3305,6 @@ make_values_for_phi (tree phi, basic_block block)
     }
 }
 
-
 /* Create value handles for STMT in BLOCK.  Return true if we handled
    the statement.  */
 
@@ -3379,12 +3316,14 @@ make_values_for_stmt (tree stmt, basic_block block)
   tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
   tree valvh = NULL_TREE;
   tree lhsval;
-  
+  VEC (tree, gc) *vuses = NULL;
+
   valvh = get_sccvn_value (lhs);
+
   if (valvh)
     {
       vn_add (lhs, valvh);
-      bitmap_value_insert_into_set (AVAIL_OUT (block), lhs);      
+      bitmap_value_insert_into_set (AVAIL_OUT (block), lhs);
       /* Shortcut for FRE. We have no need to create value expressions,
         just want to know what values are available where.  */
       if (in_fre)
@@ -3401,9 +3340,9 @@ make_values_for_stmt (tree stmt, basic_block block)
       bitmap_value_insert_into_set (AVAIL_OUT (block), lhs);
       return true;
     }
-  
+
   lhsval = valvh ? valvh : get_value_handle (lhs);
-  
+  vuses = copy_vuses_from_stmt (stmt);
   STRIP_USELESS_TYPE_CONVERSION (rhs);
   if (can_value_number_operation (rhs)
       && (!lhsval || !is_gimple_min_invariant (lhsval)))
@@ -3411,9 +3350,10 @@ make_values_for_stmt (tree stmt, basic_block block)
       /* For value numberable operation, create a
         duplicate expression with the operands replaced
         with the value handles of the original RHS.  */
-      tree newt = create_value_expr_from (rhs, block, stmt);
+      tree newt = create_value_expr_from (rhs, block, vuses);
       if (newt)
        {
+         set_expression_vuses (newt, vuses);
          /* If we already have a value number for the LHS, reuse
             it rather than creating a new one.  */
          if (lhsval)
@@ -3424,13 +3364,13 @@ make_values_for_stmt (tree stmt, basic_block block)
            }
          else
            {
-             tree val = vn_lookup_or_add_with_stmt (newt, stmt);
+             tree val = vn_lookup_or_add_with_vuses (newt, vuses);
              vn_add (lhs, val);
            }
-         
+
          add_to_exp_gen (block, newt);
-       }      
-      
+       }
+
       bitmap_insert_into_set (TMP_GEN (block), lhs);
       bitmap_value_insert_into_set (AVAIL_OUT (block), lhs);
       return true;
@@ -3442,9 +3382,10 @@ make_values_for_stmt (tree stmt, basic_block block)
           || TREE_INVARIANT (rhs)
           || DECL_P (rhs))
     {
-      
+
       if (lhsval)
        {
+         set_expression_vuses (rhs, vuses);
          set_value_handle (rhs, lhsval);
          if (!is_gimple_min_invariant (lhsval))
            add_to_value (lhsval, rhs);
@@ -3456,11 +3397,12 @@ make_values_for_stmt (tree stmt, basic_block block)
          /* Compute a value number for the RHS of the statement
             and add its value to the AVAIL_OUT set for the block.
             Add the LHS to TMP_GEN.  */
-         add_to_sets (lhs, rhs, stmt, TMP_GEN (block),
+         set_expression_vuses (rhs, vuses);
+         add_to_sets (lhs, rhs, vuses, TMP_GEN (block),
                       AVAIL_OUT (block));
        }
       /* None of the rest of these can be PRE'd.  */
-      if (TREE_CODE (rhs) == SSA_NAME && !is_undefined_value (rhs))
+      if (TREE_CODE (rhs) == SSA_NAME && !ssa_undefined_value_p (rhs))
        add_to_exp_gen (block, rhs);
       return true;
     }
@@ -3515,7 +3457,7 @@ compute_avail (void)
          tree def = gimple_default_def (cfun, param);
 
          vn_lookup_or_add (def);
-         if (!in_fre) 
+         if (!in_fre)
            {
              bitmap_insert_into_set (TMP_GEN (ENTRY_BLOCK_PTR), def);
              bitmap_value_insert_into_set (maximal_set, def);
@@ -3610,10 +3552,11 @@ compute_avail (void)
            }
 
          else if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
-             && !ann->has_volatile_ops
-             && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == SSA_NAME
-             && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI
-                  (GIMPLE_STMT_OPERAND (stmt, 0)))
+                  && !ann->has_volatile_ops
+                  && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == SSA_NAME
+                  && (!SSA_NAME_OCCURS_IN_ABNORMAL_PHI
+                      (GIMPLE_STMT_OPERAND (stmt, 0)))
+                  && !tree_could_throw_p (stmt))
            {
              if (make_values_for_stmt (stmt, block))
                continue;
@@ -3676,7 +3619,7 @@ eliminate (void)
 
              sprime = bitmap_find_leader (AVAIL_OUT (b),
                                           get_value_handle (lhs));
-             
+
              if (sprime
                  && sprime != lhs
                  && (TREE_CODE (*rhs_p) != SSA_NAME
@@ -3848,9 +3791,10 @@ static void
 init_pre (bool do_fre)
 {
   basic_block bb;
-  
+
   next_expression_id = 0;
   expressions = NULL;
+  expression_vuses = NULL;
   in_fre = do_fre;
 
   inserted_exprs = NULL;
@@ -3976,7 +3920,13 @@ execute_pre (bool do_fre)
     insert_fake_stores ();
 
   /* Collect and value number expressions computed in each basic block.  */
-  run_scc_vn ();
+  if (!run_scc_vn ())
+    {
+      if (!do_fre)
+       remove_dead_inserted_code ();
+      fini_pre ();
+      return;
+    }
   switch_to_PRE_table ();
   compute_avail ();
 
@@ -4001,7 +3951,6 @@ execute_pre (bool do_fre)
      computing ANTIC, either, even though it's plenty fast.  */
   if (!do_fre && n_basic_blocks < 4000)
     {
-      compute_antic_safe ();
       compute_antic ();
       insert ();
     }
@@ -4036,7 +3985,7 @@ static unsigned int
 do_pre (void)
 {
   execute_pre (false);
-  return 0;
+  return TODO_rebuild_alias;
 }
 
 static bool