Commit d276406a by Martin Liska Committed by Martin Liska

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
parent 555dbc42
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
......
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. */
......
......@@ -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 *);
......
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
......
/* { 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" } } */
/* { 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] " : "");
......
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