summaryrefslogtreecommitdiff
path: root/gcc/rtl-profile.c
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2005-03-29 11:45:51 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2005-03-29 11:45:51 +0000
commitd297148788686526bc4f9a4b8b1bbaf0c8c96dc9 (patch)
tree06715d5d420f0cc621f0ca883cf604ecc6862320 /gcc/rtl-profile.c
parentcb09492adbe1e4187a6b9f80afdb8bc9637543b1 (diff)
downloadgcc-d297148788686526bc4f9a4b8b1bbaf0c8c96dc9.tar.gz
* Makefile.in (value-prof.o): New dependencies on $(DIAGNOSTIC_H)
$(TREE_H) and $(COVERAGE_H). * coverage.c (compute_checksum): Use DECL_NAME not DECL_ASSEMBLER_NAME. * opts.c (common_handle_option): Enable tree-based value transforms. * toplev.c (process_options): Ditto. * value-prof.h (struct histogram_value_t): Redefine. "Adjust" below refers to references to this type. * tree-flow.h: (struct stmt_ann_d): Add histograms field. * rtl-profile.c (rtl_gen_interval_profiler): Adjust. Remove checks for may_be_more, may_be_less. (rtl_gen_pow2_profiler): Adjust. (rtl_gen_one_value_profiler_no_edge_manip): Adjust. (rtl_gen_one_value_profiler): Adjust. (rtl_gen_const_delta_profiler): Adjust. * tree-profile.c (tree_gen_interval_profiler): Implement. (tree_gen_pow2_profiler): Ditto. (tree_gen_one_value_profiler): Ditto. (tree_profiling): New. (pass_tree_profile): Reference it. * value-prof.c: Include tree-flow.h, tree-flow-inline.h, diagnostic.h, tree.h, gcov-io.h. (insn_divmod_values_to_profile): Rename to rtl_divmod_values_to_profile. Adjust. (insn_values_to_profile): Rename to rtl_values_to_profile. Adjust. (insn_prefetch_values_to_profile): Adjust. (rtl_value_profile_transformations): Adjust. (gen_divmod_fixed_value): Rename to rtl_divmod_fixed_value. (gen_mod_pow2): Rename to rtl_mod_pow2. (gen_mod_subtract): Rename to rtl_mod_subtract. (divmod_fixed_value_transform): Rename to rtl_divmod_fixed_value_transform. (mod_pow2_value_transform): Rename to rtl_mod_pow2_value_transform. (mod_subtract_transform): Rename to rtl_mod_subtract_transform. (rtl_find_values_to_profile): Adjust. (tree_value_profile_transformations): Implement. (tree_divmod_values_to_profile): New. (tree_values_to_profile): New. (tree_divmod_fixed_value): New. (tree_mod_pow2): New. (tree_mod_subtract): New. (tree_divmod_fixed_value_transform): New. (tree_mod_pow2_value_transform): New. (tree_mod_subtract_transform): New. (tree_find_values_to_profile): Implement. * profile.c (instrument_values): Free histograms. (compute_value_histograms): Adjust. Implement tree version. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@97156 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/rtl-profile.c')
-rw-r--r--gcc/rtl-profile.c117
1 files changed, 39 insertions, 78 deletions
diff --git a/gcc/rtl-profile.c b/gcc/rtl-profile.c
index 3439f472b7b..b6d597103f3 100644
--- a/gcc/rtl-profile.c
+++ b/gcc/rtl-profile.c
@@ -23,30 +23,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
/* Generate basic block profile instrumentation and auxiliary files.
- Profile generation is optimized, so that not all arcs in the basic
- block graph need instrumenting. First, the BB graph is closed with
- one entry (function start), and one exit (function exit). Any
- ABNORMAL_EDGE cannot be instrumented (because there is no control
- path to place the code). We close the graph by inserting fake
- EDGE_FAKE edges to the EXIT_BLOCK, from the sources of abnormal
- edges that do not go to the exit_block. We ignore such abnormal
- edges. Naturally these fake edges are never directly traversed,
- and so *cannot* be directly instrumented. Some other graph
- massaging is done. To optimize the instrumentation we generate the
- BB minimal span tree, only edges that are not on the span tree
- (plus the entry point) need instrumenting. From that information
- all other edge counts can be deduced. By construction all fake
- edges must be on the spanning tree. We also attempt to place
- EDGE_CRITICAL edges on the spanning tree.
-
- The auxiliary file generated is <dumpbase>.bbg. The format is
- described in full in gcov-io.h. */
-
-/* ??? Register allocation should use basic block execution counts to
- give preference to the most commonly executed blocks. */
-
-/* ??? Should calculate branch probabilities before instrumenting code, since
- then we can use arc counts to help decide which arcs to instrument. */
+ RTL-based version. See profile.c for overview. */
#include "config.h"
#include "system.h"
@@ -114,33 +91,33 @@ rtl_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
rtx less_label = gen_label_rtx ();
rtx end_of_code_label = gen_label_rtx ();
int per_counter = gcov_size / BITS_PER_UNIT;
- edge e = split_block (BLOCK_FOR_INSN ((rtx)value->insn),
- PREV_INSN ((rtx)value->insn));
+ edge e = split_block (BLOCK_FOR_INSN (value->hvalue.rtl.insn),
+ PREV_INSN (value->hvalue.rtl.insn));
start_sequence ();
- if (value->seq)
- emit_insn (value->seq);
+ if (value->hvalue.rtl.seq)
+ emit_insn (value->hvalue.rtl.seq);
mr = gen_reg_rtx (Pmode);
tmp = rtl_coverage_counter_ref (tag, base);
tmp = force_reg (Pmode, XEXP (tmp, 0));
- val = expand_simple_binop (value->mode, MINUS,
- copy_rtx (value->value),
+ val = expand_simple_binop (value->hvalue.rtl.mode, MINUS,
+ copy_rtx (value->hvalue.rtl.value),
GEN_INT (value->hdata.intvl.int_start),
NULL_RTX, 0, OPTAB_WIDEN);
- if (value->hdata.intvl.may_be_more)
do_compare_rtx_and_jump (copy_rtx (val), GEN_INT (value->hdata.intvl.steps),
- GE, 0, value->mode, NULL_RTX, NULL_RTX, more_label);
- if (value->hdata.intvl.may_be_less)
- do_compare_rtx_and_jump (copy_rtx (val), const0_rtx, LT, 0, value->mode,
+ GE, 0, value->hvalue.rtl.mode, NULL_RTX, NULL_RTX,
+ more_label);
+ do_compare_rtx_and_jump (copy_rtx (val), const0_rtx, LT, 0,
+ value->hvalue.rtl.mode,
NULL_RTX, NULL_RTX, less_label);
/* We are in range. */
- tmp1 = expand_simple_binop (value->mode, MULT,
+ tmp1 = expand_simple_binop (value->hvalue.rtl.mode, MULT,
copy_rtx (val), GEN_INT (per_counter),
NULL_RTX, 0, OPTAB_WIDEN);
tmp1 = expand_simple_binop (Pmode, PLUS, copy_rtx (tmp), tmp1, mr,
@@ -148,43 +125,27 @@ rtl_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
if (tmp1 != mr)
emit_move_insn (copy_rtx (mr), tmp1);
- if (value->hdata.intvl.may_be_more
- || value->hdata.intvl.may_be_less)
- {
emit_jump_insn (gen_jump (end_of_code_label));
emit_barrier ();
- }
/* Above the interval. */
- if (value->hdata.intvl.may_be_more)
- {
emit_label (more_label);
tmp1 = expand_simple_binop (Pmode, PLUS, copy_rtx (tmp),
GEN_INT (per_counter * value->hdata.intvl.steps),
mr, 0, OPTAB_WIDEN);
if (tmp1 != mr)
emit_move_insn (copy_rtx (mr), tmp1);
- if (value->hdata.intvl.may_be_less)
- {
emit_jump_insn (gen_jump (end_of_code_label));
emit_barrier ();
- }
- }
/* Below the interval. */
- if (value->hdata.intvl.may_be_less)
- {
emit_label (less_label);
tmp1 = expand_simple_binop (Pmode, PLUS, copy_rtx (tmp),
- GEN_INT (per_counter * (value->hdata.intvl.steps
- + (value->hdata.intvl.may_be_more ? 1 : 0))),
+ GEN_INT (per_counter * (value->hdata.intvl.steps +1)),
mr, 0, OPTAB_WIDEN);
if (tmp1 != mr)
emit_move_insn (copy_rtx (mr), tmp1);
- }
- if (value->hdata.intvl.may_be_more
- || value->hdata.intvl.may_be_less)
emit_label (end_of_code_label);
mem_ref = validize_mem (gen_rtx_MEM (mode, mr));
@@ -215,32 +176,32 @@ rtl_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
rtx end_of_code_label = gen_label_rtx ();
rtx loop_label = gen_label_rtx ();
int per_counter = gcov_size / BITS_PER_UNIT;
- edge e = split_block (BLOCK_FOR_INSN ((rtx)value->insn),
- PREV_INSN ((rtx)value->insn));
+ edge e = split_block (BLOCK_FOR_INSN (value->hvalue.rtl.insn),
+ PREV_INSN (value->hvalue.rtl.insn));
start_sequence ();
- if (value->seq)
- emit_insn (value->seq);
+ if (value->hvalue.rtl.seq)
+ emit_insn (value->hvalue.rtl.seq);
mr = gen_reg_rtx (Pmode);
tmp = rtl_coverage_counter_ref (tag, base);
tmp = force_reg (Pmode, XEXP (tmp, 0));
emit_move_insn (mr, tmp);
- uval = gen_reg_rtx (value->mode);
- emit_move_insn (uval, copy_rtx (value->value));
+ uval = gen_reg_rtx (value->hvalue.rtl.mode);
+ emit_move_insn (uval, copy_rtx (value->hvalue.rtl.value));
/* Check for non-power of 2. */
if (value->hdata.pow2.may_be_other)
{
- do_compare_rtx_and_jump (copy_rtx (uval), const0_rtx, LE, 0, value->mode,
+ do_compare_rtx_and_jump (copy_rtx (uval), const0_rtx, LE, 0, value->hvalue.rtl.mode,
NULL_RTX, NULL_RTX, end_of_code_label);
- tmp = expand_simple_binop (value->mode, PLUS, copy_rtx (uval),
+ tmp = expand_simple_binop (value->hvalue.rtl.mode, PLUS, copy_rtx (uval),
constm1_rtx, NULL_RTX, 0, OPTAB_WIDEN);
- tmp = expand_simple_binop (value->mode, AND, copy_rtx (uval), tmp,
+ tmp = expand_simple_binop (value->hvalue.rtl.mode, AND, copy_rtx (uval), tmp,
NULL_RTX, 0, OPTAB_WIDEN);
- do_compare_rtx_and_jump (tmp, const0_rtx, NE, 0, value->mode, NULL_RTX,
+ do_compare_rtx_and_jump (tmp, const0_rtx, NE, 0, value->hvalue.rtl.mode, NULL_RTX,
NULL_RTX, end_of_code_label);
}
@@ -251,12 +212,12 @@ rtl_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
if (tmp != mr)
emit_move_insn (copy_rtx (mr), tmp);
- tmp = expand_simple_binop (value->mode, ASHIFTRT, copy_rtx (uval), const1_rtx,
+ tmp = expand_simple_binop (value->hvalue.rtl.mode, ASHIFTRT, copy_rtx (uval), const1_rtx,
uval, 0, OPTAB_WIDEN);
if (tmp != uval)
emit_move_insn (copy_rtx (uval), tmp);
- do_compare_rtx_and_jump (copy_rtx (uval), const0_rtx, NE, 0, value->mode,
+ do_compare_rtx_and_jump (copy_rtx (uval), const0_rtx, NE, 0, value->hvalue.rtl.mode,
NULL_RTX, NULL_RTX, loop_label);
/* Increase the counter. */
@@ -295,8 +256,8 @@ rtl_gen_one_value_profiler_no_edge_manipulation (histogram_value value,
start_sequence ();
- if (value->seq)
- emit_insn (value->seq);
+ if (value->hvalue.rtl.seq)
+ emit_insn (value->hvalue.rtl.seq);
stored_value_ref = rtl_coverage_counter_ref (tag, base);
counter_ref = rtl_coverage_counter_ref (tag, base + 1);
@@ -306,7 +267,7 @@ rtl_gen_one_value_profiler_no_edge_manipulation (histogram_value value,
all = validize_mem (all_ref);
uval = gen_reg_rtx (mode);
- convert_move (uval, copy_rtx (value->value), 0);
+ convert_move (uval, copy_rtx (value->hvalue.rtl.value), 0);
/* Check if the stored value matches. */
do_compare_rtx_and_jump (copy_rtx (uval), copy_rtx (stored_value), EQ,
@@ -362,8 +323,8 @@ rtl_gen_one_value_profiler_no_edge_manipulation (histogram_value value,
static void
rtl_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
{
- edge e = split_block (BLOCK_FOR_INSN ((rtx)value->insn),
- PREV_INSN ((rtx)value->insn));
+ edge e = split_block (BLOCK_FOR_INSN (value->hvalue.rtl.insn),
+ PREV_INSN (value->hvalue.rtl.insn));
rtx sequence = rtl_gen_one_value_profiler_no_edge_manipulation (value,
tag, base);
rebuild_jump_labels (sequence);
@@ -383,28 +344,28 @@ rtl_gen_const_delta_profiler (histogram_value value, unsigned tag, unsigned base
enum machine_mode mode = mode_for_size (gcov_size, MODE_INT, 0);
rtx stored_value_ref, stored_value, tmp, uval;
rtx sequence;
- edge e = split_block (BLOCK_FOR_INSN ((rtx)value->insn),
- PREV_INSN ((rtx)value->insn));
+ edge e = split_block (BLOCK_FOR_INSN (value->hvalue.rtl.insn),
+ PREV_INSN (value->hvalue.rtl.insn));
start_sequence ();
- if (value->seq)
- emit_insn (value->seq);
+ if (value->hvalue.rtl.seq)
+ emit_insn (value->hvalue.rtl.seq);
stored_value_ref = rtl_coverage_counter_ref (tag, base);
stored_value = validize_mem (stored_value_ref);
uval = gen_reg_rtx (mode);
- convert_move (uval, copy_rtx (value->value), 0);
+ convert_move (uval, copy_rtx (value->hvalue.rtl.value), 0);
tmp = expand_simple_binop (mode, MINUS,
copy_rtx (uval), copy_rtx (stored_value),
NULL_RTX, 0, OPTAB_WIDEN);
one_value_delta = ggc_alloc (sizeof (*one_value_delta));
- one_value_delta->value = tmp;
- one_value_delta->mode = mode;
- one_value_delta->seq = NULL_RTX;
- one_value_delta->insn = value->insn;
+ one_value_delta->hvalue.rtl.value = tmp;
+ one_value_delta->hvalue.rtl.mode = mode;
+ one_value_delta->hvalue.rtl.seq = NULL_RTX;
+ one_value_delta->hvalue.rtl.insn = value->hvalue.rtl.insn;
one_value_delta->type = HIST_TYPE_SINGLE_VALUE;
emit_insn (rtl_gen_one_value_profiler_no_edge_manipulation (one_value_delta,
tag, base + 1));