Support profile (BB counts and edge probabilities) in GIMPLE FE.
2019-05-09 Martin Liska <mliska@suse.cz> * tree-cfg.c (dump_function_to_file): Dump entry BB count. * gimple-pretty-print.c (dump_gimple_bb_header): Dump BB count. (pp_cfg_jump): Dump edge probability. * profile-count.c (profile_quality_as_string): Simplify with a static array. (parse_profile_quality): New function. (profile_count::dump): Simplify with a static array. (profile_count::from_gcov_type): Add new argument. * profile-count.h (parse_profile_quality): Likewise. * predict.h (set_hot_bb_threshold): New. * params.def (PARAM_GIMPLE_FE_COMPUTED_HOT_BB_THRESHOLD): New param. * predict.c (get_hot_bb_threshold): Set from the new param. (set_hot_bb_threshold): New. 2019-05-09 Martin Liska <mliska@suse.cz> * gimple-parser.c (struct gimple_parser): Add probability. for gimple_parser_edge. (gimple_parser::push_edge): Add new argument probability. (c_parser_gimple_parse_bb_spec): Parse also probability if present. (c_parser_parse_gimple_body): Set edge probability. (c_parser_gimple_compound_statement): Consume token before calling c_parser_gimple_goto_stmt. Parse BB counts. (c_parser_gimple_statement): Pass new argument. (c_parser_gimple_goto_stmt): Likewise. (c_parser_gimple_if_stmt): Likewise. (c_parser_gimple_or_rtl_pass_list): Parse hot_bb_threshold. * c-parser.c (c_parser_declaration_or_fndef): Pass hot_bb_threshold argument. * c-tree.h (struct c_declspecs): Add hot_bb_threshold field. (c_parser_gimple_parse_bb_spec_edge_probability): New. 2019-05-09 Martin Liska <mliska@suse.cz> * gcc.dg/gimplefe-37.c: New test. * gcc.dg/gimplefe-33.c: Likewise. From-SVN: r271034
This commit is contained in:
parent
555dbc42b2
commit
d276406ac1
|
@ -1,3 +1,21 @@
|
|||
2019-05-09 Martin Liska <mliska@suse.cz>
|
||||
|
||||
* tree-cfg.c (dump_function_to_file): Dump entry BB count.
|
||||
* gimple-pretty-print.c (dump_gimple_bb_header):
|
||||
Dump BB count.
|
||||
(pp_cfg_jump): Dump edge probability.
|
||||
* profile-count.c (profile_quality_as_string): Simplify
|
||||
with a static array.
|
||||
(parse_profile_quality): New function.
|
||||
(profile_count::dump): Simplify with a static array.
|
||||
(profile_count::from_gcov_type): Add new argument.
|
||||
* profile-count.h (parse_profile_quality): Likewise.
|
||||
* predict.h (set_hot_bb_threshold): New.
|
||||
* params.def (PARAM_GIMPLE_FE_COMPUTED_HOT_BB_THRESHOLD):
|
||||
New param.
|
||||
* predict.c (get_hot_bb_threshold): Set from the new param.
|
||||
(set_hot_bb_threshold): New.
|
||||
|
||||
2019-05-09 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/90395
|
||||
|
|
|
@ -1,3 +1,24 @@
|
|||
2019-05-09 Martin Liska <mliska@suse.cz>
|
||||
|
||||
* gimple-parser.c (struct gimple_parser): Add probability.
|
||||
for gimple_parser_edge.
|
||||
(gimple_parser::push_edge): Add new argument probability.
|
||||
(c_parser_gimple_parse_bb_spec): Parse also probability
|
||||
if present.
|
||||
(c_parser_parse_gimple_body): Set edge probability.
|
||||
(c_parser_gimple_compound_statement): Consume token
|
||||
before calling c_parser_gimple_goto_stmt.
|
||||
Parse BB counts.
|
||||
(c_parser_gimple_statement): Pass new argument.
|
||||
(c_parser_gimple_goto_stmt): Likewise.
|
||||
(c_parser_gimple_if_stmt): Likewise.
|
||||
(c_parser_gimple_or_rtl_pass_list): Parse hot_bb_threshold.
|
||||
* c-parser.c (c_parser_declaration_or_fndef): Pass
|
||||
hot_bb_threshold argument.
|
||||
* c-tree.h (struct c_declspecs): Add hot_bb_threshold
|
||||
field.
|
||||
(c_parser_gimple_parse_bb_spec_edge_probability): New.
|
||||
|
||||
2019-04-26 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR debug/90197
|
||||
|
|
|
@ -2347,7 +2347,8 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
|
|||
bool saved = in_late_binary_op;
|
||||
in_late_binary_op = true;
|
||||
c_parser_parse_gimple_body (parser, specs->gimple_or_rtl_pass,
|
||||
specs->declspec_il);
|
||||
specs->declspec_il,
|
||||
specs->entry_bb_count);
|
||||
in_late_binary_op = saved;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -317,6 +317,8 @@ struct c_declspecs {
|
|||
tree attrs;
|
||||
/* The pass to start compiling a __GIMPLE or __RTL function with. */
|
||||
char *gimple_or_rtl_pass;
|
||||
/* ENTRY BB count. */
|
||||
profile_count entry_bb_count;
|
||||
/* The base-2 log of the greatest alignment required by an _Alignas
|
||||
specifier, in bytes, or -1 if no such specifiers with nonzero
|
||||
alignment. */
|
||||
|
|
|
@ -63,6 +63,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "tree-phinodes.h"
|
||||
#include "tree-into-ssa.h"
|
||||
#include "bitmap.h"
|
||||
#include "params.h"
|
||||
|
||||
|
||||
/* GIMPLE parser state. */
|
||||
|
@ -81,20 +82,23 @@ struct gimple_parser
|
|||
int src;
|
||||
int dest;
|
||||
int flags;
|
||||
profile_probability probability;
|
||||
};
|
||||
auto_vec<gimple_parser_edge> edges;
|
||||
basic_block current_bb;
|
||||
|
||||
void push_edge (int, int, int);
|
||||
void push_edge (int, int, int, profile_probability);
|
||||
};
|
||||
|
||||
void
|
||||
gimple_parser::push_edge (int src, int dest, int flags)
|
||||
gimple_parser::push_edge (int src, int dest, int flags,
|
||||
profile_probability prob)
|
||||
{
|
||||
gimple_parser_edge e;
|
||||
e.src = src;
|
||||
e.dest = dest;
|
||||
e.flags = flags;
|
||||
e.probability = prob;
|
||||
edges.safe_push (e);
|
||||
}
|
||||
|
||||
|
@ -120,7 +124,7 @@ static void c_parser_gimple_expr_list (gimple_parser &, vec<tree> *);
|
|||
|
||||
|
||||
/* See if VAL is an identifier matching __BB<num> and return <num>
|
||||
in *INDEX. Return true if so. */
|
||||
in *INDEX. */
|
||||
|
||||
static bool
|
||||
c_parser_gimple_parse_bb_spec (tree val, int *index)
|
||||
|
@ -134,11 +138,77 @@ c_parser_gimple_parse_bb_spec (tree val, int *index)
|
|||
return *index > 0;
|
||||
}
|
||||
|
||||
/* See if VAL is an identifier matching __BB<num> and return <num>
|
||||
in *INDEX. Return true if so and parse also FREQUENCY of
|
||||
the edge. */
|
||||
|
||||
|
||||
static bool
|
||||
c_parser_gimple_parse_bb_spec_edge_probability (tree val,
|
||||
gimple_parser &parser,
|
||||
int *index,
|
||||
profile_probability *probablity)
|
||||
{
|
||||
bool return_p = c_parser_gimple_parse_bb_spec (val, index);
|
||||
if (return_p)
|
||||
{
|
||||
*probablity = profile_probability::uninitialized ();
|
||||
/* Parse frequency if provided. */
|
||||
if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
|
||||
{
|
||||
tree f;
|
||||
c_parser_consume_token (parser);
|
||||
if (!c_parser_next_token_is (parser, CPP_NAME))
|
||||
{
|
||||
c_parser_error (parser, "expected frequency quality");
|
||||
return false;
|
||||
}
|
||||
|
||||
profile_quality quality;
|
||||
const char *v
|
||||
= IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
|
||||
if (!parse_profile_quality (v, &quality))
|
||||
{
|
||||
c_parser_error (parser, "unknown profile quality");
|
||||
return false;
|
||||
}
|
||||
|
||||
c_parser_consume_token (parser);
|
||||
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
|
||||
return false;
|
||||
|
||||
if (!c_parser_next_token_is (parser, CPP_NUMBER)
|
||||
|| (TREE_CODE (f = c_parser_peek_token (parser)->value)
|
||||
!= INTEGER_CST))
|
||||
{
|
||||
c_parser_error (parser, "expected frequency value");
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int value = TREE_INT_CST_LOW (f);
|
||||
*probablity = profile_probability (value, quality);
|
||||
|
||||
c_parser_consume_token (parser);
|
||||
if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
|
||||
return false;
|
||||
|
||||
if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/* Parse the body of a function declaration marked with "__GIMPLE". */
|
||||
|
||||
void
|
||||
c_parser_parse_gimple_body (c_parser *cparser, char *gimple_pass,
|
||||
enum c_declspec_il cdil)
|
||||
enum c_declspec_il cdil,
|
||||
profile_count entry_bb_count)
|
||||
{
|
||||
gimple_parser parser (cparser);
|
||||
gimple_seq seq = NULL;
|
||||
|
@ -209,9 +279,12 @@ c_parser_parse_gimple_body (c_parser *cparser, char *gimple_pass,
|
|||
add_local_decl (cfun, var);
|
||||
/* We have a CFG. Build the edges. */
|
||||
for (unsigned i = 0; i < parser.edges.length (); ++i)
|
||||
make_edge (BASIC_BLOCK_FOR_FN (cfun, parser.edges[i].src),
|
||||
BASIC_BLOCK_FOR_FN (cfun, parser.edges[i].dest),
|
||||
parser.edges[i].flags);
|
||||
{
|
||||
edge e = make_edge (BASIC_BLOCK_FOR_FN (cfun, parser.edges[i].src),
|
||||
BASIC_BLOCK_FOR_FN (cfun, parser.edges[i].dest),
|
||||
parser.edges[i].flags);
|
||||
e->probability = parser.edges[i].probability;
|
||||
}
|
||||
/* Add edges for case labels. */
|
||||
basic_block bb;
|
||||
FOR_EACH_BB_FN (bb, cfun)
|
||||
|
@ -274,6 +347,13 @@ c_parser_parse_gimple_body (c_parser *cparser, char *gimple_pass,
|
|||
fix_loop_structure (NULL);
|
||||
}
|
||||
|
||||
if (cfun->curr_properties & PROP_cfg)
|
||||
{
|
||||
ENTRY_BLOCK_PTR_FOR_FN (cfun)->count = entry_bb_count;
|
||||
gcov_type t = PARAM_VALUE (PARAM_GIMPLE_FE_COMPUTED_HOT_BB_THRESHOLD);
|
||||
set_hot_bb_threshold (t);
|
||||
update_max_bb_count ();
|
||||
}
|
||||
dump_function (TDI_gimple, current_function_decl);
|
||||
}
|
||||
|
||||
|
@ -337,11 +417,9 @@ c_parser_gimple_compound_statement (gimple_parser &parser, gimple_seq *seq)
|
|||
c_parser_consume_token (parser);
|
||||
if (c_parser_next_token_is (parser, CPP_NAME))
|
||||
{
|
||||
c_parser_gimple_goto_stmt (parser, loc,
|
||||
c_parser_peek_token
|
||||
(parser)->value,
|
||||
seq);
|
||||
tree label = c_parser_peek_token (parser)->value;
|
||||
c_parser_consume_token (parser);
|
||||
c_parser_gimple_goto_stmt (parser, loc, label, seq);
|
||||
if (! c_parser_require (parser, CPP_SEMICOLON,
|
||||
"expected %<;%>"))
|
||||
return return_p;
|
||||
|
@ -355,7 +433,8 @@ c_parser_gimple_compound_statement (gimple_parser &parser, gimple_seq *seq)
|
|||
"expected %<;%>"))
|
||||
return return_p;
|
||||
if (cfun->curr_properties & PROP_cfg)
|
||||
parser.push_edge (parser.current_bb->index, EXIT_BLOCK, 0);
|
||||
parser.push_edge (parser.current_bb->index, EXIT_BLOCK, 0,
|
||||
profile_probability::uninitialized ());
|
||||
break;
|
||||
default:
|
||||
goto expr_stmt;
|
||||
|
@ -397,6 +476,7 @@ c_parser_gimple_compound_statement (gimple_parser &parser, gimple_seq *seq)
|
|||
return return_p;
|
||||
}
|
||||
int is_loop_header_of = -1;
|
||||
profile_count bb_count = profile_count::uninitialized ();
|
||||
c_parser_consume_token (parser);
|
||||
while (c_parser_next_token_is (parser, CPP_COMMA))
|
||||
{
|
||||
|
@ -430,10 +510,39 @@ c_parser_gimple_compound_statement (gimple_parser &parser, gimple_seq *seq)
|
|||
"expected %<)%>"))
|
||||
return return_p;
|
||||
}
|
||||
/* Parse profile: quality(value) */
|
||||
else
|
||||
{
|
||||
c_parser_error (parser, "unknown block specifier");
|
||||
return return_p;
|
||||
tree q;
|
||||
profile_quality quality;
|
||||
tree v = c_parser_peek_token (parser)->value;
|
||||
if (!parse_profile_quality (IDENTIFIER_POINTER (v),
|
||||
&quality))
|
||||
{
|
||||
c_parser_error (parser, "unknown block specifier");
|
||||
return false;
|
||||
}
|
||||
|
||||
c_parser_consume_token (parser);
|
||||
if (!c_parser_require (parser, CPP_OPEN_PAREN,
|
||||
"expected %<(%>"))
|
||||
return false;
|
||||
|
||||
if (!c_parser_next_token_is (parser, CPP_NUMBER)
|
||||
|| (TREE_CODE (q = c_parser_peek_token (parser)->value)
|
||||
!= INTEGER_CST))
|
||||
{
|
||||
c_parser_error (parser, "expected count value");
|
||||
return false;
|
||||
}
|
||||
|
||||
bb_count
|
||||
= profile_count::from_gcov_type (TREE_INT_CST_LOW (q),
|
||||
quality);
|
||||
c_parser_consume_token (parser);
|
||||
if (! c_parser_require (parser, CPP_CLOSE_PAREN,
|
||||
"expected %<)%>"))
|
||||
return return_p;
|
||||
}
|
||||
}
|
||||
if (! c_parser_require (parser, CPP_CLOSE_PAREN,
|
||||
|
@ -470,7 +579,8 @@ c_parser_gimple_compound_statement (gimple_parser &parser, gimple_seq *seq)
|
|||
last_basic_block_for_fn (cfun) = index + 1;
|
||||
n_basic_blocks_for_fn (cfun)++;
|
||||
if (!parser.current_bb)
|
||||
parser.push_edge (ENTRY_BLOCK, bb->index, EDGE_FALLTHRU);
|
||||
parser.push_edge (ENTRY_BLOCK, bb->index, EDGE_FALLTHRU,
|
||||
profile_probability::always ());
|
||||
|
||||
/* We leave the proper setting to fixup. */
|
||||
struct loop *loop_father = loops_for_fn (cfun)->tree_root;
|
||||
|
@ -498,6 +608,7 @@ c_parser_gimple_compound_statement (gimple_parser &parser, gimple_seq *seq)
|
|||
loop_father = get_loop (cfun, is_loop_header_of);
|
||||
}
|
||||
bb->loop_father = loop_father;
|
||||
bb->count = bb_count;
|
||||
|
||||
/* Stmts now go to the new block. */
|
||||
parser.current_bb = bb;
|
||||
|
@ -1609,8 +1720,10 @@ c_parser_gimple_or_rtl_pass_list (c_parser *parser, c_declspecs *specs)
|
|||
return;
|
||||
c_parser_consume_token (parser);
|
||||
|
||||
specs->entry_bb_count = profile_count::uninitialized ();
|
||||
while (c_parser_next_token_is (parser, CPP_NAME))
|
||||
{
|
||||
profile_quality quality;
|
||||
const char *op = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
|
||||
c_parser_consume_token (parser);
|
||||
if (! strcmp (op, "startwith"))
|
||||
|
@ -1629,6 +1742,26 @@ c_parser_gimple_or_rtl_pass_list (c_parser *parser, c_declspecs *specs)
|
|||
if (! c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<(%>"))
|
||||
return;
|
||||
}
|
||||
else if (parse_profile_quality (op, &quality))
|
||||
{
|
||||
tree q;
|
||||
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
|
||||
return;
|
||||
|
||||
if (!c_parser_next_token_is (parser, CPP_NUMBER)
|
||||
|| (TREE_CODE (q = c_parser_peek_token (parser)->value)
|
||||
!= INTEGER_CST))
|
||||
{
|
||||
c_parser_error (parser, "expected count value");
|
||||
return;
|
||||
}
|
||||
|
||||
specs->entry_bb_count
|
||||
= profile_count::from_gcov_type (TREE_INT_CST_LOW (q), quality);
|
||||
c_parser_consume_token (parser);
|
||||
if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
|
||||
return;
|
||||
}
|
||||
else if (specs->declspec_il != cdil_gimple)
|
||||
/* Allow only one IL specifier and none on RTL. */
|
||||
;
|
||||
|
@ -1757,10 +1890,12 @@ c_parser_gimple_goto_stmt (gimple_parser &parser,
|
|||
if (cfun->curr_properties & PROP_cfg)
|
||||
{
|
||||
int dest_index;
|
||||
if (c_parser_gimple_parse_bb_spec (label, &dest_index))
|
||||
profile_probability prob;
|
||||
if (c_parser_gimple_parse_bb_spec_edge_probability (label, parser,
|
||||
&dest_index, &prob))
|
||||
{
|
||||
parser.push_edge (parser.current_bb->index, dest_index,
|
||||
EDGE_FALLTHRU);
|
||||
EDGE_FALLTHRU, prob);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1811,10 +1946,12 @@ c_parser_gimple_if_stmt (gimple_parser &parser, gimple_seq *seq)
|
|||
label = c_parser_peek_token (parser)->value;
|
||||
c_parser_consume_token (parser);
|
||||
int dest_index;
|
||||
profile_probability prob;
|
||||
if ((cfun->curr_properties & PROP_cfg)
|
||||
&& c_parser_gimple_parse_bb_spec (label, &dest_index))
|
||||
&& c_parser_gimple_parse_bb_spec_edge_probability (label, parser,
|
||||
&dest_index, &prob))
|
||||
parser.push_edge (parser.current_bb->index, dest_index,
|
||||
EDGE_TRUE_VALUE);
|
||||
EDGE_TRUE_VALUE, prob);
|
||||
else
|
||||
t_label = lookup_label_for_goto (loc, label);
|
||||
if (! c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
|
||||
|
@ -1844,14 +1981,16 @@ c_parser_gimple_if_stmt (gimple_parser &parser, gimple_seq *seq)
|
|||
return;
|
||||
}
|
||||
label = c_parser_peek_token (parser)->value;
|
||||
c_parser_consume_token (parser);
|
||||
int dest_index;
|
||||
profile_probability prob;
|
||||
if ((cfun->curr_properties & PROP_cfg)
|
||||
&& c_parser_gimple_parse_bb_spec (label, &dest_index))
|
||||
&& c_parser_gimple_parse_bb_spec_edge_probability (label, parser,
|
||||
&dest_index, &prob))
|
||||
parser.push_edge (parser.current_bb->index, dest_index,
|
||||
EDGE_FALSE_VALUE);
|
||||
EDGE_FALSE_VALUE, prob);
|
||||
else
|
||||
f_label = lookup_label_for_goto (loc, label);
|
||||
c_parser_consume_token (parser);
|
||||
if (! c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -22,7 +22,8 @@ along with GCC; see the file COPYING3. If not see
|
|||
|
||||
/* Gimple parsing functions. */
|
||||
extern void c_parser_parse_gimple_body (c_parser *, char *,
|
||||
enum c_declspec_il);
|
||||
enum c_declspec_il,
|
||||
profile_count);
|
||||
extern void c_parser_gimple_or_rtl_pass_list (c_parser *, c_declspecs *);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2704,6 +2704,10 @@ dump_gimple_bb_header (FILE *outf, basic_block bb, int indent,
|
|||
fprintf (outf, "%*s__BB(%d", indent, "", bb->index);
|
||||
if (bb->loop_father->header == bb)
|
||||
fprintf (outf, ",loop_header(%d)", bb->loop_father->num);
|
||||
if (bb->count.initialized_p ())
|
||||
fprintf (outf, ",%s(%d)",
|
||||
profile_quality_as_string (bb->count.quality ()),
|
||||
bb->count.value ());
|
||||
fprintf (outf, "):\n");
|
||||
}
|
||||
else
|
||||
|
@ -2760,6 +2764,15 @@ pp_cfg_jump (pretty_printer *buffer, edge e, dump_flags_t flags)
|
|||
{
|
||||
pp_string (buffer, "goto __BB");
|
||||
pp_decimal_int (buffer, e->dest->index);
|
||||
if (e->probability.initialized_p ())
|
||||
{
|
||||
pp_string (buffer, "(");
|
||||
pp_string (buffer,
|
||||
profile_quality_as_string (e->probability.quality ()));
|
||||
pp_string (buffer, "(");
|
||||
pp_decimal_int (buffer, e->probability.value ());
|
||||
pp_string (buffer, "))");
|
||||
}
|
||||
pp_semicolon (buffer);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1419,6 +1419,12 @@ DEFPARAM(PARAM_LOOP_VERSIONING_MAX_OUTER_INSNS,
|
|||
" loops.",
|
||||
100, 0, 0)
|
||||
|
||||
DEFPARAM(PARAM_GIMPLE_FE_COMPUTED_HOT_BB_THRESHOLD,
|
||||
"gimple-fe-computed-hot-bb-threshold",
|
||||
"The number of executions of a basic block which is considered hot."
|
||||
" The parameters is used only in GIMPLE FE.",
|
||||
0, 0, 0)
|
||||
|
||||
/*
|
||||
|
||||
Local variables:
|
||||
|
|
|
@ -132,8 +132,8 @@ get_hot_bb_threshold ()
|
|||
{
|
||||
if (min_count == -1)
|
||||
{
|
||||
min_count
|
||||
= profile_info->sum_max / PARAM_VALUE (HOT_BB_COUNT_FRACTION);
|
||||
gcov_type t = profile_info->sum_max / PARAM_VALUE (HOT_BB_COUNT_FRACTION);
|
||||
set_hot_bb_threshold (t);
|
||||
if (dump_file)
|
||||
fprintf (dump_file, "Setting hotness threshold to %" PRId64 ".\n",
|
||||
min_count);
|
||||
|
|
|
@ -33,34 +33,57 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "wide-int.h"
|
||||
#include "sreal.h"
|
||||
|
||||
/* Names from profile_quality enum values. */
|
||||
|
||||
const char *profile_quality_names[] =
|
||||
{
|
||||
"uninitialized",
|
||||
"guessed_local",
|
||||
"guessed_global0",
|
||||
"guessed_global0adjusted",
|
||||
"guessed",
|
||||
"afdo",
|
||||
"adjusted",
|
||||
"precise"
|
||||
};
|
||||
|
||||
/* Get a string describing QUALITY. */
|
||||
|
||||
const char *
|
||||
profile_quality_as_string (enum profile_quality quality)
|
||||
{
|
||||
switch (quality)
|
||||
{
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
case profile_uninitialized:
|
||||
return "uninitialized";
|
||||
case profile_guessed_local:
|
||||
return "guessed_local";
|
||||
case profile_guessed_global0:
|
||||
return "guessed_global0";
|
||||
case profile_guessed_global0adjusted:
|
||||
return "guessed_global0adjusted";
|
||||
case profile_guessed:
|
||||
return "guessed";
|
||||
case profile_afdo:
|
||||
return "afdo";
|
||||
case profile_adjusted:
|
||||
return "adjusted";
|
||||
case profile_precise:
|
||||
return "precise";
|
||||
}
|
||||
return profile_quality_names[quality];
|
||||
}
|
||||
|
||||
/* Parse VALUE as profile quality and return true when a valid QUALITY. */
|
||||
|
||||
bool
|
||||
parse_profile_quality (const char *value, profile_quality *quality)
|
||||
{
|
||||
for (unsigned i = 0; i < ARRAY_SIZE (profile_quality_names); i++)
|
||||
if (strcmp (profile_quality_names[i], value) == 0)
|
||||
{
|
||||
*quality = (profile_quality)i;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Display names from profile_quality enum values. */
|
||||
|
||||
const char *profile_quality_display_names[] =
|
||||
{
|
||||
NULL,
|
||||
"estimated locally",
|
||||
"estimated locally, globally 0",
|
||||
"estimated locally, globally 0 adjusted",
|
||||
"adjusted",
|
||||
"auto FDO",
|
||||
"guessed",
|
||||
"precise"
|
||||
};
|
||||
|
||||
/* Dump THIS to F. */
|
||||
|
||||
void
|
||||
|
@ -69,23 +92,8 @@ profile_count::dump (FILE *f) const
|
|||
if (!initialized_p ())
|
||||
fprintf (f, "uninitialized");
|
||||
else
|
||||
{
|
||||
fprintf (f, "%" PRId64, m_val);
|
||||
if (m_quality == profile_guessed_local)
|
||||
fprintf (f, " (estimated locally)");
|
||||
else if (m_quality == profile_guessed_global0)
|
||||
fprintf (f, " (estimated locally, globally 0)");
|
||||
else if (m_quality == profile_guessed_global0adjusted)
|
||||
fprintf (f, " (estimated locally, globally 0 adjusted)");
|
||||
else if (m_quality == profile_adjusted)
|
||||
fprintf (f, " (adjusted)");
|
||||
else if (m_quality == profile_afdo)
|
||||
fprintf (f, " (auto FDO)");
|
||||
else if (m_quality == profile_guessed)
|
||||
fprintf (f, " (guessed)");
|
||||
else if (m_quality == profile_precise)
|
||||
fprintf (f, " (precise)");
|
||||
}
|
||||
fprintf (f, "%" PRId64 " (%s)", m_val,
|
||||
profile_quality_display_names[m_quality]);
|
||||
}
|
||||
|
||||
/* Dump THIS to stderr. */
|
||||
|
@ -362,7 +370,7 @@ profile_count::combine_with_ipa_count (profile_count ipa)
|
|||
Conversions back and forth are used to read the coverage and get it
|
||||
into internal representation. */
|
||||
profile_count
|
||||
profile_count::from_gcov_type (gcov_type v)
|
||||
profile_count::from_gcov_type (gcov_type v, profile_quality quality)
|
||||
{
|
||||
profile_count ret;
|
||||
gcc_checking_assert (v >= 0);
|
||||
|
@ -371,7 +379,7 @@ profile_count::from_gcov_type (gcov_type v)
|
|||
"Capping gcov count %" PRId64 " to max_count %" PRId64 "\n",
|
||||
(int64_t) v, (int64_t) max_count);
|
||||
ret.m_val = MIN (v, (gcov_type)max_count);
|
||||
ret.m_quality = profile_precise;
|
||||
ret.m_quality = quality;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -60,6 +60,8 @@ enum profile_quality {
|
|||
};
|
||||
|
||||
extern const char *profile_quality_as_string (enum profile_quality);
|
||||
extern bool parse_profile_quality (const char *value,
|
||||
profile_quality *quality);
|
||||
|
||||
/* The base value for branch probability notes and edge probabilities. */
|
||||
#define REG_BR_PROB_BASE 10000
|
||||
|
@ -149,6 +151,13 @@ class GTY((user)) profile_probability
|
|||
|
||||
friend class profile_count;
|
||||
public:
|
||||
profile_probability (): m_val (uninitialized_probability),
|
||||
m_quality (profile_guessed)
|
||||
{}
|
||||
|
||||
profile_probability (uint32_t val, profile_quality quality):
|
||||
m_val (val), m_quality (quality)
|
||||
{}
|
||||
|
||||
/* Named probabilities. */
|
||||
static profile_probability never ()
|
||||
|
@ -558,6 +567,12 @@ public:
|
|||
return initialized_p () && other.initialized_p () && m_val >= other.m_val;
|
||||
}
|
||||
|
||||
/* Get the value of the count. */
|
||||
uint32_t value () const { return m_val; }
|
||||
|
||||
/* Get the quality of the count. */
|
||||
enum profile_quality quality () const { return m_quality; }
|
||||
|
||||
/* Output THIS to F. */
|
||||
void dump (FILE *f) const;
|
||||
|
||||
|
@ -675,7 +690,6 @@ private:
|
|||
return ipa_p () == other.ipa_p ();
|
||||
}
|
||||
public:
|
||||
|
||||
/* Used for counters which are expected to be never executed. */
|
||||
static profile_count zero ()
|
||||
{
|
||||
|
@ -737,6 +751,9 @@ public:
|
|||
return m_quality == profile_precise;
|
||||
}
|
||||
|
||||
/* Get the value of the count. */
|
||||
uint32_t value () const { return m_val; }
|
||||
|
||||
/* Get the quality of the count. */
|
||||
enum profile_quality quality () const { return m_quality; }
|
||||
|
||||
|
@ -1136,7 +1153,8 @@ public:
|
|||
/* The profiling runtime uses gcov_type, which is usually 64bit integer.
|
||||
Conversions back and forth are used to read the coverage and get it
|
||||
into internal representation. */
|
||||
static profile_count from_gcov_type (gcov_type v);
|
||||
static profile_count from_gcov_type (gcov_type v,
|
||||
profile_quality quality = profile_precise);
|
||||
|
||||
/* LTO streaming support. */
|
||||
static profile_count stream_in (struct lto_input_block *);
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2019-05-09 Martin Liska <mliska@suse.cz>
|
||||
|
||||
* gcc.dg/gimplefe-37.c: New test.
|
||||
* gcc.dg/gimplefe-33.c: Likewise.
|
||||
|
||||
2019-05-09 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR c++/90382
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -fgimple -fdump-tree-optimized --param=gimple-fe-computed-hot-bb-threshold=10 " } */
|
||||
|
||||
int __GIMPLE (ssa,startwith("slsr"),precise(3))
|
||||
main (int argc)
|
||||
{
|
||||
int _1;
|
||||
|
||||
__BB(2,precise(3)):
|
||||
if (argc_2(D) == 2)
|
||||
goto __BB3(precise(44739243));
|
||||
else
|
||||
goto __BB4(precise(89478485));
|
||||
|
||||
__BB(3,precise(1)):
|
||||
goto __BB4(precise(134217728));
|
||||
|
||||
__BB(4,precise(3)):
|
||||
_1 = __PHI (__BB2: 0, __BB3: 12);
|
||||
return _1;
|
||||
}
|
||||
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "<bb \[0-9\]> \\\[count: 3" 2 "optimized" } } */
|
||||
/* { dg-final { scan-tree-dump-times "<bb \[0-9\]> \\\[count: 2" 1 "optimized" } } */
|
||||
/* { dg-final { scan-tree-dump-times "goto <bb \[0-9\]>; \\\[33\\\.33%\\\]" 1 "optimized" } } */
|
||||
/* { dg-final { scan-tree-dump-times "goto <bb \[0-9\]>; \\\[66\\\.67%\\\]" 1 "optimized" } } */
|
|
@ -0,0 +1,27 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -fgimple -fdump-tree-slsr" } */
|
||||
|
||||
int __GIMPLE (ssa,startwith("slsr"),guessed_local(1073741824))
|
||||
main (int argc)
|
||||
{
|
||||
int _1;
|
||||
|
||||
__BB(2,guessed_local(1073741824)):
|
||||
if (argc_2(D) == 2)
|
||||
goto __BB3(guessed(16777216));
|
||||
else
|
||||
goto __BB4(guessed(117440512));
|
||||
|
||||
__BB(3,guessed_local(134217728)):
|
||||
goto __BB4(precise(134217728));
|
||||
|
||||
__BB(4,guessed_local(1073741824)):
|
||||
_1 = __PHI (__BB2: 0, __BB3: 12);
|
||||
return _1;
|
||||
}
|
||||
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "<bb \[0-9\]> \\\[local count: 1073741824" 2 "slsr" } } */
|
||||
/* { dg-final { scan-tree-dump-times "<bb \[0-9\]> \\\[local count: 134217728" 1 "slsr" } } */
|
||||
/* { dg-final { scan-tree-dump-times "goto <bb \[0-9\]>; \\\[12\\\.50%\\\]" 1 "slsr" } } */
|
||||
/* { dg-final { scan-tree-dump-times "goto <bb \[0-9\]>; \\\[87\\\.50%\\\]" 1 "slsr" } } */
|
|
@ -62,6 +62,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "selftest.h"
|
||||
#include "opts.h"
|
||||
#include "asan.h"
|
||||
#include "profile.h"
|
||||
|
||||
/* This file contains functions for building the Control Flow Graph (CFG)
|
||||
for a function tree. */
|
||||
|
@ -7872,13 +7873,32 @@ dump_function_to_file (tree fndecl, FILE *file, dump_flags_t flags)
|
|||
current_function_decl = fndecl;
|
||||
if (flags & TDF_GIMPLE)
|
||||
{
|
||||
static bool hotness_bb_param_printed = false;
|
||||
if (profile_info != NULL
|
||||
&& !hotness_bb_param_printed)
|
||||
{
|
||||
hotness_bb_param_printed = true;
|
||||
fprintf (file,
|
||||
"/* --param=gimple-fe-computed-hot-bb-threshold=%" PRId64
|
||||
" */\n", get_hot_bb_threshold ());
|
||||
}
|
||||
|
||||
print_generic_expr (file, TREE_TYPE (TREE_TYPE (fndecl)),
|
||||
dump_flags | TDF_SLIM);
|
||||
fprintf (file, " __GIMPLE (%s)\n%s (",
|
||||
fprintf (file, " __GIMPLE (%s",
|
||||
(fun->curr_properties & PROP_ssa) ? "ssa"
|
||||
: (fun->curr_properties & PROP_cfg) ? "cfg"
|
||||
: "",
|
||||
function_name (fun));
|
||||
: "");
|
||||
|
||||
if (cfun->cfg)
|
||||
{
|
||||
basic_block bb = ENTRY_BLOCK_PTR_FOR_FN (cfun);
|
||||
if (bb->count.initialized_p ())
|
||||
fprintf (file, ",%s(%d)",
|
||||
profile_quality_as_string (bb->count.quality ()),
|
||||
bb->count.value ());
|
||||
fprintf (file, ")\n%s (", function_name (fun));
|
||||
}
|
||||
}
|
||||
else
|
||||
fprintf (file, "%s %s(", function_name (fun), tmclone ? "[tm-clone] " : "");
|
||||
|
|
Loading…
Reference in New Issue