Commit 878f99d2 by Jan Hubicka Committed by Jan Hubicka

basic-block.h (profile_staus): New global variable.

	* basic-block.h (profile_staus): New global variable.
	* cfg.c (profile_status): Declare.
	(check_bb_profile): Break out from ....; use profile_status
	(dump_flow_info): ... here.
	* cfgbuild.c (find_basic_blocks): Set profile_status.
	* cfgexpand.c (tree_expand_cfg): Likewise.
	* predict.c (estimate_probability): Likewise.
	* profile.c (branch_prob): Likewise.
	* tree-cfg.c (build_tree_cfg): Likewise.
	(dump_function_to_file): Use check_bb_profile.
	* tree-pretty-print (dump_bb_header): Likewise.
	* tree-profile.c (do_tree_profiling): Cleanup.

From-SVN: r85579
parent d4794d1a
2004-08-04 Jan Hubicka <jh@suse.cz>
* basic-block.h (profile_staus): New global variable.
* cfg.c (profile_status): Declare.
(check_bb_profile): Break out from ....; use profile_status
(dump_flow_info): ... here.
* cfgbuild.c (find_basic_blocks): Set profile_status.
* cfgexpand.c (tree_expand_cfg): Likewise.
* predict.c (estimate_probability): Likewise.
* profile.c (branch_prob): Likewise.
* tree-cfg.c (build_tree_cfg): Likewise.
(dump_function_to_file): Use check_bb_profile.
* tree-pretty-print (dump_bb_header): Likewise.
* tree-profile.c (do_tree_profiling): Cleanup.
2004-08-04 Zack Weinberg <zack@codesourcery.com> 2004-08-04 Zack Weinberg <zack@codesourcery.com>
* Makefile.in (RTL_BASE_H, RTL_H): Correct. * Makefile.in (RTL_BASE_H, RTL_H): Correct.
......
...@@ -330,6 +330,14 @@ extern int last_basic_block; ...@@ -330,6 +330,14 @@ extern int last_basic_block;
extern int n_edges; extern int n_edges;
/* Signalize the status of profile information in the CFG. */
extern enum profile_status
{
PROFILE_ABSENT,
PROFILE_GUESSED,
PROFILE_READ
} profile_status;
/* Index by basic block number, get basic block struct info. */ /* Index by basic block number, get basic block struct info. */
extern GTY(()) varray_type basic_block_info; extern GTY(()) varray_type basic_block_info;
...@@ -723,6 +731,7 @@ extern basic_block first_dom_son (enum cdi_direction, basic_block); ...@@ -723,6 +731,7 @@ extern basic_block first_dom_son (enum cdi_direction, basic_block);
extern basic_block next_dom_son (enum cdi_direction, basic_block); extern basic_block next_dom_son (enum cdi_direction, basic_block);
extern edge try_redirect_by_replacing_jump (edge, basic_block, bool); extern edge try_redirect_by_replacing_jump (edge, basic_block, bool);
extern void break_superblocks (void); extern void break_superblocks (void);
extern void check_bb_profile (basic_block, FILE *);
#include "cfghooks.h" #include "cfghooks.h"
......
...@@ -94,6 +94,9 @@ alloc_pool rbi_pool; ...@@ -94,6 +94,9 @@ alloc_pool rbi_pool;
void debug_flow_info (void); void debug_flow_info (void);
static void free_edge (edge); static void free_edge (edge);
/* Indicate the presence of the profile. */
enum profile_status profile_status;
/* Called once at initialization time. */ /* Called once at initialization time. */
...@@ -468,6 +471,53 @@ clear_bb_flags (void) ...@@ -468,6 +471,53 @@ clear_bb_flags (void)
bb->flags = 0; bb->flags = 0;
} }
/* Check the consistency of profile information. We can't do that
in verify_flow_info, as the counts may get invalid for incompletely
solved graphs, later eliminating of conditionals or roundoff errors.
It is still practical to have them reported for debugging of simple
testcases. */
void
check_bb_profile (basic_block bb, FILE * file)
{
edge e;
int sum = 0;
gcov_type lsum;
if (profile_status == PROFILE_ABSENT)
return;
if (bb != EXIT_BLOCK_PTR)
{
for (e = bb->succ; e; e = e->succ_next)
sum += e->probability;
if (bb->succ && abs (sum - REG_BR_PROB_BASE) > 100)
fprintf (file, "Invalid sum of outgoing probabilities %.1f%%\n",
sum * 100.0 / REG_BR_PROB_BASE);
lsum = 0;
for (e = bb->succ; e; e = e->succ_next)
lsum += e->count;
if (bb->succ && (lsum - bb->count > 100 || lsum - bb->count < -100))
fprintf (file, "Invalid sum of outgoing counts %i, should be %i\n",
(int) lsum, (int) bb->count);
}
if (bb != ENTRY_BLOCK_PTR)
{
sum = 0;
for (e = bb->pred; e; e = e->pred_next)
sum += EDGE_FREQUENCY (e);
if (abs (sum - bb->frequency) > 100)
fprintf (file,
"Invalid sum of incomming frequencies %i, should be %i\n",
sum, bb->frequency);
lsum = 0;
for (e = bb->pred; e; e = e->pred_next)
lsum += e->count;
if (lsum - bb->count > 100 || lsum - bb->count < -100)
fprintf (file, "Invalid sum of incomming counts %i, should be %i\n",
(int) lsum, (int) bb->count);
}
}
void void
dump_flow_info (FILE *file) dump_flow_info (FILE *file)
{ {
...@@ -527,8 +577,6 @@ dump_flow_info (FILE *file) ...@@ -527,8 +577,6 @@ dump_flow_info (FILE *file)
FOR_EACH_BB (bb) FOR_EACH_BB (bb)
{ {
edge e; edge e;
int sum;
gcov_type lsum;
fprintf (file, "\nBasic block %d ", bb->index); fprintf (file, "\nBasic block %d ", bb->index);
fprintf (file, "prev %d, next %d, ", fprintf (file, "prev %d, next %d, ",
...@@ -555,39 +603,23 @@ dump_flow_info (FILE *file) ...@@ -555,39 +603,23 @@ dump_flow_info (FILE *file)
fprintf (file, "\nRegisters live at end:"); fprintf (file, "\nRegisters live at end:");
dump_regset (bb->global_live_at_end, file); dump_regset (bb->global_live_at_end, file);
putc ('\n', file); putc ('\n', file);
/* Check the consistency of profile information. We can't do that if (bb->global_live_at_start)
in verify_flow_info, as the counts may get invalid for incompletely {
solved graphs, later eliminating of conditionals or roundoff errors. fprintf (file, "\nRegisters live at start:");
It is still practical to have them reported for debugging of simple dump_regset (bb->global_live_at_start, file);
testcases. */ }
sum = 0;
for (e = bb->succ; e; e = e->succ_next) if (bb->global_live_at_end)
sum += e->probability; {
if (bb->succ && abs (sum - REG_BR_PROB_BASE) > 100) fprintf (file, "\nRegisters live at end:");
fprintf (file, "Invalid sum of outgoing probabilities %.1f%%\n", dump_regset (bb->global_live_at_end, file);
sum * 100.0 / REG_BR_PROB_BASE); }
sum = 0;
for (e = bb->pred; e; e = e->pred_next) putc ('\n', file);
sum += EDGE_FREQUENCY (e); check_bb_profile (bb, file);
if (abs (sum - bb->frequency) > 100)
fprintf (file,
"Invalid sum of incomming frequencies %i, should be %i\n",
sum, bb->frequency);
lsum = 0;
for (e = bb->pred; e; e = e->pred_next)
lsum += e->count;
if (lsum - bb->count > 100 || lsum - bb->count < -100)
fprintf (file, "Invalid sum of incomming counts %i, should be %i\n",
(int)lsum, (int)bb->count);
lsum = 0;
for (e = bb->succ; e; e = e->succ_next)
lsum += e->count;
if (bb->succ && (lsum - bb->count > 100 || lsum - bb->count < -100))
fprintf (file, "Invalid sum of incomming counts %i, should be %i\n",
(int)lsum, (int)bb->count);
} }
putc ('\n', file); putc ('\n', file);
......
...@@ -546,6 +546,8 @@ find_basic_blocks (rtx f, int nregs ATTRIBUTE_UNUSED, ...@@ -546,6 +546,8 @@ find_basic_blocks (rtx f, int nregs ATTRIBUTE_UNUSED,
find_basic_blocks_1 (f); find_basic_blocks_1 (f);
profile_status = PROFILE_ABSENT;
/* Discover the edges of our cfg. */ /* Discover the edges of our cfg. */
make_edges (ENTRY_BLOCK_PTR->next_bb, EXIT_BLOCK_PTR->prev_bb, 0); make_edges (ENTRY_BLOCK_PTR->next_bb, EXIT_BLOCK_PTR->prev_bb, 0);
......
...@@ -433,6 +433,8 @@ tree_expand_cfg (void) ...@@ -433,6 +433,8 @@ tree_expand_cfg (void)
IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl))); IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)));
} }
profile_status = PROFILE_ABSENT;
/* Some backends want to know that we are expanding to RTL. */ /* Some backends want to know that we are expanding to RTL. */
currently_expanding_to_rtl = 1; currently_expanding_to_rtl = 1;
......
...@@ -805,6 +805,8 @@ estimate_probability (struct loops *loops_info) ...@@ -805,6 +805,8 @@ estimate_probability (struct loops *loops_info)
} }
estimate_bb_frequencies (loops_info); estimate_bb_frequencies (loops_info);
free_dominance_info (CDI_POST_DOMINATORS); free_dominance_info (CDI_POST_DOMINATORS);
if (profile_status == PROFILE_ABSENT)
profile_status = PROFILE_GUESSED;
} }
...@@ -988,6 +990,8 @@ tree_estimate_probability (void) ...@@ -988,6 +990,8 @@ tree_estimate_probability (void)
flow_loops_free (&loops_info); flow_loops_free (&loops_info);
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
dump_tree_cfg (dump_file, dump_flags); dump_tree_cfg (dump_file, dump_flags);
if (profile_status == PROFILE_ABSENT)
profile_status = PROFILE_GUESSED;
} }
/* __builtin_expect dropped tokens into the insn stream describing expected /* __builtin_expect dropped tokens into the insn stream describing expected
......
...@@ -1005,6 +1005,7 @@ branch_prob (void) ...@@ -1005,6 +1005,7 @@ branch_prob (void)
} }
free_edge_list (el); free_edge_list (el);
profile_status = PROFILE_READ;
} }
/* Union find algorithm implementation for the basic blocks using /* Union find algorithm implementation for the basic blocks using
......
...@@ -125,6 +125,7 @@ build_tree_cfg (tree *tp) ...@@ -125,6 +125,7 @@ build_tree_cfg (tree *tp)
/* Initialize the basic block array. */ /* Initialize the basic block array. */
init_flow (); init_flow ();
profile_status = PROFILE_ABSENT;
n_basic_blocks = 0; n_basic_blocks = 0;
last_basic_block = 0; last_basic_block = 0;
VARRAY_BB_INIT (basic_block_info, initial_cfg_capacity, "basic_block_info"); VARRAY_BB_INIT (basic_block_info, initial_cfg_capacity, "basic_block_info");
...@@ -4396,6 +4397,7 @@ dump_function_to_file (tree fn, FILE *file, int flags) ...@@ -4396,6 +4397,7 @@ dump_function_to_file (tree fn, FILE *file, int flags)
if (basic_block_info) if (basic_block_info)
{ {
/* Make a CFG based dump. */ /* Make a CFG based dump. */
check_bb_profile (ENTRY_BLOCK_PTR, file);
if (!ignore_topmost_bind) if (!ignore_topmost_bind)
fprintf (file, "{\n"); fprintf (file, "{\n");
...@@ -4406,6 +4408,7 @@ dump_function_to_file (tree fn, FILE *file, int flags) ...@@ -4406,6 +4408,7 @@ dump_function_to_file (tree fn, FILE *file, int flags)
dump_generic_bb (file, bb, 2, flags); dump_generic_bb (file, bb, 2, flags);
fprintf (file, "}\n"); fprintf (file, "}\n");
check_bb_profile (EXIT_BLOCK_PTR, file);
} }
else else
{ {
......
...@@ -2144,6 +2144,8 @@ dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags) ...@@ -2144,6 +2144,8 @@ dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
pp_newline (buffer); pp_newline (buffer);
} }
} }
pp_write_text_to_stream (buffer);
check_bb_profile (bb, buffer->buffer->stream);
} }
/* Dumps end of basic block BB to buffer BUFFER indented by INDENT /* Dumps end of basic block BB to buffer BUFFER indented by INDENT
......
...@@ -146,7 +146,8 @@ tree_gen_const_delta_profiler (struct histogram_value *value ATTRIBUTE_UNUSED, ...@@ -146,7 +146,8 @@ tree_gen_const_delta_profiler (struct histogram_value *value ATTRIBUTE_UNUSED,
If it is, set up hooks for tree-based profiling. If it is, set up hooks for tree-based profiling.
Gate for pass_tree_profile. */ Gate for pass_tree_profile. */
static bool do_tree_profiling (void) { static bool do_tree_profiling (void)
{
if (flag_tree_based_profiling) if (flag_tree_based_profiling)
{ {
tree_register_profile_hooks (); tree_register_profile_hooks ();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment