X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fvalue-prof.c;h=84956cdbac559286c2a749a45fbc182e096b0bc4;hb=68bc9ae64c729fe49f9fa57cd1176cdb5257d7f3;hp=f3522f6dcb5036a9009ca266109dab505f2cb480;hpb=e0dc6f2bee436056af7d1c49ed2714fa53ee430d;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/value-prof.c b/gcc/value-prof.c index f3522f6dcb5..84956cdbac5 100644 --- a/gcc/value-prof.c +++ b/gcc/value-prof.c @@ -1,6 +1,6 @@ /* Transformations based on profile information for values. - Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Free Software - Foundation, Inc. + Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 + Free Software Foundation, Inc. This file is part of GCC. @@ -37,6 +37,8 @@ along with GCC; see the file COPYING3. If not see #include "tree-flow.h" #include "tree-flow-inline.h" #include "diagnostic.h" +#include "tree-pretty-print.h" +#include "gimple-pretty-print.h" #include "coverage.h" #include "tree.h" #include "gcov-io.h" @@ -384,7 +386,7 @@ visit_hist (void **slot, void *data) /* Verify sanity of the histograms. */ -void +DEBUG_FUNCTION void verify_histograms (void) { basic_block bb; @@ -464,9 +466,9 @@ check_counter (gimple stmt, const char * name, : DECL_SOURCE_LOCATION (current_function_decl); if (flag_profile_correction) { - inform ("%HCorrecting inconsistent value profile: " + inform (locus, "Correcting inconsistent value profile: " "%s profiler overall count (%d) does not match BB count " - "(%d)", &locus, name, (int)all, (int)bb_count); + "(%d)", name, (int)*all, (int)bb_count); *all = bb_count; if (*count > *all) *count = *all; @@ -474,9 +476,9 @@ check_counter (gimple stmt, const char * name, } else { - error ("%HCorrupted value profile: %s profiler overall count (%d) " - "does not match BB count (%d)", &locus, name, (int)all, - (int)bb_count); + error_at (locus, "Corrupted value profile: %s " + "profiler overall count (%d) does not match BB count (%d)", + name, (int)*all, (int)bb_count); return true; } } @@ -617,7 +619,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 +651,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; @@ -669,7 +671,7 @@ gimple_divmod_fixed_value_transform (gimple_stmt_iterator *si) at least 50% of time (and 75% gives the guarantee of usage). */ if (simple_cst_equal (gimple_assign_rhs2 (stmt), value) != 1 || 2 * count < all - || !maybe_hot_bb_p (gimple_bb (stmt))) + || optimize_bb_for_size_p (gimple_bb (stmt))) return false; if (check_counter (stmt, "value", &count, &all, gimple_bb (stmt)->count)) @@ -703,7 +705,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 +774,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 +805,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; @@ -820,7 +822,7 @@ gimple_mod_pow2_value_transform (gimple_stmt_iterator *si) /* We require that we hit a power of 2 at least half of all evaluations. */ if (simple_cst_equal (gimple_assign_rhs2 (stmt), value) != 1 || count < wrong_values - || !maybe_hot_bb_p (gimple_bb (stmt))) + || optimize_bb_for_size_p (gimple_bb (stmt))) return false; if (dump_file) @@ -851,8 +853,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 +913,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 +961,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 +976,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 +984,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++) @@ -1017,7 +1018,7 @@ gimple_mod_subtract_transform (gimple_stmt_iterator *si) break; } if (i == steps - || !maybe_hot_bb_p (gimple_bb (stmt))) + || optimize_bb_for_size_p (gimple_bb (stmt))) return false; gimple_remove_histogram_value (cfun, stmt, histogram); @@ -1051,7 +1052,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; @@ -1059,8 +1060,7 @@ init_pid_map (void) if (pid_map != NULL) return; - pid_map - = (struct cgraph_node**) xmalloc (sizeof (struct cgraph_node*) * cgraph_max_pid); + pid_map = XCNEWVEC (struct cgraph_node*, cgraph_max_pid); for (n = cgraph_nodes; n; n = n->next) { @@ -1088,85 +1088,87 @@ find_func_by_pid (int pid) */ static gimple -gimple_ic (gimple stmt, gimple call, struct cgraph_node *direct_call, +gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call, int prob, gcov_type count, gcov_type all) { - gimple stmt1, stmt2, stmt3; + gimple dcall_stmt, load_stmt, cond_stmt; tree tmp1, tmpv, tmp; - gimple bb1end, bb2end, bb3end; - basic_block bb, bb2, bb3, bb4; + basic_block cond_bb, dcall_bb, icall_bb, join_bb; tree optype = build_pointer_type (void_type_node); - edge e12, e13, e23, e24, e34; + edge e_cd, e_ci, e_di, e_dj, e_ij; gimple_stmt_iterator gsi; - int region; + int lp_nr; - bb = gimple_bb (stmt); - gsi = gsi_for_stmt (stmt); + cond_bb = gimple_bb (icall_stmt); + gsi = gsi_for_stmt (icall_stmt); tmpv = create_tmp_var (optype, "PROF"); tmp1 = create_tmp_var (optype, "PROF"); - stmt1 = gimple_build_assign (tmpv, unshare_expr (gimple_call_fn (call))); + tmp = unshare_expr (gimple_call_fn (icall_stmt)); + 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)); - stmt2 = gimple_build_assign (tmp1, tmp); - stmt3 = gimple_build_cond (NE_EXPR, tmp1, tmpv, NULL_TREE, NULL_TREE); - gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT); - gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT); - gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT); - bb1end = stmt3; + load_stmt = gimple_build_assign (tmp1, tmp); + gsi_insert_before (&gsi, load_stmt, GSI_SAME_STMT); - stmt1 = gimple_copy (stmt); - gimple_call_set_fn (stmt, - build_addr (direct_call->decl, current_function_decl)); - gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT); - bb2end = stmt1; - bb3end = stmt; + cond_stmt = gimple_build_cond (EQ_EXPR, tmp1, tmpv, NULL_TREE, NULL_TREE); + gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT); + + dcall_stmt = gimple_copy (icall_stmt); + gimple_call_set_fndecl (dcall_stmt, direct_call->decl); + gsi_insert_before (&gsi, dcall_stmt, GSI_SAME_STMT); /* Fix CFG. */ - /* Edge e23 connects bb2 to bb3, etc. */ - e12 = split_block (bb, bb1end); - bb2 = e12->dest; - bb2->count = count; - e23 = split_block (bb2, bb2end); - bb3 = e23->dest; - bb3->count = all - count; - e34 = split_block (bb3, bb3end); - bb4 = e34->dest; - bb4->count = all; + /* Edge e_cd connects cond_bb to dcall_bb, etc; note the first letters. */ + e_cd = split_block (cond_bb, cond_stmt); + dcall_bb = e_cd->dest; + dcall_bb->count = count; - e12->flags &= ~EDGE_FALLTHRU; - e12->flags |= EDGE_FALSE_VALUE; - e12->probability = prob; - e12->count = count; + e_di = split_block (dcall_bb, dcall_stmt); + icall_bb = e_di->dest; + icall_bb->count = all - count; - e13 = make_edge (bb, bb3, EDGE_TRUE_VALUE); - e13->probability = REG_BR_PROB_BASE - prob; - e13->count = all - count; + e_ij = split_block (icall_bb, icall_stmt); + join_bb = e_ij->dest; + join_bb->count = all; - remove_edge (e23); - - e24 = make_edge (bb2, bb4, EDGE_FALLTHRU); - e24->probability = REG_BR_PROB_BASE; - e24->count = count; - e34->probability = REG_BR_PROB_BASE; - e34->count = all - count; + e_cd->flags = (e_cd->flags & ~EDGE_FALLTHRU) | EDGE_TRUE_VALUE; + e_cd->probability = prob; + e_cd->count = count; + + e_ci = make_edge (cond_bb, icall_bb, EDGE_FALSE_VALUE); + e_ci->probability = REG_BR_PROB_BASE - prob; + 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; + + e_ij->probability = REG_BR_PROB_BASE; + e_ij->count = all - count; /* Fix eh edges */ - region = lookup_stmt_eh_region (stmt); - if (region >= 0 && stmt_could_throw_p (stmt1)) + lp_nr = lookup_stmt_eh_lp (icall_stmt); + if (lp_nr != 0) { - add_stmt_to_eh_region (stmt1, region); - make_eh_edges (stmt1); - } + if (stmt_could_throw_p (dcall_stmt)) + { + add_stmt_to_eh_lp (dcall_stmt, lp_nr); + make_eh_edges (dcall_stmt); + } - if (region >= 0 && stmt_could_throw_p (stmt)) - { - gimple_purge_dead_eh_edges (bb4); - make_eh_edges (stmt); + 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 stmt1; + return dcall_stmt; } /* @@ -1184,7 +1186,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 +1208,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) @@ -1222,7 +1224,7 @@ gimple_ic_transform (gimple stmt) if (direct_call == NULL) return false; - modify = gimple_ic (stmt, stmt, direct_call, prob, count, all); + modify = gimple_ic (stmt, direct_call, prob, count, all); if (dump_file) { @@ -1241,9 +1243,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 +1260,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: @@ -1268,89 +1276,85 @@ interesting_stringop_to_profile_p (tree fndecl, gimple call) } } -/* Convert stringop (..., size) - into - if (size == VALUE) - stringop (...., VALUE); +/* Convert stringop (..., vcall_size) + into + if (vcall_size == icall_size) + stringop (..., icall_size); else - stringop (...., size); - assuming constant propagation of VALUE will happen later. -*/ + stringop (..., vcall_size); + assuming we'll propagate a true constant into ICALL_SIZE later. */ + static void -gimple_stringop_fixed_value (gimple stmt, tree value, int prob, gcov_type count, - gcov_type all) +gimple_stringop_fixed_value (gimple vcall_stmt, tree icall_size, int prob, + gcov_type count, gcov_type all) { - gimple stmt1, stmt2, stmt3; - tree tmp1, tmpv; - gimple bb1end, bb2end; - basic_block bb, bb2, bb3, bb4; - edge e12, e13, e23, e24, e34; + gimple tmp_stmt, cond_stmt, icall_stmt; + tree tmp1, tmpv, vcall_size, optype; + 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 blck_size = gimple_call_arg (stmt, 2); - tree optype = TREE_TYPE (blck_size); - int region; + tree fndecl; + int size_arg; - bb = gimple_bb (stmt); - gsi = gsi_for_stmt (stmt); + fndecl = gimple_call_fndecl (vcall_stmt); + if (!interesting_stringop_to_profile_p (fndecl, vcall_stmt, &size_arg)) + gcc_unreachable(); - if (gsi_end_p (gsi)) - { - edge_iterator ei; - for (ei = ei_start (bb->succs); (e34 = ei_safe_edge (ei)); ) - if (!e34->flags & EDGE_ABNORMAL) - break; - } - else - { - e34 = split_block (bb, stmt); - gsi = gsi_for_stmt (stmt); - } - bb4 = e34->dest; + cond_bb = gimple_bb (vcall_stmt); + gsi = gsi_for_stmt (vcall_stmt); + + vcall_size = gimple_call_arg (vcall_stmt, size_arg); + optype = TREE_TYPE (vcall_size); tmpv = create_tmp_var (optype, "PROF"); tmp1 = create_tmp_var (optype, "PROF"); - stmt1 = gimple_build_assign (tmpv, fold_convert (optype, value)); - stmt2 = gimple_build_assign (tmp1, blck_size); - stmt3 = gimple_build_cond (NE_EXPR, tmp1, tmpv, NULL_TREE, NULL_TREE); - gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT); - gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT); - gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT); - bb1end = stmt3; + tmp_stmt = gimple_build_assign (tmpv, fold_convert (optype, icall_size)); + gsi_insert_before (&gsi, tmp_stmt, GSI_SAME_STMT); - stmt1 = gimple_copy (stmt); - gimple_call_set_arg (stmt1, 2, value); - gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT); - region = lookup_stmt_eh_region (stmt); - if (region >= 0) - add_stmt_to_eh_region (stmt1, region); - bb2end = stmt1; + tmp_stmt = gimple_build_assign (tmp1, vcall_size); + gsi_insert_before (&gsi, tmp_stmt, GSI_SAME_STMT); + + cond_stmt = gimple_build_cond (EQ_EXPR, tmp1, tmpv, NULL_TREE, NULL_TREE); + gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT); + + icall_stmt = gimple_copy (vcall_stmt); + gimple_call_set_arg (icall_stmt, size_arg, icall_size); + gsi_insert_before (&gsi, icall_stmt, GSI_SAME_STMT); /* Fix CFG. */ - /* Edge e23 connects bb2 to bb3, etc. */ - e12 = split_block (bb, bb1end); - bb2 = e12->dest; - bb2->count = count; - e23 = split_block (bb2, bb2end); - bb3 = e23->dest; - bb3->count = all - count; + /* Edge e_ci connects cond_bb to icall_bb, etc. */ + e_ci = split_block (cond_bb, cond_stmt); + icall_bb = e_ci->dest; + icall_bb->count = count; - e12->flags &= ~EDGE_FALLTHRU; - e12->flags |= EDGE_FALSE_VALUE; - e12->probability = prob; - e12->count = count; + e_iv = split_block (icall_bb, icall_stmt); + vcall_bb = e_iv->dest; + vcall_bb->count = all - count; - e13 = make_edge (bb, bb3, EDGE_TRUE_VALUE); - e13->probability = REG_BR_PROB_BASE - prob; - e13->count = all - count; + e_vj = split_block (vcall_bb, vcall_stmt); + join_bb = e_vj->dest; + join_bb->count = all; - remove_edge (e23); - - e24 = make_edge (bb2, bb4, EDGE_FALLTHRU); - e24->probability = REG_BR_PROB_BASE; - e24->count = count; + e_ci->flags = (e_ci->flags & ~EDGE_FALLTHRU) | EDGE_TRUE_VALUE; + e_ci->probability = prob; + e_ci->count = count; - e34->probability = REG_BR_PROB_BASE; - e34->count = all - count; + e_cv = make_edge (cond_bb, vcall_bb, EDGE_FALSE_VALUE); + e_cv->probability = REG_BR_PROB_BASE - 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; + + e_vj->probability = REG_BR_PROB_BASE; + e_vj->count = all - count; + + /* 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)); } /* Find values inside STMT for that we want to measure histograms for @@ -1364,11 +1368,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; @@ -1376,20 +1380,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]; @@ -1397,7 +1397,7 @@ gimple_stringops_transform (gimple_stmt_iterator *gsi) /* We require that count is at least half of all; this means that for the transformation to fire the value must be constant at least 80% of time. */ - if ((6 * count / 5) < all || !maybe_hot_bb_p (gimple_bb (stmt))) + if ((6 * count / 5) < all || optimize_bb_for_size_p (gimple_bb (stmt))) return false; if (check_counter (stmt, "value", &count, &all, gimple_bb (stmt)->count)) return false; @@ -1441,7 +1441,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; } @@ -1500,7 +1500,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); }; /* Find values inside STMT for that we want to measure histograms for @@ -1561,8 +1561,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) @@ -1577,7 +1577,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)); @@ -1592,23 +1592,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) { @@ -1651,8 +1647,8 @@ 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++) + + FOR_EACH_VEC_ELT (histogram_value, *values, i, hist) { switch (hist->type) {