diff options
author | rakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-04-22 10:57:04 +0000 |
---|---|---|
committer | rakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-04-22 10:57:04 +0000 |
commit | d7683f13b72231b1f7a051374baeb8f783dd9a33 (patch) | |
tree | 3d4bc0e193a087dc3f70c67b813b2d73c8772b43 /gcc/value-prof.c | |
parent | ea10cf3db684bc1b2670f5bfddac97ba67533195 (diff) | |
download | gcc-d7683f13b72231b1f7a051374baeb8f783dd9a33.tar.gz |
* Makefile.in (LIBGCOV): Add _gcov_interval_profiler,
_gcov_pow2_profiler and _gcov_one_value_profiler.
(tree-profile.o): Add GGC_H and gt-tree-profile.h dependency.
(GTFILES): Add $(srcdir)/tree-profile.c.
* gcov-io.h (__gcov_interval_profiler, __gcov_pow2_profiler,
__gcov_one_value_profiler): Declare.
* gimplify.c (force_gimple_operand): Check whether the statements
should be produced in ssa form.
(force_gimple_operand_bsi): New function.
* libgcov.c (__gcov_interval_profiler, __gcov_pow2_profiler,
__gcov_one_value_profiler): New functions.
* rtl-profile.c (rtl_gen_pow2_profiler): Only measure whether
the profiled value is a power of two or not.
* tree-cfg.c (tree_block_ends_with_condjump_p): Handle empty blocks.
* tree-flow.h (in_ssa_p): Declare.
(force_gimple_operand_bsi): Declare.
* tree-into-ssa.c (in_ssa_p): New variable.
(rewrite_into_ssa): Set in_ssa_p.
* tree-outof-ssa.c (rewrite_out_of_ssa): Set in_ssa_p.
* tree-profile.c: Include ggc.h and gt-tree-profile.h.
(gcov_type_node, tree_interval_profiler_fn, tree_pow2_profiler_fn,
tree_one_value_profiler_fn): New variables.
(tree_init_edge_profiler): Initialize the profiler function decls.
(tree_gen_edge_profiler): Use global gcov_type_node.
(prepare_instrumented_value): New function.
(tree_gen_interval_profiler, tree_gen_interval_profiler,
tree_gen_one_value_profiler): Call the library functions instead of
creating instrumentation code.
* tree.c (build_fn_decl): New function.
* tree.h (build_fn_decl): Declare.
* value-prof.c (rtl_divmod_values_to_profile,
rtl_find_values_to_profile, rtl_mod_pow2_value_transform,
tree_mod_pow2_value_transform, tree_find_values_to_profile):
Do not handle may_be_other and precise values of exponents at pow2
profiler.
(tree_mod_subtract_transform): Reflect that value field of
histogram has changed meaning.
(tree_divmod_values_to_profile): Record the values correctly.
(tree_values_to_profile): Update comment.
* value-prof.h (struct histogram_value_t): Remove pow2 data.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@98555 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/value-prof.c')
-rw-r--r-- | gcc/value-prof.c | 113 |
1 files changed, 45 insertions, 68 deletions
diff --git a/gcc/value-prof.c b/gcc/value-prof.c index 398fdfc0ad4..4f6d0c3cf9a 100644 --- a/gcc/value-prof.c +++ b/gcc/value-prof.c @@ -128,8 +128,6 @@ static bool rtl_mod_subtract_transform (rtx); #ifdef HAVE_prefetch static bool speculative_prefetching_transform (rtx); #endif -static void tree_divmod_values_to_profile (tree, histogram_values *); -static void tree_values_to_profile (tree, histogram_values *); static tree tree_divmod_fixed_value (tree, tree, tree, tree, tree, int, gcov_type, gcov_type); static tree tree_mod_pow2 (tree, tree, tree, tree, int, gcov_type, gcov_type); @@ -181,7 +179,6 @@ rtl_divmod_values_to_profile (rtx insn, histogram_values *values) hist->hvalue.rtl.mode = mode; hist->hvalue.rtl.insn = insn; hist->type = HIST_TYPE_POW2; - hist->hdata.pow2.may_be_other = 1; VEC_safe_push (histogram_value, heap, *values, hist); } @@ -360,9 +357,7 @@ rtl_find_values_to_profile (histogram_values *values) fprintf (dump_file, "Pow2 counter for insn %d.\n", INSN_UID ((rtx)hist->hvalue.rtl.insn)); - hist->n_counters - = GET_MODE_BITSIZE (hist->hvalue.rtl.mode) - + (hist->hdata.pow2.may_be_other ? 1 : 0); + hist->n_counters = 2; break; case HIST_TYPE_SINGLE_VALUE: @@ -722,7 +717,7 @@ rtl_mod_pow2_value_transform (rtx insn) enum machine_mode mode; gcov_type wrong_values, count; edge e; - int i, all, prob; + int all, prob; set = single_set (insn); if (!set) @@ -751,15 +746,9 @@ rtl_mod_pow2_value_transform (rtx insn) histogram = XEXP (XEXP (histogram, 0), 1); value = XEXP (histogram, 0); histogram = XEXP (histogram, 1); - wrong_values =INTVAL (XEXP (histogram, 0)); + wrong_values = INTVAL (XEXP (histogram, 0)); histogram = XEXP (histogram, 1); - - count = 0; - for (i = 0; i < GET_MODE_BITSIZE (mode); i++) - { - count += INTVAL (XEXP (histogram, 0)); - histogram = XEXP (histogram, 1); - } + count = INTVAL (XEXP (histogram, 0)); if (!rtx_equal_p (op2, value)) return false; @@ -1355,7 +1344,6 @@ tree_mod_pow2_value_transform (tree stmt) gcov_type count, wrong_values, all; tree modify, op, op1, op2, result, value; int prob; - unsigned int i; modify = stmt; if (TREE_CODE (stmt) == RETURN_EXPR @@ -1386,9 +1374,7 @@ tree_mod_pow2_value_transform (tree stmt) value = histogram->hvalue.tree.value; wrong_values = histogram->hvalue.tree.counters[0]; - count = 0; - for (i = 1; i <= TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (stmt))); i++) - count += histogram->hvalue.tree.counters[i]; + count = histogram->hvalue.tree.counters[1]; /* We require that we hit a power of 2 at least half of all evaluations. */ if (simple_cst_equal (op2, value) != 1 || count < wrong_values) @@ -1576,10 +1562,6 @@ tree_mod_subtract_transform (tree stmt) wrong_values += histogram->hvalue.tree.counters[i+1]; all += wrong_values; - /* Sanity check. */ - if (simple_cst_equal (op2, value) != 1) - return false; - /* We require that we use just subtractions in at least 50% of all evaluations. */ count = 0; @@ -1638,54 +1620,53 @@ rtl_register_value_prof_hooks (void) gcc_assert (!ir_type ()); } -/* Find values inside INSN for that we want to measure histograms for +/* Find values inside STMT for that we want to measure histograms for division/modulo optimization. */ static void tree_divmod_values_to_profile (tree stmt, histogram_values *values) { - tree op, op1, op2; + tree assign, lhs, rhs, divisor, op0, type; histogram_value hist; - op = stmt; - if (TREE_CODE (stmt) == RETURN_EXPR - && TREE_OPERAND (stmt, 0) - && TREE_CODE (TREE_OPERAND (stmt, 0)) == MODIFY_EXPR) - op = TREE_OPERAND (stmt, 0); + if (TREE_CODE (stmt) == RETURN_EXPR) + assign = TREE_OPERAND (stmt, 0); + else + assign = stmt; - if (TREE_CODE (op) != MODIFY_EXPR) + if (!assign + || TREE_CODE (assign) != MODIFY_EXPR) return; - if (!INTEGRAL_TYPE_P (TREE_TYPE (op))) + lhs = TREE_OPERAND (assign, 0); + type = TREE_TYPE (lhs); + if (!INTEGRAL_TYPE_P (type)) return; - op = TREE_OPERAND (op, 1); - switch (TREE_CODE (op)) + + rhs = TREE_OPERAND (assign, 1); + switch (TREE_CODE (rhs)) { case TRUNC_DIV_EXPR: case TRUNC_MOD_EXPR: - op1 = TREE_OPERAND (op, 0); - op2 = TREE_OPERAND (op, 1); + divisor = TREE_OPERAND (rhs, 1); + op0 = TREE_OPERAND (rhs, 0); VEC_reserve (histogram_value, heap, *values, 3); - - /* Check for a special case where the divisor is power(s) of 2. - This is more aggressive than the RTL version, under the - assumption that later phases will reduce / or % by power of 2 - to something clever most of the time. Signed or unsigned. */ - if (TREE_CODE (op2) != INTEGER_CST) + + if (is_gimple_reg (divisor)) { + /* Check for a special case where the divisor is power(s) of 2. + This is more aggressive than the RTL version, under the + assumption that later phases will reduce / or % by power of 2 + to something clever most of the time. Signed or unsigned. */ hist = ggc_alloc (sizeof (*hist)); - hist->hvalue.tree.value = op2; + hist->hvalue.tree.value = divisor; hist->hvalue.tree.stmt = stmt; hist->type = HIST_TYPE_POW2; - hist->hdata.pow2.may_be_other = 1; VEC_quick_push (histogram_value, *values, hist); - } - /* Check for the case where the divisor is the same value most - of the time. */ - if (TREE_CODE (op2) != INTEGER_CST) - { + /* Check for the case where the divisor is the same value most + of the time. */ hist = ggc_alloc (sizeof (*hist)); - hist->hvalue.tree.value = op2; + hist->hvalue.tree.value = divisor; hist->hvalue.tree.stmt = stmt; hist->type = HIST_TYPE_SINGLE_VALUE; VEC_quick_push (histogram_value, *values, hist); @@ -1693,11 +1674,13 @@ tree_divmod_values_to_profile (tree stmt, histogram_values *values) /* For mod, check whether it is not often a noop (or replaceable by a few subtractions). */ - if (TREE_CODE (op) == TRUNC_MOD_EXPR && TYPE_UNSIGNED (TREE_TYPE (op))) + if (TREE_CODE (rhs) == TRUNC_MOD_EXPR + && TYPE_UNSIGNED (type)) { hist = ggc_alloc (sizeof (*hist)); hist->hvalue.tree.stmt = stmt; - hist->hvalue.tree.value = op2; + hist->hvalue.tree.value + = build2 (TRUNC_DIV_EXPR, type, op0, divisor); hist->type = HIST_TYPE_INTERVAL; hist->hdata.intvl.int_start = 0; hist->hdata.intvl.steps = 2; @@ -1710,8 +1693,9 @@ tree_divmod_values_to_profile (tree stmt, histogram_values *values) } } -/* Find values inside INSN for that we want to measure histograms and adds - them to list VALUES (increasing the record of its length in N_VALUES). */ +/* Find values inside STMT for that we want to measure histograms and adds + them to list VALUES. */ + static void tree_values_to_profile (tree stmt, histogram_values *values) { @@ -1724,17 +1708,13 @@ tree_find_values_to_profile (histogram_values *values) { basic_block bb; block_stmt_iterator bsi; - tree stmt; - unsigned int i; + unsigned i; histogram_value hist; - + *values = NULL; FOR_EACH_BB (bb) for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi)) - { - tree stmt = bsi_stmt (bsi); - tree_values_to_profile (stmt, values); - } + tree_values_to_profile (bsi_stmt (bsi), values); static_values = *values; for (i = 0; VEC_iterate (histogram_value, *values, i, hist); i++) @@ -1758,20 +1738,17 @@ tree_find_values_to_profile (histogram_values *values) case HIST_TYPE_POW2: if (dump_file) { - fprintf (dump_file, "Pow2 counter for insn "); + fprintf (dump_file, "Pow2 counter for tree "); print_generic_expr (dump_file, hist->hvalue.tree.stmt, TDF_SLIM); fprintf (dump_file, ".\n"); } - stmt = hist->hvalue.tree.stmt; - hist->n_counters - = TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (stmt))) - + (hist->hdata.pow2.may_be_other ? 1 : 0); + hist->n_counters = 2; break; case HIST_TYPE_SINGLE_VALUE: if (dump_file) { - fprintf (dump_file, "Single value counter for insn "); + fprintf (dump_file, "Single value counter for tree "); print_generic_expr (dump_file, hist->hvalue.tree.stmt, TDF_SLIM); fprintf (dump_file, ".\n"); } @@ -1781,7 +1758,7 @@ tree_find_values_to_profile (histogram_values *values) case HIST_TYPE_CONST_DELTA: if (dump_file) { - fprintf (dump_file, "Constant delta counter for insn "); + fprintf (dump_file, "Constant delta counter for tree "); print_generic_expr (dump_file, hist->hvalue.tree.stmt, TDF_SLIM); fprintf (dump_file, ".\n"); } |