OSDN Git Service

PR debug/43983
[pf3gnuchains/gcc-fork.git] / gcc / value-prof.c
index 9109286..0dde9bf 100644 (file)
@@ -617,7 +617,7 @@ gimple_divmod_fixed_value (gimple stmt, tree value, int prob, gcov_type count,
   e13->count = all - count;
 
   remove_edge (e23);
-  
+
   e24 = make_edge (bb2, bb4, EDGE_FALLTHRU);
   e24->probability = REG_BR_PROB_BASE;
   e24->count = count;
@@ -649,7 +649,7 @@ gimple_divmod_fixed_value_transform (gimple_stmt_iterator *si)
     return false;
 
   code = gimple_assign_rhs_code (stmt);
-  
+
   if (code != TRUNC_DIV_EXPR && code != TRUNC_MOD_EXPR)
     return false;
 
@@ -703,7 +703,7 @@ gimple_divmod_fixed_value_transform (gimple_stmt_iterator *si)
 
 /* Generate code for transformation 2 (with parent gimple assign STMT and
    probability of taking the optimal path PROB, which is equivalent to COUNT/ALL
-   within roundoff error).  This generates the result into a temp and returns 
+   within roundoff error).  This generates the result into a temp and returns
    the temp; it does not replace or alter the original STMT.  */
 static tree
 gimple_mod_pow2 (gimple stmt, int prob, gcov_type count, gcov_type all)
@@ -772,7 +772,7 @@ gimple_mod_pow2 (gimple stmt, int prob, gcov_type count, gcov_type all)
   e13->count = all - count;
 
   remove_edge (e23);
-  
+
   e24 = make_edge (bb2, bb4, EDGE_FALLTHRU);
   e24->probability = REG_BR_PROB_BASE;
   e24->count = count;
@@ -803,7 +803,7 @@ gimple_mod_pow2_value_transform (gimple_stmt_iterator *si)
     return false;
 
   code = gimple_assign_rhs_code (stmt);
-  
+
   if (code != TRUNC_MOD_EXPR || !TYPE_UNSIGNED (lhs_type))
     return false;
 
@@ -851,8 +851,8 @@ gimple_mod_pow2_value_transform (gimple_stmt_iterator *si)
    NCOUNTS the number of cases to support.  Currently only NCOUNTS==0 or 1 is
    supported and this is built into this interface.  The probabilities of taking
    the optimal paths are PROB1 and PROB2, which are equivalent to COUNT1/ALL and
-   COUNT2/ALL respectively within roundoff error).  This generates the 
-   result into a temp and returns the temp; it does not replace or alter 
+   COUNT2/ALL respectively within roundoff error).  This generates the
+   result into a temp and returns the temp; it does not replace or alter
    the original STMT.  */
 /* FIXME: Generalize the interface to handle NCOUNTS > 1.  */
 
