OSDN Git Service

* config/microblaze/microblaze.h (CC1_SPEC): Remove %{save-temps: }.
[pf3gnuchains/gcc-fork.git] / gcc / value-prof.c
index 0710250..0a36ed2 100644 (file)
@@ -1,5 +1,5 @@
 /* Transformations based on profile information for values.
-   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -45,11 +45,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "cgraph.h"
 #include "timevar.h"
 #include "tree-pass.h"
-#include "toplev.h"
 #include "pointer-set.h"
 
-static struct value_prof_hooks *value_prof_hooks;
-
 /* In this file value profile based optimizations are placed.  Currently the
    following optimizations are implemented (for more detailed descriptions
    see comments at value_profile_transformations):
@@ -489,7 +486,7 @@ check_counter (gimple stmt, const char * name,
 
 /* GIMPLE based transformations. */
 
-static bool
+bool
 gimple_value_profile_transformations (void)
 {
   basic_block bb;
@@ -702,6 +699,7 @@ gimple_divmod_fixed_value_transform (gimple_stmt_iterator *si)
     }
 
   gimple_assign_set_rhs_from_tree (si, result);
+  update_stmt (gsi_stmt (*si));
 
   return true;
 }
@@ -851,6 +849,7 @@ gimple_mod_pow2_value_transform (gimple_stmt_iterator *si)
   result = gimple_mod_pow2 (stmt, prob, count, all);
 
   gimple_assign_set_rhs_from_tree (si, result);
+  update_stmt (gsi_stmt (*si));
 
   return true;
 }
@@ -1051,6 +1050,7 @@ gimple_mod_subtract_transform (gimple_stmt_iterator *si)
   result = gimple_mod_subtract (stmt, prob1, prob2, i, count1, count2, all);
 
   gimple_assign_set_rhs_from_tree (si, result);
+  update_stmt (gsi_stmt (*si));
 
   return true;
 }
@@ -1143,7 +1143,16 @@ gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call,
   icall_bb = e_di->dest;
   icall_bb->count = all - count;
 
-  e_ij = split_block (icall_bb, icall_stmt);
+  /* Do not disturb existing EH edges from the indirect call.  */
+  if (!stmt_ends_bb_p (icall_stmt))
+    e_ij = split_block (icall_bb, icall_stmt);
+  else
+    {
+      e_ij = find_fallthru_edge (icall_bb->succs);
+      e_ij->probability = REG_BR_PROB_BASE;
+      e_ij->count = all - count;
+      e_ij = single_pred_edge (split_edge (e_ij));
+    }
   join_bb = e_ij->dest;
   join_bb->count = all;
 
@@ -1179,21 +1188,27 @@ gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call,
       add_phi_arg (phi, gimple_call_lhs (dcall_stmt), e_dj, UNKNOWN_LOCATION);
     }
 
-  /* Fix eh edges */
+  /* Build an EH edge for the direct call if necessary.  */
   lp_nr = lookup_stmt_eh_lp (icall_stmt);
-  if (lp_nr != 0)
+  if (lp_nr != 0
+      && stmt_could_throw_p (dcall_stmt))
     {
-      if (stmt_could_throw_p (dcall_stmt))
+      edge e_eh, e;
+      edge_iterator ei;
+      gimple_stmt_iterator psi;
+
+      add_stmt_to_eh_lp (dcall_stmt, lp_nr);
+      FOR_EACH_EDGE (e_eh, ei, icall_bb->succs)
+       if (e_eh->flags & EDGE_EH)
+         break;
+      e = make_edge (dcall_bb, e_eh->dest, EDGE_EH);
+      for (psi = gsi_start_phis (e_eh->dest);
+          !gsi_end_p (psi); gsi_next (&psi))
        {
-         add_stmt_to_eh_lp (dcall_stmt, lp_nr);
-         make_eh_edges (dcall_stmt);
+         gimple phi = gsi_stmt (psi);
+         SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e),
+                  PHI_ARG_DEF_FROM_EDGE (phi, e_eh));
        }
-
-      gcc_assert (stmt_could_throw_p (icall_stmt));
-      make_eh_edges (icall_stmt);
-
-      /* The old EH edges are sill on the join BB, purge them.  */
-      gimple_purge_dead_eh_edges (join_bb);
     }
 
   return dcall_stmt;
@@ -1386,6 +1401,21 @@ gimple_stringop_fixed_value (gimple vcall_stmt, tree icall_size, int prob,
   e_vj->probability = REG_BR_PROB_BASE;
   e_vj->count = all - count;
 
+  /* Insert PHI node for the call result if necessary.  */
+  if (gimple_call_lhs (vcall_stmt)
+      && TREE_CODE (gimple_call_lhs (vcall_stmt)) == SSA_NAME)
+    {
+      tree result = gimple_call_lhs (vcall_stmt);
+      gimple phi = create_phi_node (result, join_bb);
+      SSA_NAME_DEF_STMT (result) = phi;
+      gimple_call_set_lhs (vcall_stmt,
+                          make_ssa_name (SSA_NAME_VAR (result), vcall_stmt));
+      add_phi_arg (phi, gimple_call_lhs (vcall_stmt), e_vj, UNKNOWN_LOCATION);
+      gimple_call_set_lhs (icall_stmt,
+                          make_ssa_name (SSA_NAME_VAR (result), icall_stmt));
+      add_phi_arg (phi, gimple_call_lhs (icall_stmt), e_ij, UNKNOWN_LOCATION);
+    }
+
   /* Because these are all string op builtins, they're all nothrow.  */
   gcc_assert (!stmt_could_throw_p (vcall_stmt));
   gcc_assert (!stmt_could_throw_p (icall_stmt));
@@ -1528,14 +1558,6 @@ stringop_block_profile (gimple stmt, unsigned int *expected_align,
     }
 }
 
-struct value_prof_hooks {
-  /* Find list of values for which we want to measure histograms.  */
-  void (*find_values_to_profile) (histogram_values *);
-
-  /* Identify and exploit properties of values that are hard to analyze
-     statically.  See value-prof.c for more detail.  */
-  bool (*value_profile_transformations) (void);
-};
 \f
 /* Find values inside STMT for that we want to measure histograms for
    division/modulo optimization.  */
@@ -1669,7 +1691,7 @@ gimple_values_to_profile (gimple stmt, histogram_values *values)
     }
 }
 
-static void
+void
 gimple_find_values_to_profile (histogram_values *values)
 {
   basic_block bb;
@@ -1726,28 +1748,3 @@ gimple_find_values_to_profile (histogram_values *values)
     }
 }
 
-static struct value_prof_hooks gimple_value_prof_hooks = {
-  gimple_find_values_to_profile,
-  gimple_value_profile_transformations
-};
-
-void
-gimple_register_value_prof_hooks (void)
-{
-  gcc_assert (current_ir_type () == IR_GIMPLE);
-  value_prof_hooks = &gimple_value_prof_hooks;
-}
-\f
-/* IR-independent entry points.  */
-void
-find_values_to_profile (histogram_values *values)
-{
-  (value_prof_hooks->find_values_to_profile) (values);
-}
-
-bool
-value_profile_transformations (void)
-{
-  return (value_prof_hooks->value_profile_transformations) ();
-}
-\f