@@ -911,7 +911,7 @@ gimple_mod_subtract (gimple stmt, int prob1, int prob2, int ncounts,
   e12 = split_block (bb, bb1end);
   bb2 = e12->dest;
   bb2->count = all - count1;
-    
+
   if (ncounts) /* Assumed to be 0 or 1.  */
     {
       e23 = split_block (bb2, bb2end);
@@ -959,7 +959,7 @@ gimple_mod_subtract_transform (gimple_stmt_iterator *si)
   histogram_value histogram;
   enum tree_code code;
   gcov_type count, wrong_values, all;
-  tree lhs_type, result, value;
+  tree lhs_type, result;
   gcov_type prob1, prob2;
   unsigned int i, steps;
   gcov_type count1, count2;
@@ -974,7 +974,7 @@ gimple_mod_subtract_transform (gimple_stmt_iterator *si)
     return false;
 
   code = gimple_assign_rhs_code (stmt);
-  
+
   if (code != TRUNC_MOD_EXPR || !TYPE_UNSIGNED (lhs_type))
     return false;
 
@@ -982,7 +982,6 @@ gimple_mod_subtract_transform (gimple_stmt_iterator *si)
   if (!histogram)
     return false;
 
-  value = histogram->hvalue.value;
   all = 0;
   wrong_values = 0;
   for (i = 0; i < histogram->hdata.intvl.steps; i++)
@@ -1051,7 +1050,7 @@ static struct cgraph_node** pid_map = NULL;
 
 /* Initialize map of pids (pid -> cgraph node) */
 
-static void 
+static void
 init_pid_map (void)
 {
   struct cgraph_node *n;
@@ -1087,7 +1086,7 @@ find_func_by_pid (int     pid)
  */
 
 static gimple
-gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call, 
+gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call,
           int prob, gcov_type count, gcov_type all)
 {
   gimple dcall_stmt, load_stmt, cond_stmt;
@@ -1107,7 +1106,7 @@ gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call,
   load_stmt = gimple_build_assign (tmpv, tmp);
   gsi_insert_before (&gsi, load_stmt, GSI_SAME_STMT);
 
-  tmp = fold_convert (optype, build_addr (direct_call->decl, 
+  tmp = fold_convert (optype, build_addr (direct_call->decl,
                                          current_function_decl));
   load_stmt = gimple_build_assign (tmp1, tmp);
   gsi_insert_before (&gsi, load_stmt, GSI_SAME_STMT);
@@ -1142,7 +1141,7 @@ gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call,
   e_ci->count = all - count;
 
   remove_edge (e_di);
-  
+
   e_dj = make_edge (dcall_bb, join_bb, EDGE_FALLTHRU);
   e_dj->probability = REG_BR_PROB_BASE;
   e_dj->count = count;
@@ -1154,8 +1153,6 @@ gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call,
   lp_nr = lookup_stmt_eh_lp (icall_stmt);
   if (lp_nr != 0)
     {
-      gimple_purge_dead_eh_edges (join_bb);
-
       if (stmt_could_throw_p (dcall_stmt))
        {
          add_stmt_to_eh_lp (dcall_stmt, lp_nr);
@@ -1164,6 +1161,9 @@ gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call,
 
       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;
@@ -1184,7 +1184,7 @@ gimple_ic_transform (gimple stmt)
   tree callee;
   gimple modify;
   struct cgraph_node *direct_call;
-  
+
   if (gimple_code (stmt) != GIMPLE_CALL)
     return false;
 
@@ -1206,7 +1206,7 @@ gimple_ic_transform (gimple stmt)
     return false;
 
   bb_all = gimple_bb (stmt)->count;
-  /* The order of CHECK_COUNTER calls is important - 
+  /* The order of CHECK_COUNTER calls is important -
      since check_counter can correct the third parameter
      and we want to make count <= all <= bb_all. */
   if ( check_counter (stmt, "ic", &all, &bb_all, bb_all)
@@ -1241,9 +1241,12 @@ gimple_ic_transform (gimple stmt)
   return true;
 }
 
-/* Return true if the stringop CALL with FNDECL shall be profiled.  */
+/* Return true if the stringop CALL with FNDECL shall be profiled.
+   SIZE_ARG be set to the argument index for the size of the string
+   operation.
+*/
 static bool
-interesting_stringop_to_profile_p (tree fndecl, gimple call)
+interesting_stringop_to_profile_p (tree fndecl, gimple call, int *size_arg)
 {
   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
 
@@ -1255,12 +1258,15 @@ interesting_stringop_to_profile_p (tree fndecl, gimple call)
     {
      case BUILT_IN_MEMCPY:
      case BUILT_IN_MEMPCPY:
+       *size_arg = 2;
        return validate_gimple_arglist (call, POINTER_TYPE, POINTER_TYPE,
                                       INTEGER_TYPE, VOID_TYPE);
      case BUILT_IN_MEMSET:
+       *size_arg = 2;
        return validate_gimple_arglist (call, POINTER_TYPE, INTEGER_TYPE,
                                      INTEGER_TYPE, VOID_TYPE);
      case BUILT_IN_BZERO:
+       *size_arg = 1;
        return validate_gimple_arglist (call, POINTER_TYPE, INTEGER_TYPE,
                                       VOID_TYPE);
      default:
@@ -1269,7 +1275,7 @@ interesting_stringop_to_profile_p (tree fndecl, gimple call)
 }
 
 /* Convert   stringop (..., vcall_size)
-   into 
+   into
    if (vcall_size == icall_size)
      stringop (..., icall_size);
    else
@@ -1285,11 +1291,17 @@ gimple_stringop_fixed_value (gimple vcall_stmt, tree icall_size, int prob,
   basic_block cond_bb, icall_bb, vcall_bb, join_bb;
   edge e_ci, e_cv, e_iv, e_ij, e_vj;
   gimple_stmt_iterator gsi;
+  tree fndecl;
+  int size_arg;
+
+  fndecl = gimple_call_fndecl (vcall_stmt);
+  if (!interesting_stringop_to_profile_p (fndecl, vcall_stmt, &size_arg))
+    gcc_unreachable();
 
   cond_bb = gimple_bb (vcall_stmt);
   gsi = gsi_for_stmt (vcall_stmt);
 
-  vcall_size = gimple_call_arg (vcall_stmt, 2);
+  vcall_size = gimple_call_arg (vcall_stmt, size_arg);
   optype = TREE_TYPE (vcall_size);
 
   tmpv = create_tmp_var (optype, "PROF");
@@ -1304,7 +1316,7 @@ gimple_stringop_fixed_value (gimple vcall_stmt, tree icall_size, int prob,
   gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
 
   icall_stmt = gimple_copy (vcall_stmt);
-  gimple_call_set_arg (icall_stmt, 2, icall_size);
+  gimple_call_set_arg (icall_stmt, size_arg, icall_size);
   gsi_insert_before (&gsi, icall_stmt, GSI_SAME_STMT);
 
   /* Fix CFG. */
@@ -1330,7 +1342,7 @@ gimple_stringop_fixed_value (gimple vcall_stmt, tree icall_size, int prob,
   e_cv->count = all - count;
 
   remove_edge (e_iv);
-  
+
   e_ij = make_edge (icall_bb, join_bb, EDGE_FALLTHRU);
   e_ij->probability = REG_BR_PROB_BASE;
   e_ij->count = count;
@@ -1354,11 +1366,11 @@ gimple_stringops_transform (gimple_stmt_iterator *gsi)
   enum built_in_function fcode;
   histogram_value histogram;
   gcov_type count, all, val;
-  tree value;
   tree dest, src;
   unsigned int dest_align, src_align;
   gcov_type prob;
   tree tree_val;
+  int size_arg;
 
   if (gimple_code (stmt) != GIMPLE_CALL)
     return false;
@@ -1366,20 +1378,16 @@ gimple_stringops_transform (gimple_stmt_iterator *gsi)
   if (!fndecl)
     return false;
   fcode = DECL_FUNCTION_CODE (fndecl);
-  if (!interesting_stringop_to_profile_p (fndecl, stmt))
+  if (!interesting_stringop_to_profile_p (fndecl, stmt, &size_arg))
     return false;
 
-  if (fcode == BUILT_IN_BZERO)
-    blck_size = gimple_call_arg (stmt, 1);
-  else
-    blck_size = gimple_call_arg (stmt, 2);
+  blck_size = gimple_call_arg (stmt, size_arg);
   if (TREE_CODE (blck_size) == INTEGER_CST)
     return false;
 
   histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_SINGLE_VALUE);
   if (!histogram)
     return false;
-  value = histogram->hvalue.value;
   val = histogram->hvalue.counters[0];
   count = histogram->hvalue.counters[1];
   all = histogram->hvalue.counters[2];
@@ -1431,7 +1439,7 @@ gimple_stringops_transform (gimple_stmt_iterator *gsi)
       print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
     }
   gimple_stringop_fixed_value (stmt, tree_val, prob, count, all);
-  
+
   return true;
 }
 
@@ -1490,7 +1498,7 @@ struct value_prof_hooks {
 
   /* Identify and exploit properties of values that are hard to analyze
      statically.  See value-prof.c for more detail.  */
-  bool (*value_profile_transformations) (void);  
+  bool (*value_profile_transformations) (void);
 };
 \f
 /* Find values inside STMT for that we want to measure histograms for
@@ -1551,8 +1559,8 @@ gimple_divmod_values_to_profile (gimple stmt, histogram_values *values)
     }
 }
 
-/* Find calls inside STMT for that we want to measure histograms for 
-   indirect/virtual call optimization. */ 
+/* Find calls inside STMT for that we want to measure histograms for
+   indirect/virtual call optimization. */
 
 static void
 gimple_indirect_call_to_profile (gimple stmt, histogram_values *values)
@@ -1567,7 +1575,7 @@ gimple_indirect_call_to_profile (gimple stmt, histogram_values *values)
 
   VEC_reserve (histogram_value, heap, *values, 3);
 
-  VEC_quick_push (histogram_value, *values, 
+  VEC_quick_push (histogram_value, *values,
                  gimple_alloc_histogram_value (cfun, HIST_TYPE_INDIR_CALL,
                                                stmt, callee));
 
@@ -1582,23 +1590,19 @@ gimple_stringops_values_to_profile (gimple stmt, histogram_values *values)
   tree fndecl;
   tree blck_size;
   tree dest;
-  enum built_in_function fcode;
+  int size_arg;
 
   if (gimple_code (stmt) != GIMPLE_CALL)
     return;
   fndecl = gimple_call_fndecl (stmt);
   if (!fndecl)
     return;
-  fcode = DECL_FUNCTION_CODE (fndecl);
 
-  if (!interesting_stringop_to_profile_p (fndecl, stmt))
+  if (!interesting_stringop_to_profile_p (fndecl, stmt, &size_arg))
     return;
 
   dest = gimple_call_arg (stmt, 0);
-  if (fcode == BUILT_IN_BZERO)
-    blck_size = gimple_call_arg (stmt, 1);
-  else
-    blck_size = gimple_call_arg (stmt, 2);
+  blck_size = gimple_call_arg (stmt, size_arg);
 
   if (TREE_CODE (blck_size) != INTEGER_CST)
     {
@@ -1641,7 +1645,7 @@ gimple_find_values_to_profile (histogram_values *values)
   FOR_EACH_BB (bb)
     for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
       gimple_values_to_profile (gsi_stmt (gsi), values);
-  
+
   for (i = 0; VEC_iterate (histogram_value, *values, i, hist); i++)
     {
       switch (hist->type)