* [PATCH][stage1] Support profile (BB counts and edge probabilities) in GIMPLE FE.
@ 2019-04-05 12:32 Martin Liška
2019-04-08 9:11 ` Richard Biener
0 siblings, 1 reply; 22+ messages in thread
From: Martin Liška @ 2019-04-05 12:32 UTC (permalink / raw)
To: gcc-patches; +Cc: Richard Biener
[-- Attachment #1: Type: text/plain, Size: 1462 bytes --]
Hi.
The patch adds support for profile for GIMPLE FE. That can be useful
in the future.
Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
Ready to be installed after stage1 opens?
Thanks,
Martin
gcc/ChangeLog:
2019-04-05 Martin Liska <mliska@suse.cz>
* gimple-pretty-print.c (dump_gimple_bb_header):
Dump BB count.
(pp_cfg_jump): Dump edge probability.
* profile-count.h (get_raw_value): New function.
(from_raw_value): Likewise.
gcc/c/ChangeLog:
2019-04-05 Martin Liska <mliska@suse.cz>
* gimple-parser.c (struct gimple_parser): Add frequency
for gimple_parser_edge.
(gimple_parser::push_edge): Add new argument frequency.
(c_parser_gimple_parse_bb_spec): Parse also frequency
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.
gcc/testsuite/ChangeLog:
2019-04-05 Martin Liska <mliska@suse.cz>
* gcc.dg/gimplefe-37.c: New test.
---
gcc/c/gimple-parser.c | 116 +++++++++++++++++++++++------
gcc/gimple-pretty-print.c | 8 ++
gcc/profile-count.h | 15 ++++
gcc/testsuite/gcc.dg/gimplefe-37.c | 27 +++++++
4 files changed, 144 insertions(+), 22 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/gimplefe-37.c
[-- Attachment #2: 0001-Support-profile-BB-counts-and-edge-probabilities-in-.patch --]
[-- Type: text/x-patch, Size: 11367 bytes --]
diff --git a/gcc/c/gimple-parser.c b/gcc/c/gimple-parser.c
index fff34606dae..082f84de3ac 100644
--- a/gcc/c/gimple-parser.c
+++ b/gcc/c/gimple-parser.c
@@ -81,20 +81,22 @@ struct gimple_parser
int src;
int dest;
int flags;
+ int frequency;
};
auto_vec<gimple_parser_edge> edges;
basic_block current_bb;
- void push_edge (int, int, int);
+ void push_edge (int, int, int, int);
};
void
-gimple_parser::push_edge (int src, int dest, int flags)
+gimple_parser::push_edge (int src, int dest, int flags, int frequency)
{
gimple_parser_edge e;
e.src = src;
e.dest = dest;
e.flags = flags;
+ e.frequency = frequency;
edges.safe_push (e);
}
@@ -120,10 +122,12 @@ 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. Return true if so and parse also FREQUENCY of
+ the edge. */
static bool
-c_parser_gimple_parse_bb_spec (tree val, int *index)
+c_parser_gimple_parse_bb_spec (tree val, gimple_parser &parser,
+ int *index, int *frequency)
{
if (strncmp (IDENTIFIER_POINTER (val), "__BB", 4) != 0)
return false;
@@ -131,7 +135,33 @@ c_parser_gimple_parse_bb_spec (tree val, int *index)
if (!ISDIGIT (*p))
return false;
*index = atoi (IDENTIFIER_POINTER (val) + 4);
- return *index > 0;
+
+ if (*index > 0)
+ {
+ *frequency = -1;
+ /* 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_NUMBER)
+ || (TREE_CODE (f = c_parser_peek_token (parser)->value)
+ != INTEGER_CST))
+ {
+ c_parser_error (parser, "expected frequency value");
+ return false;
+ }
+
+ *frequency = TREE_INT_CST_LOW (f);
+ c_parser_consume_token (parser);
+ 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". */
@@ -209,9 +239,14 @@ 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);
+ if (parser.edges[i].frequency != -1)
+ e->probability
+ = profile_probability::from_raw_value (parser.edges[i].frequency);
+ }
/* Add edges for case labels. */
basic_block bb;
FOR_EACH_BB_FN (bb, cfun)
@@ -274,6 +309,8 @@ c_parser_parse_gimple_body (c_parser *cparser, char *gimple_pass,
fix_loop_structure (NULL);
}
+ if (cfun->curr_properties & PROP_cfg)
+ update_max_bb_count ();
dump_function (TDI_gimple, current_function_decl);
}
@@ -337,11 +374,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 +390,7 @@ 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, -1);
break;
default:
goto expr_stmt;
@@ -397,6 +432,7 @@ c_parser_gimple_compound_statement (gimple_parser &parser, gimple_seq *seq)
return return_p;
}
int is_loop_header_of = -1;
+ int bb_count = -1;
c_parser_consume_token (parser);
while (c_parser_next_token_is (parser, CPP_COMMA))
{
@@ -430,6 +466,30 @@ c_parser_gimple_compound_statement (gimple_parser &parser, gimple_seq *seq)
"expected %<)%>"))
return return_p;
}
+ /* count (NUM) */
+ else if (!strcmp (IDENTIFIER_POINTER
+ (c_parser_peek_token (parser)->value),
+ "count"))
+ {
+ c_parser_consume_token (parser);
+ if (! c_parser_require (parser, CPP_OPEN_PAREN,
+ "expected %<(%>"))
+ return return_p;
+ tree count;
+ if (! c_parser_next_token_is (parser, CPP_NUMBER)
+ || TREE_CODE (count
+ = c_parser_peek_token (parser)->value)
+ != INTEGER_CST)
+ {
+ c_parser_error (parser, "expected count value");
+ return return_p;
+ }
+ c_parser_consume_token (parser);
+ bb_count = TREE_INT_CST_LOW (count);
+ if (! c_parser_require (parser, CPP_CLOSE_PAREN,
+ "expected %<)%>"))
+ return return_p;
+ }
else
{
c_parser_error (parser, "unknown block specifier");
@@ -470,7 +530,7 @@ 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, -1);
/* We leave the proper setting to fixup. */
struct loop *loop_father = loops_for_fn (cfun)->tree_root;
@@ -499,6 +559,10 @@ c_parser_gimple_compound_statement (gimple_parser &parser, gimple_seq *seq)
}
bb->loop_father = loop_father;
+ if (bb_count != -1)
+ bb->count
+ = profile_count::from_gcov_type (bb_count).guessed_local ();
+
/* Stmts now go to the new block. */
parser.current_bb = bb;
break;
@@ -688,7 +752,9 @@ c_parser_gimple_statement (gimple_parser &parser, gimple_seq *seq)
if (c_parser_next_token_is (parser, CPP_COLON))
c_parser_consume_token (parser);
int src_index = -1;
- if (!c_parser_gimple_parse_bb_spec (arg, &src_index))
+ int frequency;
+ if (!c_parser_gimple_parse_bb_spec (arg, parser, &src_index,
+ &frequency))
c_parser_error (parser, "invalid source block specification");
vargs.safe_push (size_int (src_index));
}
@@ -1757,10 +1823,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))
+ int frequency;
+ if (c_parser_gimple_parse_bb_spec (label, parser, &dest_index,
+ &frequency))
{
parser.push_edge (parser.current_bb->index, dest_index,
- EDGE_FALLTHRU);
+ EDGE_FALLTHRU, frequency);
return;
}
}
@@ -1811,10 +1879,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;
+ int frequency;
if ((cfun->curr_properties & PROP_cfg)
- && c_parser_gimple_parse_bb_spec (label, &dest_index))
+ && c_parser_gimple_parse_bb_spec (label, parser, &dest_index,
+ &frequency))
parser.push_edge (parser.current_bb->index, dest_index,
- EDGE_TRUE_VALUE);
+ EDGE_TRUE_VALUE, frequency);
else
t_label = lookup_label_for_goto (loc, label);
if (! c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
@@ -1844,14 +1914,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;
+ int frequency;
if ((cfun->curr_properties & PROP_cfg)
- && c_parser_gimple_parse_bb_spec (label, &dest_index))
+ && c_parser_gimple_parse_bb_spec (label, parser, &dest_index,
+ &frequency))
parser.push_edge (parser.current_bb->index, dest_index,
- EDGE_FALSE_VALUE);
+ EDGE_FALSE_VALUE, frequency);
else
f_label = lookup_label_for_goto (loc, label);
- c_parser_consume_token (parser);
if (! c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
return;
}
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index 69bae0d10d0..b5fca58aa07 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -2704,6 +2704,8 @@ 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, ",count(%" PRId64 ")", bb->count.to_gcov_type ());
fprintf (outf, "):\n");
}
else
@@ -2760,6 +2762,12 @@ 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_decimal_int (buffer, e->probability.get_raw_value ());
+ pp_string (buffer, ")");
+ }
pp_semicolon (buffer);
}
else
diff --git a/gcc/profile-count.h b/gcc/profile-count.h
index d6de61f0a61..8d978e14e00 100644
--- a/gcc/profile-count.h
+++ b/gcc/profile-count.h
@@ -564,6 +564,21 @@ public:
/* Print THIS to stderr. */
void debug () const;
+ /* Get m_val for GIMPLE FE. */
+ uint32_t get_raw_value () const
+ {
+ return m_val;
+ }
+
+ /* Build guessed profiled based on VALUE (in GIMPLE FE). */
+ static profile_probability from_raw_value (uint32_t value)
+ {
+ profile_probability ret;
+ ret.m_val = value;
+ ret.m_quality = profile_guessed;
+ return ret;
+ }
+
/* Return true if THIS is known to differ significantly from OTHER. */
bool differs_from_p (profile_probability other) const;
/* Return if difference is greater than 50%. */
diff --git a/gcc/testsuite/gcc.dg/gimplefe-37.c b/gcc/testsuite/gcc.dg/gimplefe-37.c
new file mode 100644
index 00000000000..2872eb03051
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gimplefe-37.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fgimple -fdump-tree-optimized" } */
+
+int __GIMPLE (ssa,startwith("slsr"))
+main (int argc)
+{
+ int _1;
+
+ __BB(2,count(3)):
+ if (argc_2(D) == 2)
+ goto __BB3(44739243);
+ else
+ goto __BB4(89478485);
+
+ __BB(3,count(1)):
+ goto __BB4(134217728);
+
+ __BB(4,count(3)):
+ _1 = __PHI (__BB2: 0, __BB3: 12);
+ return _1;
+}
+
+
+/* { dg-final { scan-tree-dump-times "<bb \[0-9\]> \\\[local count: 3" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "<bb \[0-9\]> \\\[local 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" } } */
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH][stage1] Support profile (BB counts and edge probabilities) in GIMPLE FE.
2019-04-05 12:32 [PATCH][stage1] Support profile (BB counts and edge probabilities) in GIMPLE FE Martin Liška
@ 2019-04-08 9:11 ` Richard Biener
2019-04-08 13:35 ` Martin Liška
0 siblings, 1 reply; 22+ messages in thread
From: Richard Biener @ 2019-04-08 9:11 UTC (permalink / raw)
To: Martin Liška, Jan Hubicka; +Cc: GCC Patches
On Fri, Apr 5, 2019 at 2:32 PM Martin Liška <mliska@suse.cz> wrote:
>
> Hi.
>
> The patch adds support for profile for GIMPLE FE. That can be useful
> in the future.
>
> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
>
> Ready to be installed after stage1 opens?
Hmm, I guess to be useful we need the profile quality indicators as well
(and think about a proper syntax here since it seems related).
Btw, do BB counts and edge probabilities not have a relation? If so why
do we need both? In predict.c we also look at ENTRY_BLOCK->count
so we need a place to set that as well. We should probably set
edge probabilities of fallthru edges properly during our "CFG build".
+ goto __BB3(44739243);
since we eventually want to add other flags this syntactically
should maybe be goto __BB3(guessed(44739243)); and similar
for the __BB count case (just s/count/quality/).
The entry block count could be sticked to __GIMPLE (ssa,guessed(N))
for example. There's also the exit block, not sure if we ever look at
its count, so __GIMPLE (ssa,guessed(N[,M])) might be a possibility
if we always have the same quality here (probably not...).
Otherwise thanks for trying ;)
Richard.
> Thanks,
> Martin
>
> gcc/ChangeLog:
>
> 2019-04-05 Martin Liska <mliska@suse.cz>
>
> * gimple-pretty-print.c (dump_gimple_bb_header):
> Dump BB count.
> (pp_cfg_jump): Dump edge probability.
> * profile-count.h (get_raw_value): New function.
> (from_raw_value): Likewise.
>
> gcc/c/ChangeLog:
>
> 2019-04-05 Martin Liska <mliska@suse.cz>
>
> * gimple-parser.c (struct gimple_parser): Add frequency
> for gimple_parser_edge.
> (gimple_parser::push_edge): Add new argument frequency.
> (c_parser_gimple_parse_bb_spec): Parse also frequency
> 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.
>
> gcc/testsuite/ChangeLog:
>
> 2019-04-05 Martin Liska <mliska@suse.cz>
>
> * gcc.dg/gimplefe-37.c: New test.
> ---
> gcc/c/gimple-parser.c | 116 +++++++++++++++++++++++------
> gcc/gimple-pretty-print.c | 8 ++
> gcc/profile-count.h | 15 ++++
> gcc/testsuite/gcc.dg/gimplefe-37.c | 27 +++++++
> 4 files changed, 144 insertions(+), 22 deletions(-)
> create mode 100644 gcc/testsuite/gcc.dg/gimplefe-37.c
>
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH][stage1] Support profile (BB counts and edge probabilities) in GIMPLE FE.
2019-04-08 9:11 ` Richard Biener
@ 2019-04-08 13:35 ` Martin Liška
2019-04-09 13:15 ` Martin Liška
0 siblings, 1 reply; 22+ messages in thread
From: Martin Liška @ 2019-04-08 13:35 UTC (permalink / raw)
To: Richard Biener, Jan Hubicka; +Cc: GCC Patches
On 4/8/19 11:11 AM, Richard Biener wrote:
> On Fri, Apr 5, 2019 at 2:32 PM Martin Liška <mliska@suse.cz> wrote:
>>
>> Hi.
>>
>> The patch adds support for profile for GIMPLE FE. That can be useful
>> in the future.
>>
>> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
>>
>> Ready to be installed after stage1 opens?
>
> Hmm, I guess to be useful we need the profile quality indicators as well
> (and think about a proper syntax here since it seems related).
I wanted to make it easy, buy yes. We should implement that.
>
> Btw, do BB counts and edge probabilities not have a relation?
Yes, they should match. But you have optimizations that make some discrepancies.
So that I would implement support for both of them.
> If so why
> do we need both? In predict.c we also look at ENTRY_BLOCK->count
> so we need a place to set that as well. We should probably set
> edge probabilities of fallthru edges properly during our "CFG build".
>
> + goto __BB3(44739243);
>
> since we eventually want to add other flags this syntactically
> should maybe be goto __BB3(guessed(44739243)); and similar
> for the __BB count case (just s/count/quality/).
The syntax works for me.
>
> The entry block count could be sticked to __GIMPLE (ssa,guessed(N))
> for example. There's also the exit block, not sure if we ever look at
> its count, so __GIMPLE (ssa,guessed(N[,M])) might be a possibility
> if we always have the same quality here (probably not...).
I'll check it.
>
> Otherwise thanks for trying ;)
>
> Richard.
>
>> Thanks,
>> Martin
>>
>> gcc/ChangeLog:
>>
>> 2019-04-05 Martin Liska <mliska@suse.cz>
>>
>> * gimple-pretty-print.c (dump_gimple_bb_header):
>> Dump BB count.
>> (pp_cfg_jump): Dump edge probability.
>> * profile-count.h (get_raw_value): New function.
>> (from_raw_value): Likewise.
>>
>> gcc/c/ChangeLog:
>>
>> 2019-04-05 Martin Liska <mliska@suse.cz>
>>
>> * gimple-parser.c (struct gimple_parser): Add frequency
>> for gimple_parser_edge.
>> (gimple_parser::push_edge): Add new argument frequency.
>> (c_parser_gimple_parse_bb_spec): Parse also frequency
>> 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.
>>
>> gcc/testsuite/ChangeLog:
>>
>> 2019-04-05 Martin Liska <mliska@suse.cz>
>>
>> * gcc.dg/gimplefe-37.c: New test.
>> ---
>> gcc/c/gimple-parser.c | 116 +++++++++++++++++++++++------
>> gcc/gimple-pretty-print.c | 8 ++
>> gcc/profile-count.h | 15 ++++
>> gcc/testsuite/gcc.dg/gimplefe-37.c | 27 +++++++
>> 4 files changed, 144 insertions(+), 22 deletions(-)
>> create mode 100644 gcc/testsuite/gcc.dg/gimplefe-37.c
>>
>>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH][stage1] Support profile (BB counts and edge probabilities) in GIMPLE FE.
2019-04-08 13:35 ` Martin Liška
@ 2019-04-09 13:15 ` Martin Liška
2019-04-09 14:02 ` Jan Hubicka
0 siblings, 1 reply; 22+ messages in thread
From: Martin Liška @ 2019-04-09 13:15 UTC (permalink / raw)
To: Richard Biener, Jan Hubicka; +Cc: GCC Patches
[-- Attachment #1: Type: text/plain, Size: 3440 bytes --]
On 4/8/19 3:35 PM, Martin Liška wrote:
> On 4/8/19 11:11 AM, Richard Biener wrote:
>> On Fri, Apr 5, 2019 at 2:32 PM Martin Liška <mliska@suse.cz> wrote:
>>>
>>> Hi.
>>>
>>> The patch adds support for profile for GIMPLE FE. That can be useful
>>> in the future.
>>>
>>> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
>>>
>>> Ready to be installed after stage1 opens?
>>
>> Hmm, I guess to be useful we need the profile quality indicators as well
>> (and think about a proper syntax here since it seems related).
>
> I wanted to make it easy, buy yes. We should implement that.
>
>>
>> Btw, do BB counts and edge probabilities not have a relation?
>
> Yes, they should match. But you have optimizations that make some discrepancies.
> So that I would implement support for both of them.
>
>> If so why
>> do we need both? In predict.c we also look at ENTRY_BLOCK->count
>> so we need a place to set that as well. We should probably set
>> edge probabilities of fallthru edges properly during our "CFG build".
>>
>> + goto __BB3(44739243);
>>
>> since we eventually want to add other flags this syntactically
>> should maybe be goto __BB3(guessed(44739243)); and similar
>> for the __BB count case (just s/count/quality/).
>
> The syntax works for me.
>
>>
>> The entry block count could be sticked to __GIMPLE (ssa,guessed(N))
>> for example. There's also the exit block, not sure if we ever look at
>> its count, so __GIMPLE (ssa,guessed(N[,M])) might be a possibility
>> if we always have the same quality here (probably not...).
>
> I'll check it.
>
>>
>> Otherwise thanks for trying ;)
>>
>> Richard.
>>
>>> Thanks,
>>> Martin
>>>
>>> gcc/ChangeLog:
>>>
>>> 2019-04-05 Martin Liska <mliska@suse.cz>
>>>
>>> * gimple-pretty-print.c (dump_gimple_bb_header):
>>> Dump BB count.
>>> (pp_cfg_jump): Dump edge probability.
>>> * profile-count.h (get_raw_value): New function.
>>> (from_raw_value): Likewise.
>>>
>>> gcc/c/ChangeLog:
>>>
>>> 2019-04-05 Martin Liska <mliska@suse.cz>
>>>
>>> * gimple-parser.c (struct gimple_parser): Add frequency
>>> for gimple_parser_edge.
>>> (gimple_parser::push_edge): Add new argument frequency.
>>> (c_parser_gimple_parse_bb_spec): Parse also frequency
>>> 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.
>>>
>>> gcc/testsuite/ChangeLog:
>>>
>>> 2019-04-05 Martin Liska <mliska@suse.cz>
>>>
>>> * gcc.dg/gimplefe-37.c: New test.
>>> ---
>>> gcc/c/gimple-parser.c | 116 +++++++++++++++++++++++------
>>> gcc/gimple-pretty-print.c | 8 ++
>>> gcc/profile-count.h | 15 ++++
>>> gcc/testsuite/gcc.dg/gimplefe-37.c | 27 +++++++
>>> 4 files changed, 144 insertions(+), 22 deletions(-)
>>> create mode 100644 gcc/testsuite/gcc.dg/gimplefe-37.c
>>>
>>>
>
Hi.
There's updated version that supports profile quality for both counts
and probabilities. I'm wondering whether ENTRY and EXIT BBs needs to
have set probability. Apparently, I haven't seen any verifier that
would complain.
Martin
[-- Attachment #2: 0001-Support-profile-BB-counts-and-edge-probabilities-in-.patch --]
[-- Type: text/x-patch, Size: 23528 bytes --]
From 8a2fed046a9a951ded01b3be1a9ce82ed5ab7496 Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Thu, 4 Apr 2019 14:46:15 +0200
Subject: [PATCH] Support profile (BB counts and edge probabilities) in GIMPLE
FE.
gcc/ChangeLog:
2019-04-05 Martin Liska <mliska@suse.cz>
* 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.
gcc/c/ChangeLog:
2019-04-05 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.
gcc/testsuite/ChangeLog:
2019-04-05 Martin Liska <mliska@suse.cz>
* gcc.dg/gimplefe-37.c: New test.
* gcc.dg/gimplefe-33.c: Likewise.
---
gcc/c/c-parser.c | 3 +-
gcc/c/c-tree.h | 2 +
gcc/c/gimple-parser.c | 170 ++++++++++++++++++++++++-----
gcc/c/gimple-parser.h | 3 +-
gcc/gimple-pretty-print.c | 13 +++
gcc/profile-count.c | 88 ++++++++-------
gcc/profile-count.h | 22 +++-
gcc/testsuite/gcc.dg/gimplefe-37.c | 27 +++++
gcc/testsuite/gcc.dg/gimplefe-38.c | 27 +++++
9 files changed, 286 insertions(+), 69 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/gimplefe-37.c
create mode 100644 gcc/testsuite/gcc.dg/gimplefe-38.c
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 741d172ff30..205ec9b61ce 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -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->hot_bb_threshold);
in_late_binary_op = saved;
}
else
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index 9393f6d1545..b3e024267a1 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -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;
+ /* Hotness threshold for __GIMPLE FE. */
+ gcov_type hot_bb_threshold;
/* The base-2 log of the greatest alignment required by an _Alignas
specifier, in bytes, or -1 if no such specifiers with nonzero
alignment. */
diff --git a/gcc/c/gimple-parser.c b/gcc/c/gimple-parser.c
index fff34606dae..351eea30a3d 100644
--- a/gcc/c/gimple-parser.c
+++ b/gcc/c/gimple-parser.c
@@ -81,20 +81,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,10 +123,12 @@ 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. Return true if so and parse also FREQUENCY of
+ the edge. */
static bool
-c_parser_gimple_parse_bb_spec (tree val, int *index)
+c_parser_gimple_parse_bb_spec (tree val, gimple_parser &parser,
+ int *index, profile_probability *probablity)
{
if (strncmp (IDENTIFIER_POINTER (val), "__BB", 4) != 0)
return false;
@@ -131,14 +136,64 @@ c_parser_gimple_parse_bb_spec (tree val, int *index)
if (!ISDIGIT (*p))
return false;
*index = atoi (IDENTIFIER_POINTER (val) + 4);
- return *index > 0;
+
+ if (*index > 0)
+ {
+ *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, gcov_type hot_bb_threshold)
{
gimple_parser parser (cparser);
gimple_seq seq = NULL;
@@ -209,9 +264,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 +332,11 @@ c_parser_parse_gimple_body (c_parser *cparser, char *gimple_pass,
fix_loop_structure (NULL);
}
+ if (cfun->curr_properties & PROP_cfg)
+ {
+ update_max_bb_count ();
+ set_hot_bb_threshold (hot_bb_threshold);
+ }
dump_function (TDI_gimple, current_function_decl);
}
@@ -337,11 +400,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 +416,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 +459,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 +493,38 @@ 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 frequency 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 +561,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::uninitialized ());
/* We leave the proper setting to fixup. */
struct loop *loop_father = loops_for_fn (cfun)->tree_root;
@@ -498,6 +590,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;
@@ -688,7 +781,9 @@ c_parser_gimple_statement (gimple_parser &parser, gimple_seq *seq)
if (c_parser_next_token_is (parser, CPP_COLON))
c_parser_consume_token (parser);
int src_index = -1;
- if (!c_parser_gimple_parse_bb_spec (arg, &src_index))
+ profile_probability prob;
+ if (!c_parser_gimple_parse_bb_spec (arg, parser, &src_index,
+ &prob))
c_parser_error (parser, "invalid source block specification");
vargs.safe_push (size_int (src_index));
}
@@ -1629,6 +1724,25 @@ 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 (! strcmp (op, "hot_bb_threshold"))
+ {
+ if (! c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
+ return;
+
+ tree v;
+ if (!c_parser_next_token_is (parser, CPP_NUMBER)
+ || (TREE_CODE (v = c_parser_peek_token (parser)->value)
+ != INTEGER_CST))
+ {
+ c_parser_error (parser, "expected frequency value");
+ return;
+ }
+
+ specs->hot_bb_threshold = TREE_INT_CST_LOW (v);
+ 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 +1871,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 (label, parser, &dest_index,
+ &prob))
{
parser.push_edge (parser.current_bb->index, dest_index,
- EDGE_FALLTHRU);
+ EDGE_FALLTHRU, prob);
return;
}
}
@@ -1811,10 +1927,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 (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 +1962,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 (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;
}
diff --git a/gcc/c/gimple-parser.h b/gcc/c/gimple-parser.h
index 383ad768759..22b5b624679 100644
--- a/gcc/c/gimple-parser.h
+++ b/gcc/c/gimple-parser.h
@@ -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, gcov_type
+ hot_bb_threshold);
extern void c_parser_gimple_or_rtl_pass_list (c_parser *, c_declspecs *);
#endif
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index 69bae0d10d0..7e3916bff86 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -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
diff --git a/gcc/profile-count.c b/gcc/profile-count.c
index 8c58f8666f0..4f0bac002d7 100644
--- a/gcc/profile-count.c
+++ b/gcc/profile-count.c
@@ -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;
}
diff --git a/gcc/profile-count.h b/gcc/profile-count.h
index d6de61f0a61..2669f0d5fff 100644
--- a/gcc/profile-count.h
+++ b/gcc/profile-count.h
@@ -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 *);
diff --git a/gcc/testsuite/gcc.dg/gimplefe-37.c b/gcc/testsuite/gcc.dg/gimplefe-37.c
new file mode 100644
index 00000000000..7554e0f2212
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gimplefe-37.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fgimple -fdump-tree-optimized" } */
+
+int __GIMPLE (ssa,startwith("slsr"),hot_bb_threshold(10))
+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" } } */
diff --git a/gcc/testsuite/gcc.dg/gimplefe-38.c b/gcc/testsuite/gcc.dg/gimplefe-38.c
new file mode 100644
index 00000000000..9398db9b0ef
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gimplefe-38.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fgimple -fdump-tree-slsr" } */
+
+int __GIMPLE (ssa,startwith("slsr"))
+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" } } */
--
2.21.0
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH][stage1] Support profile (BB counts and edge probabilities) in GIMPLE FE.
2019-04-09 13:15 ` Martin Liška
@ 2019-04-09 14:02 ` Jan Hubicka
2019-04-10 9:57 ` Martin Liška
0 siblings, 1 reply; 22+ messages in thread
From: Jan Hubicka @ 2019-04-09 14:02 UTC (permalink / raw)
To: Martin Liška; +Cc: Richard Biener, GCC Patches
> Hi.
>
> There's updated version that supports profile quality for both counts
> and probabilities. I'm wondering whether ENTRY and EXIT BBs needs to
> have set probability. Apparently, I haven't seen any verifier that
> would complain.
Well, you do not need to define it but then several cases will
degenerate. In particular BB frequencies (for callgraph profile or
hot/cold decisions) are calculated as ratios of entry BB and given BB
count. If entry BB is undefined you will get those undefined and
heuristics will resort to conservative answers.
I do not think we use exit block count.
Honza
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH][stage1] Support profile (BB counts and edge probabilities) in GIMPLE FE.
2019-04-09 14:02 ` Jan Hubicka
@ 2019-04-10 9:57 ` Martin Liška
2019-04-26 13:29 ` Richard Biener
0 siblings, 1 reply; 22+ messages in thread
From: Martin Liška @ 2019-04-10 9:57 UTC (permalink / raw)
To: Jan Hubicka; +Cc: Richard Biener, GCC Patches
[-- Attachment #1: Type: text/plain, Size: 812 bytes --]
On 4/9/19 3:19 PM, Jan Hubicka wrote:
>> Hi.
>>
>> There's updated version that supports profile quality for both counts
>> and probabilities. I'm wondering whether ENTRY and EXIT BBs needs to
>> have set probability. Apparently, I haven't seen any verifier that
>> would complain.
>
> Well, you do not need to define it but then several cases will
> degenerate. In particular BB frequencies (for callgraph profile or
> hot/cold decisions) are calculated as ratios of entry BB and given BB
> count. If entry BB is undefined you will get those undefined and
> heuristics will resort to conservative answers.
>
> I do not think we use exit block count.
>
> Honza
>
Thank you Honza for explanation. I'm sending version of the patch
that supports entry BB count.
I've been testing the patch right now.
Martin
[-- Attachment #2: 0001-Support-profile-BB-counts-and-edge-probabilities-in-.patch --]
[-- Type: text/x-patch, Size: 25846 bytes --]
From cc041144e55b0d002f43a1a2a61364b0e085c4a0 Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Thu, 4 Apr 2019 14:46:15 +0200
Subject: [PATCH] Support profile (BB counts and edge probabilities) in GIMPLE
FE.
gcc/ChangeLog:
2019-04-05 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.
gcc/c/ChangeLog:
2019-04-05 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.
gcc/testsuite/ChangeLog:
2019-04-05 Martin Liska <mliska@suse.cz>
* gcc.dg/gimplefe-37.c: New test.
* gcc.dg/gimplefe-33.c: Likewise.
---
gcc/c/c-parser.c | 4 +-
gcc/c/c-tree.h | 4 +
gcc/c/gimple-parser.c | 195 +++++++++++++++++++++++++----
gcc/c/gimple-parser.h | 3 +-
gcc/gimple-pretty-print.c | 13 ++
gcc/profile-count.c | 88 +++++++------
gcc/profile-count.h | 22 +++-
gcc/testsuite/gcc.dg/gimplefe-37.c | 27 ++++
gcc/testsuite/gcc.dg/gimplefe-38.c | 27 ++++
gcc/tree-cfg.c | 11 +-
10 files changed, 322 insertions(+), 72 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/gimplefe-37.c
create mode 100644 gcc/testsuite/gcc.dg/gimplefe-38.c
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 741d172ff30..8a6dea4ba06 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -2347,7 +2347,9 @@ 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->hot_bb_threshold,
+ specs->entry_bb_count);
in_late_binary_op = saved;
}
else
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index 9393f6d1545..9294fd4106e 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -317,6 +317,10 @@ struct c_declspecs {
tree attrs;
/* The pass to start compiling a __GIMPLE or __RTL function with. */
char *gimple_or_rtl_pass;
+ /* Hotness threshold for __GIMPLE FE. */
+ gcov_type hot_bb_threshold;
+ /* 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. */
diff --git a/gcc/c/gimple-parser.c b/gcc/c/gimple-parser.c
index fff34606dae..8a4262d6642 100644
--- a/gcc/c/gimple-parser.c
+++ b/gcc/c/gimple-parser.c
@@ -81,20 +81,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,10 +123,12 @@ 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. Return true if so and parse also FREQUENCY of
+ the edge. */
static bool
-c_parser_gimple_parse_bb_spec (tree val, int *index)
+c_parser_gimple_parse_bb_spec (tree val, gimple_parser &parser,
+ int *index, profile_probability *probablity)
{
if (strncmp (IDENTIFIER_POINTER (val), "__BB", 4) != 0)
return false;
@@ -131,14 +136,65 @@ c_parser_gimple_parse_bb_spec (tree val, int *index)
if (!ISDIGIT (*p))
return false;
*index = atoi (IDENTIFIER_POINTER (val) + 4);
- return *index > 0;
+
+ if (*index > 0)
+ {
+ *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, gcov_type hot_bb_threshold,
+ profile_count entry_bb_count)
{
gimple_parser parser (cparser);
gimple_seq seq = NULL;
@@ -209,9 +265,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 +333,12 @@ c_parser_parse_gimple_body (c_parser *cparser, char *gimple_pass,
fix_loop_structure (NULL);
}
+ if (cfun->curr_properties & PROP_cfg)
+ {
+ update_max_bb_count ();
+ set_hot_bb_threshold (hot_bb_threshold);
+ ENTRY_BLOCK_PTR_FOR_FN (cfun)->count = entry_bb_count;
+ }
dump_function (TDI_gimple, current_function_decl);
}
@@ -337,11 +402,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 +418,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 +461,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 +495,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 +564,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::uninitialized ());
/* We leave the proper setting to fixup. */
struct loop *loop_father = loops_for_fn (cfun)->tree_root;
@@ -498,6 +593,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;
@@ -688,7 +784,9 @@ c_parser_gimple_statement (gimple_parser &parser, gimple_seq *seq)
if (c_parser_next_token_is (parser, CPP_COLON))
c_parser_consume_token (parser);
int src_index = -1;
- if (!c_parser_gimple_parse_bb_spec (arg, &src_index))
+ profile_probability prob;
+ if (!c_parser_gimple_parse_bb_spec (arg, parser, &src_index,
+ &prob))
c_parser_error (parser, "invalid source block specification");
vargs.safe_push (size_int (src_index));
}
@@ -1609,8 +1707,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 +1729,45 @@ 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 (!strcmp (op, "hot_bb_threshold"))
+ {
+ if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
+ return;
+
+ tree v;
+ if (!c_parser_next_token_is (parser, CPP_NUMBER)
+ || (TREE_CODE (v = c_parser_peek_token (parser)->value)
+ != INTEGER_CST))
+ {
+ c_parser_error (parser, "expected frequency value");
+ return;
+ }
+
+ specs->hot_bb_threshold = TREE_INT_CST_LOW (v);
+ c_parser_consume_token (parser);
+ 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 +1896,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 (label, parser, &dest_index,
+ &prob))
{
parser.push_edge (parser.current_bb->index, dest_index,
- EDGE_FALLTHRU);
+ EDGE_FALLTHRU, prob);
return;
}
}
@@ -1811,10 +1952,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 (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 +1987,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 (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;
}
diff --git a/gcc/c/gimple-parser.h b/gcc/c/gimple-parser.h
index 383ad768759..1c7a155c06b 100644
--- a/gcc/c/gimple-parser.h
+++ b/gcc/c/gimple-parser.h
@@ -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, gcov_type,
+ profile_count);
extern void c_parser_gimple_or_rtl_pass_list (c_parser *, c_declspecs *);
#endif
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index 69bae0d10d0..7e3916bff86 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -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
diff --git a/gcc/profile-count.c b/gcc/profile-count.c
index 8c58f8666f0..4f0bac002d7 100644
--- a/gcc/profile-count.c
+++ b/gcc/profile-count.c
@@ -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;
}
diff --git a/gcc/profile-count.h b/gcc/profile-count.h
index d6de61f0a61..2669f0d5fff 100644
--- a/gcc/profile-count.h
+++ b/gcc/profile-count.h
@@ -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 *);
diff --git a/gcc/testsuite/gcc.dg/gimplefe-37.c b/gcc/testsuite/gcc.dg/gimplefe-37.c
new file mode 100644
index 00000000000..855bc306fea
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gimplefe-37.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fgimple -fdump-tree-optimized" } */
+
+int __GIMPLE (ssa,startwith("slsr"),hot_bb_threshold(10),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" } } */
diff --git a/gcc/testsuite/gcc.dg/gimplefe-38.c b/gcc/testsuite/gcc.dg/gimplefe-38.c
new file mode 100644
index 00000000000..64532d87da5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gimplefe-38.c
@@ -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" } } */
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 0dc94ea41d4..bf50de5da5e 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -7874,11 +7874,16 @@ dump_function_to_file (tree fndecl, FILE *file, dump_flags_t flags)
{
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));
+ : "");
+ 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] " : "");
--
2.21.0
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH][stage1] Support profile (BB counts and edge probabilities) in GIMPLE FE.
2019-04-10 9:57 ` Martin Liška
@ 2019-04-26 13:29 ` Richard Biener
2019-04-29 12:54 ` Martin Liška
2019-04-30 2:05 ` Joseph Myers
0 siblings, 2 replies; 22+ messages in thread
From: Richard Biener @ 2019-04-26 13:29 UTC (permalink / raw)
To: Martin Liška, Joseph S. Myers; +Cc: Jan Hubicka, GCC Patches
On Wed, Apr 10, 2019 at 10:12 AM Martin Liška <mliska@suse.cz> wrote:
>
> On 4/9/19 3:19 PM, Jan Hubicka wrote:
> >> Hi.
> >>
> >> There's updated version that supports profile quality for both counts
> >> and probabilities. I'm wondering whether ENTRY and EXIT BBs needs to
> >> have set probability. Apparently, I haven't seen any verifier that
> >> would complain.
> >
> > Well, you do not need to define it but then several cases will
> > degenerate. In particular BB frequencies (for callgraph profile or
> > hot/cold decisions) are calculated as ratios of entry BB and given BB
> > count. If entry BB is undefined you will get those undefined and
> > heuristics will resort to conservative answers.
> >
> > I do not think we use exit block count.
> >
> > Honza
> >
>
> Thank you Honza for explanation. I'm sending version of the patch
> that supports entry BB count.
>
> I've been testing the patch right now.
Can you move the GIMPLE/RTL FE specific data in c_declspecs to
a substructure accessed via indirection? I guess enlarging that
isn't really what we should do. You'd move gimple_or_rtl_pass
there and make that pointer one to a struct aux_fe_data
(lifetime managed by the respective RTL/GIMPLE FE, thus
to be freed there)? Joseph, do you agree or is adding more
stuff to c_declspecs OK (I would guess it could be a few more
elements in the future).
-c_parser_gimple_parse_bb_spec (tree val, int *index)
+c_parser_gimple_parse_bb_spec (tree val, gimple_parser &parser,
+ int *index, profile_probability *probablity)
{
so this will allow specifying probability in PHI node arguments.
I think we want to split this into the already existing part
and a c_parser_gimple_parse_bb_spec_with_edge_probability
to be used at edge sources.
+ if (cfun->curr_properties & PROP_cfg)
+ {
+ update_max_bb_count ();
+ set_hot_bb_threshold (hot_bb_threshold);
+ ENTRY_BLOCK_PTR_FOR_FN (cfun)->count = entry_bb_count;
I guess the last one should be before update_max_bb_count ()?
+ }
+ /* 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;
peek next token before the if/else and do
else if (!strcmp (...))
as in the loop_header case. I expected we can somehow share
parsing of profile quality and BB/edge count/frequency? How's
the expected syntax btw, comments in the code should tell us.
I'm guessing it's quality-id '(' number ')' and thus it should be
really shareable between edge and BB count and also __GIMPLE
header parsing? So parse_profile_quality should be
parse_profile () instead, resulting in a combined value
(we do use the same for edge/bb?).
+ else if (!strcmp (op, "hot_bb_threshold"))
+ {
I'm not sure about this - it doesn't make sense to specify this
on a per-function base since it seems to control a global
variable (booo!)? Isn't this instead computed on-demand
based on profile_info->sum_max? If not then I think
we need an alternate way of funneling in global state into
the GIMPLE FE.
Thanks,
Richard.
>
> Martin
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH][stage1] Support profile (BB counts and edge probabilities) in GIMPLE FE.
2019-04-26 13:29 ` Richard Biener
@ 2019-04-29 12:54 ` Martin Liška
2019-05-02 12:31 ` Richard Biener
2019-04-30 2:05 ` Joseph Myers
1 sibling, 1 reply; 22+ messages in thread
From: Martin Liška @ 2019-04-29 12:54 UTC (permalink / raw)
To: Richard Biener, Joseph S. Myers; +Cc: Jan Hubicka, GCC Patches
On 4/26/19 3:18 PM, Richard Biener wrote:
> On Wed, Apr 10, 2019 at 10:12 AM Martin Liška <mliska@suse.cz> wrote:
>>
>> On 4/9/19 3:19 PM, Jan Hubicka wrote:
>>>> Hi.
>>>>
>>>> There's updated version that supports profile quality for both counts
>>>> and probabilities. I'm wondering whether ENTRY and EXIT BBs needs to
>>>> have set probability. Apparently, I haven't seen any verifier that
>>>> would complain.
>>>
>>> Well, you do not need to define it but then several cases will
>>> degenerate. In particular BB frequencies (for callgraph profile or
>>> hot/cold decisions) are calculated as ratios of entry BB and given BB
>>> count. If entry BB is undefined you will get those undefined and
>>> heuristics will resort to conservative answers.
>>>
>>> I do not think we use exit block count.
>>>
>>> Honza
>>>
>>
>> Thank you Honza for explanation. I'm sending version of the patch
>> that supports entry BB count.
>>
>> I've been testing the patch right now.
>
> Can you move the GIMPLE/RTL FE specific data in c_declspecs to
> a substructure accessed via indirection? I guess enlarging that
> isn't really what we should do. You'd move gimple_or_rtl_pass
> there and make that pointer one to a struct aux_fe_data
> (lifetime managed by the respective RTL/GIMPLE FE, thus
> to be freed there)? Joseph, do you agree or is adding more
> stuff to c_declspecs OK (I would guess it could be a few more
> elements in the future).
Let's wait here for Joseph.
>
> -c_parser_gimple_parse_bb_spec (tree val, int *index)
> +c_parser_gimple_parse_bb_spec (tree val, gimple_parser &parser,
> + int *index, profile_probability *probablity)
> {
>
> so this will allow specifying probability in PHI node arguments.
> I think we want to split this into the already existing part
> and a c_parser_gimple_parse_bb_spec_with_edge_probability
> to be used at edge sources.
Yes, that's a good idea!
>
> + if (cfun->curr_properties & PROP_cfg)
> + {
> + update_max_bb_count ();
> + set_hot_bb_threshold (hot_bb_threshold);
> + ENTRY_BLOCK_PTR_FOR_FN (cfun)->count = entry_bb_count;
>
> I guess the last one should be before update_max_bb_count ()?
Same here.
>
> + }
>
> + /* 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;
>
> peek next token before the if/else and do
>
> else if (!strcmp (...))
>
> as in the loop_header case. I expected we can somehow share
> parsing of profile quality and BB/edge count/frequency? How's
> the expected syntax btw, comments in the code should tell us.
> I'm guessing it's quality-id '(' number ')' and thus it should be
> really shareable between edge and BB count and also __GIMPLE
> header parsing? So parse_profile_quality should be
> parse_profile () instead, resulting in a combined value
> (we do use the same for edge/bb?).
It's problematic, there are different error messages for count/frequency.
Moreover call to parse_profile_quality in c_parser_gimple_or_rtl_pass_list
is a way how to test that next 'token' is a profile count.
>
> + else if (!strcmp (op, "hot_bb_threshold"))
> + {
>
> I'm not sure about this - it doesn't make sense to specify this
> on a per-function base since it seems to control a global
> variable (booo!)?
Yep, shame on me!
> Isn't this instead computed on-demand
> based on profile_info->sum_max?
No it's a global value shared among functions.
> If not then I think
> we need an alternate way of funneling in global state into
> the GIMPLE FE.
What about --param gimple-fe-hot-bb-threshold ?
Thanks,
Martin
>
> Thanks,
> Richard.
>
>
>>
>> Martin
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH][stage1] Support profile (BB counts and edge probabilities) in GIMPLE FE.
2019-04-26 13:29 ` Richard Biener
2019-04-29 12:54 ` Martin Liška
@ 2019-04-30 2:05 ` Joseph Myers
1 sibling, 0 replies; 22+ messages in thread
From: Joseph Myers @ 2019-04-30 2:05 UTC (permalink / raw)
To: Richard Biener; +Cc: Martin Liška, Jan Hubicka, GCC Patches
On Fri, 26 Apr 2019, Richard Biener wrote:
> Can you move the GIMPLE/RTL FE specific data in c_declspecs to
> a substructure accessed via indirection? I guess enlarging that
> isn't really what we should do. You'd move gimple_or_rtl_pass
> there and make that pointer one to a struct aux_fe_data
> (lifetime managed by the respective RTL/GIMPLE FE, thus
> to be freed there)? Joseph, do you agree or is adding more
> stuff to c_declspecs OK (I would guess it could be a few more
> elements in the future).
c_declspecs is shortlived (on the parser obstack, freed after each
external declaration is parsed). I don't think its size is particularly
important (this is however a guess, not based on any actual measurements
of cc1 memory usage).
--
Joseph S. Myers
joseph@codesourcery.com
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH][stage1] Support profile (BB counts and edge probabilities) in GIMPLE FE.
2019-04-29 12:54 ` Martin Liška
@ 2019-05-02 12:31 ` Richard Biener
2019-05-06 7:59 ` Martin Liška
0 siblings, 1 reply; 22+ messages in thread
From: Richard Biener @ 2019-05-02 12:31 UTC (permalink / raw)
To: Martin Liška; +Cc: Joseph S. Myers, Jan Hubicka, GCC Patches
On Mon, Apr 29, 2019 at 2:51 PM Martin Liška <mliska@suse.cz> wrote:
>
> On 4/26/19 3:18 PM, Richard Biener wrote:
> > On Wed, Apr 10, 2019 at 10:12 AM Martin Liška <mliska@suse.cz> wrote:
> >>
> >> On 4/9/19 3:19 PM, Jan Hubicka wrote:
> >>>> Hi.
> >>>>
> >>>> There's updated version that supports profile quality for both counts
> >>>> and probabilities. I'm wondering whether ENTRY and EXIT BBs needs to
> >>>> have set probability. Apparently, I haven't seen any verifier that
> >>>> would complain.
> >>>
> >>> Well, you do not need to define it but then several cases will
> >>> degenerate. In particular BB frequencies (for callgraph profile or
> >>> hot/cold decisions) are calculated as ratios of entry BB and given BB
> >>> count. If entry BB is undefined you will get those undefined and
> >>> heuristics will resort to conservative answers.
> >>>
> >>> I do not think we use exit block count.
> >>>
> >>> Honza
> >>>
> >>
> >> Thank you Honza for explanation. I'm sending version of the patch
> >> that supports entry BB count.
> >>
> >> I've been testing the patch right now.
> >
> > Can you move the GIMPLE/RTL FE specific data in c_declspecs to
> > a substructure accessed via indirection? I guess enlarging that
> > isn't really what we should do. You'd move gimple_or_rtl_pass
> > there and make that pointer one to a struct aux_fe_data
> > (lifetime managed by the respective RTL/GIMPLE FE, thus
> > to be freed there)? Joseph, do you agree or is adding more
> > stuff to c_declspecs OK (I would guess it could be a few more
> > elements in the future).
>
> Let's wait here for Joseph.
So looks like it won't matter so let's go with the current approach
for the moment.
> >
> > -c_parser_gimple_parse_bb_spec (tree val, int *index)
> > +c_parser_gimple_parse_bb_spec (tree val, gimple_parser &parser,
> > + int *index, profile_probability *probablity)
> > {
> >
> > so this will allow specifying probability in PHI node arguments.
> > I think we want to split this into the already existing part
> > and a c_parser_gimple_parse_bb_spec_with_edge_probability
> > to be used at edge sources.
>
> Yes, that's a good idea!
>
> >
> > + if (cfun->curr_properties & PROP_cfg)
> > + {
> > + update_max_bb_count ();
> > + set_hot_bb_threshold (hot_bb_threshold);
> > + ENTRY_BLOCK_PTR_FOR_FN (cfun)->count = entry_bb_count;
> >
> > I guess the last one should be before update_max_bb_count ()?
>
> Same here.
>
> >
> > + }
> >
> > + /* 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;
> >
> > peek next token before the if/else and do
> >
> > else if (!strcmp (...))
> >
> > as in the loop_header case. I expected we can somehow share
> > parsing of profile quality and BB/edge count/frequency? How's
> > the expected syntax btw, comments in the code should tell us.
> > I'm guessing it's quality-id '(' number ')' and thus it should be
> > really shareable between edge and BB count and also __GIMPLE
> > header parsing? So parse_profile_quality should be
> > parse_profile () instead, resulting in a combined value
> > (we do use the same for edge/bb?).
>
> It's problematic, there are different error messages for count/frequency.
> Moreover call to parse_profile_quality in c_parser_gimple_or_rtl_pass_list
> is a way how to test that next 'token' is a profile count.
Who cares about error messages... But sure, I'm just proposing to
merge testing for next token and actual parsing.
> >
> > + else if (!strcmp (op, "hot_bb_threshold"))
> > + {
> >
> > I'm not sure about this - it doesn't make sense to specify this
> > on a per-function base since it seems to control a global
> > variable (booo!)?
>
> Yep, shame on me!
>
> > Isn't this instead computed on-demand
> > based on profile_info->sum_max?
>
> No it's a global value shared among functions.
>
> > If not then I think
> > we need an alternate way of funneling in global state into
> > the GIMPLE FE.
>
> What about --param gimple-fe-hot-bb-threshold ?
I thought about that, yes ... in absence can it actually be
"computed"?
Richard.
> Thanks,
> Martin
>
> >
> > Thanks,
> > Richard.
> >
> >
> >>
> >> Martin
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH][stage1] Support profile (BB counts and edge probabilities) in GIMPLE FE.
2019-05-02 12:31 ` Richard Biener
@ 2019-05-06 7:59 ` Martin Liška
2019-05-06 8:00 ` [PATCH 2/2] Support {MIN,MAX}_EXPR " Martin Liška
2019-05-06 14:02 ` [PATCH][stage1] Support profile (BB counts and edge probabilities) " Richard Biener
0 siblings, 2 replies; 22+ messages in thread
From: Martin Liška @ 2019-05-06 7:59 UTC (permalink / raw)
To: Richard Biener; +Cc: Joseph S. Myers, Jan Hubicka, GCC Patches
[-- Attachment #1: Type: text/plain, Size: 4894 bytes --]
On 5/2/19 2:31 PM, Richard Biener wrote:
> On Mon, Apr 29, 2019 at 2:51 PM Martin Liška <mliska@suse.cz> wrote:
>>
>> On 4/26/19 3:18 PM, Richard Biener wrote:
>>> On Wed, Apr 10, 2019 at 10:12 AM Martin Liška <mliska@suse.cz> wrote:
>>>>
>>>> On 4/9/19 3:19 PM, Jan Hubicka wrote:
>>>>>> Hi.
>>>>>>
>>>>>> There's updated version that supports profile quality for both counts
>>>>>> and probabilities. I'm wondering whether ENTRY and EXIT BBs needs to
>>>>>> have set probability. Apparently, I haven't seen any verifier that
>>>>>> would complain.
>>>>>
>>>>> Well, you do not need to define it but then several cases will
>>>>> degenerate. In particular BB frequencies (for callgraph profile or
>>>>> hot/cold decisions) are calculated as ratios of entry BB and given BB
>>>>> count. If entry BB is undefined you will get those undefined and
>>>>> heuristics will resort to conservative answers.
>>>>>
>>>>> I do not think we use exit block count.
>>>>>
>>>>> Honza
>>>>>
>>>>
>>>> Thank you Honza for explanation. I'm sending version of the patch
>>>> that supports entry BB count.
>>>>
>>>> I've been testing the patch right now.
>>>
>>> Can you move the GIMPLE/RTL FE specific data in c_declspecs to
>>> a substructure accessed via indirection? I guess enlarging that
>>> isn't really what we should do. You'd move gimple_or_rtl_pass
>>> there and make that pointer one to a struct aux_fe_data
>>> (lifetime managed by the respective RTL/GIMPLE FE, thus
>>> to be freed there)? Joseph, do you agree or is adding more
>>> stuff to c_declspecs OK (I would guess it could be a few more
>>> elements in the future).
>>
>> Let's wait here for Joseph.
>
> So looks like it won't matter so let's go with the current approach
> for the moment.
>
>>>
>>> -c_parser_gimple_parse_bb_spec (tree val, int *index)
>>> +c_parser_gimple_parse_bb_spec (tree val, gimple_parser &parser,
>>> + int *index, profile_probability *probablity)
>>> {
>>>
>>> so this will allow specifying probability in PHI node arguments.
>>> I think we want to split this into the already existing part
>>> and a c_parser_gimple_parse_bb_spec_with_edge_probability
>>> to be used at edge sources.
>>
>> Yes, that's a good idea!
>>
>>>
>>> + if (cfun->curr_properties & PROP_cfg)
>>> + {
>>> + update_max_bb_count ();
>>> + set_hot_bb_threshold (hot_bb_threshold);
>>> + ENTRY_BLOCK_PTR_FOR_FN (cfun)->count = entry_bb_count;
>>>
>>> I guess the last one should be before update_max_bb_count ()?
>>
>> Same here.
>>
>>>
>>> + }
>>>
>>> + /* 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;
>>>
>>> peek next token before the if/else and do
>>>
>>> else if (!strcmp (...))
>>>
>>> as in the loop_header case. I expected we can somehow share
>>> parsing of profile quality and BB/edge count/frequency? How's
>>> the expected syntax btw, comments in the code should tell us.
>>> I'm guessing it's quality-id '(' number ')' and thus it should be
>>> really shareable between edge and BB count and also __GIMPLE
>>> header parsing? So parse_profile_quality should be
>>> parse_profile () instead, resulting in a combined value
>>> (we do use the same for edge/bb?).
>>
>> It's problematic, there are different error messages for count/frequency.
>> Moreover call to parse_profile_quality in c_parser_gimple_or_rtl_pass_list
>> is a way how to test that next 'token' is a profile count.
>
> Who cares about error messages... But sure, I'm just proposing to
> merge testing for next token and actual parsing.
After I've done removal of hot_bb_threshold parsing, there are just 2 usages
of parse_profile_quality. I would like to leave it as it, not introducing a wrappers.
>
>>>
>>> + else if (!strcmp (op, "hot_bb_threshold"))
>>> + {
>>>
>>> I'm not sure about this - it doesn't make sense to specify this
>>> on a per-function base since it seems to control a global
>>> variable (booo!)?
>>
>> Yep, shame on me!
>>
>>> Isn't this instead computed on-demand
>>> based on profile_info->sum_max?
>>
>> No it's a global value shared among functions.
>>
>>> If not then I think
>>> we need an alternate way of funneling in global state into
>>> the GIMPLE FE.
>>
>> What about --param gimple-fe-hot-bb-threshold ?
>
> I thought about that, yes ... in absence can it actually be
> "computed"?
Renamed to it.
Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
Ready to be installed?
Thanks,
Martin
>
> Richard.
>
>> Thanks,
>> Martin
>>
>>>
>>> Thanks,
>>> Richard.
>>>
>>>
>>>>
>>>> Martin
>>
[-- Attachment #2: 0001-Support-profile-BB-counts-and-edge-probabilities-in-.patch --]
[-- Type: text/x-patch, Size: 27338 bytes --]
From e61a8cbf3c9c8b7aef250e1a5d31cf654fad76bb Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Thu, 4 Apr 2019 14:46:15 +0200
Subject: [PATCH 1/2] Support profile (BB counts and edge probabilities) in
GIMPLE FE.
gcc/ChangeLog:
2019-04-05 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 (get_current_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.
(get_current_hot_bb_threshold): New.
gcc/c/ChangeLog:
2019-04-05 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.
gcc/testsuite/ChangeLog:
2019-04-05 Martin Liska <mliska@suse.cz>
* gcc.dg/gimplefe-37.c: New test.
* gcc.dg/gimplefe-33.c: Likewise.
---
gcc/c/c-parser.c | 3 +-
gcc/c/c-tree.h | 2 +
gcc/c/gimple-parser.c | 180 +++++++++++++++++++++++++----
gcc/c/gimple-parser.h | 3 +-
gcc/gimple-pretty-print.c | 13 +++
gcc/params.def | 6 +
gcc/predict.c | 15 ++-
gcc/predict.h | 1 +
gcc/profile-count.c | 88 +++++++-------
gcc/profile-count.h | 22 +++-
gcc/testsuite/gcc.dg/gimplefe-37.c | 27 +++++
gcc/testsuite/gcc.dg/gimplefe-38.c | 27 +++++
gcc/tree-cfg.c | 25 +++-
13 files changed, 341 insertions(+), 71 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/gimplefe-37.c
create mode 100644 gcc/testsuite/gcc.dg/gimplefe-38.c
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 854cd6ce8c6..3aa85125cf1 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -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
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index 7e35ab1f0bc..346f46a5207 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -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. */
diff --git a/gcc/c/gimple-parser.c b/gcc/c/gimple-parser.c
index fff34606dae..6558770873f 100644
--- a/gcc/c/gimple-parser.c
+++ b/gcc/c/gimple-parser.c
@@ -81,20 +81,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 +123,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 +137,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 +278,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 +346,11 @@ 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;
+ update_max_bb_count ();
+ }
dump_function (TDI_gimple, current_function_decl);
}
@@ -337,11 +414,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 +430,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 +473,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 +507,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 +576,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::uninitialized ());
/* We leave the proper setting to fixup. */
struct loop *loop_father = loops_for_fn (cfun)->tree_root;
@@ -498,6 +605,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 +1717,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 +1739,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 +1887,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 +1943,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 +1978,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;
}
diff --git a/gcc/c/gimple-parser.h b/gcc/c/gimple-parser.h
index 383ad768759..cc28c0f7bf9 100644
--- a/gcc/c/gimple-parser.h
+++ b/gcc/c/gimple-parser.h
@@ -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
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index 69bae0d10d0..7e3916bff86 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -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
diff --git a/gcc/params.def b/gcc/params.def
index 3c9c5fc0f13..840b81f43cc 100644
--- a/gcc/params.def
+++ b/gcc/params.def
@@ -1414,6 +1414,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:
diff --git a/gcc/predict.c b/gcc/predict.c
index b010c20ff7d..12a484a799a 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -132,8 +132,11 @@ get_hot_bb_threshold ()
{
if (min_count == -1)
{
- min_count
- = profile_info->sum_max / PARAM_VALUE (HOT_BB_COUNT_FRACTION);
+ if (flag_gimple)
+ min_count = PARAM_VALUE (PARAM_GIMPLE_FE_COMPUTED_HOT_BB_THRESHOLD);
+ else
+ min_count
+ = profile_info->sum_max / PARAM_VALUE (HOT_BB_COUNT_FRACTION);
if (dump_file)
fprintf (dump_file, "Setting hotness threshold to %" PRId64 ".\n",
min_count);
@@ -141,6 +144,14 @@ get_hot_bb_threshold ()
return min_count;
}
+/* Determine the threshold for hot BB counts and do not set the value. */
+
+gcov_type
+get_current_hot_bb_threshold ()
+{
+ return min_count;
+}
+
/* Set the threshold for hot BB counts. */
void
diff --git a/gcc/predict.h b/gcc/predict.h
index c1f2f0307dd..fe87dd6fc92 100644
--- a/gcc/predict.h
+++ b/gcc/predict.h
@@ -52,6 +52,7 @@ enum prediction
extern profile_probability split_branch_probability;
extern gcov_type get_hot_bb_threshold (void);
+extern gcov_type get_current_hot_bb_threshold (void);
extern void set_hot_bb_threshold (gcov_type);
extern bool maybe_hot_count_p (struct function *, profile_count);
extern bool maybe_hot_bb_p (struct function *, const_basic_block);
diff --git a/gcc/profile-count.c b/gcc/profile-count.c
index 8c58f8666f0..4f0bac002d7 100644
--- a/gcc/profile-count.c
+++ b/gcc/profile-count.c
@@ -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;
}
diff --git a/gcc/profile-count.h b/gcc/profile-count.h
index d6de61f0a61..2669f0d5fff 100644
--- a/gcc/profile-count.h
+++ b/gcc/profile-count.h
@@ -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 *);
diff --git a/gcc/testsuite/gcc.dg/gimplefe-37.c b/gcc/testsuite/gcc.dg/gimplefe-37.c
new file mode 100644
index 00000000000..d3ea186d7f9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gimplefe-37.c
@@ -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" } } */
diff --git a/gcc/testsuite/gcc.dg/gimplefe-38.c b/gcc/testsuite/gcc.dg/gimplefe-38.c
new file mode 100644
index 00000000000..64532d87da5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gimplefe-38.c
@@ -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" } } */
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 587408150fb..f7ebac674db 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -7872,13 +7872,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 (get_current_hot_bb_threshold () != -1
+ && !hotness_bb_param_printed)
+ {
+ hotness_bb_param_printed = true;
+ fprintf (file,
+ "/* --param=gimple-fe-computed-hot-bb-threshold=%" PRId64
+ " */\n", get_current_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] " : "");
--
2.21.0
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH 2/2] Support {MIN,MAX}_EXPR in GIMPLE FE.
2019-05-06 7:59 ` Martin Liška
@ 2019-05-06 8:00 ` Martin Liška
2019-05-06 11:35 ` Richard Biener
2019-05-06 14:02 ` [PATCH][stage1] Support profile (BB counts and edge probabilities) " Richard Biener
1 sibling, 1 reply; 22+ messages in thread
From: Martin Liška @ 2019-05-06 8:00 UTC (permalink / raw)
To: Richard Biener; +Cc: Joseph S. Myers, Jan Hubicka, GCC Patches
[-- Attachment #1: Type: text/plain, Size: 165 bytes --]
Hi.
The patch is about support of a new GIMPLE expr.
Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
Ready to be installed?
Thanks,
Martin
[-- Attachment #2: 0002-Support-MIN-MAX-_EXPR-in-GIMPLE-FE.patch --]
[-- Type: text/x-patch, Size: 4938 bytes --]
From a4f23fe8d876f2d8a0628feb57127e276348aab0 Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Fri, 3 May 2019 13:54:40 +0200
Subject: [PATCH 2/2] Support {MIN,MAX}_EXPR in GIMPLE FE.
gcc/ChangeLog:
2019-05-03 Martin Liska <mliska@suse.cz>
* gimple-pretty-print.c (dump_binary_rhs): Dump MIN_EXPR
and MAX_EXPR in GIMPLE FE format.
gcc/c/ChangeLog:
2019-05-03 Martin Liska <mliska@suse.cz>
* c-typeck.c (build_binary_op): Handle MIN_EXPR and MAX_EXPR
with flag_gimple.
* gimple-parser.c (c_parser_gimple_statement): Support __MIN and
__MAX.
(c_parser_gimple_unary_expression): Parse also binary expression
__MIN and __MAX.
gcc/testsuite/ChangeLog:
2019-05-03 Martin Liska <mliska@suse.cz>
* gcc.dg/gimplefe-39.c: New test.
---
gcc/c/c-typeck.c | 10 ++++++++++
gcc/c/gimple-parser.c | 21 ++++++++++++++++++++-
gcc/gimple-pretty-print.c | 15 ++++++++++++++-
gcc/testsuite/gcc.dg/gimplefe-39.c | 21 +++++++++++++++++++++
4 files changed, 65 insertions(+), 2 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/gimplefe-39.c
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 4e443754002..d0ae9c51f6b 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -12193,6 +12193,16 @@ build_binary_op (location_t location, enum tree_code code,
maybe_warn_bool_compare (location, code, orig_op0, orig_op1);
break;
+ case MIN_EXPR:
+ case MAX_EXPR:
+ if (flag_gimple)
+ {
+ result_type = c_common_type (type0, type1);
+ break;
+ }
+ else
+ gcc_unreachable ();
+
default:
gcc_unreachable ();
}
diff --git a/gcc/c/gimple-parser.c b/gcc/c/gimple-parser.c
index 6558770873f..f3e0d2f94ad 100644
--- a/gcc/c/gimple-parser.c
+++ b/gcc/c/gimple-parser.c
@@ -747,7 +747,9 @@ c_parser_gimple_statement (gimple_parser &parser, gimple_seq *seq)
{
tree id = c_parser_peek_token (parser)->value;
if (strcmp (IDENTIFIER_POINTER (id), "__ABS") == 0
- || strcmp (IDENTIFIER_POINTER (id), "__ABSU") == 0)
+ || strcmp (IDENTIFIER_POINTER (id), "__ABSU") == 0
+ || strcmp (IDENTIFIER_POINTER (id), "__MIN") == 0
+ || strcmp (IDENTIFIER_POINTER (id), "__MAX") == 0)
goto build_unary_expr;
break;
}
@@ -1062,6 +1064,7 @@ c_parser_gimple_unary_expression (gimple_parser &parser)
}
case CPP_NAME:
{
+ bool is_min;
tree id = c_parser_peek_token (parser)->value;
if (strcmp (IDENTIFIER_POINTER (id), "__ABS") == 0)
{
@@ -1075,6 +1078,22 @@ c_parser_gimple_unary_expression (gimple_parser &parser)
op = c_parser_gimple_postfix_expression (parser);
return parser_build_unary_op (op_loc, ABSU_EXPR, op);
}
+ else if ((is_min = strcmp (IDENTIFIER_POINTER (id), "__MIN") == 0)
+ || strcmp (IDENTIFIER_POINTER (id), "__MAX") == 0)
+ {
+ c_parser_consume_token (parser);
+ if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
+ return ret;
+ c_expr op1 = c_parser_gimple_postfix_expression (parser);
+ if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
+ return ret;
+ c_expr op2 = c_parser_gimple_postfix_expression (parser);
+ if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
+ return ret;
+ return parser_build_binary_op (op_loc,
+ is_min ? MIN_EXPR : MAX_EXPR,
+ op1, op2);
+ }
else
return c_parser_gimple_postfix_expression (parser);
}
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index 7e3916bff86..58212c4dcc1 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -423,9 +423,22 @@ dump_binary_rhs (pretty_printer *buffer, gassign *gs, int spc,
enum tree_code code = gimple_assign_rhs_code (gs);
switch (code)
{
- case COMPLEX_EXPR:
case MIN_EXPR:
case MAX_EXPR:
+ if (flags & TDF_GIMPLE)
+ {
+ pp_string (buffer, code == MIN_EXPR ? "__MIN (" : "__MAX (");
+ dump_generic_node (buffer, gimple_assign_rhs1 (gs), spc, flags,
+ false);
+ pp_string (buffer, ", ");
+ dump_generic_node (buffer, gimple_assign_rhs2 (gs), spc, flags,
+ false);
+ pp_string (buffer, ")");
+ break;
+ }
+ else
+ gcc_fallthrough ();
+ case COMPLEX_EXPR:
case VEC_WIDEN_MULT_HI_EXPR:
case VEC_WIDEN_MULT_LO_EXPR:
case VEC_WIDEN_MULT_EVEN_EXPR:
diff --git a/gcc/testsuite/gcc.dg/gimplefe-39.c b/gcc/testsuite/gcc.dg/gimplefe-39.c
new file mode 100644
index 00000000000..30677356d5b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gimplefe-39.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fgimple -fdump-tree-optimized" } */
+
+int a, b;
+
+int __GIMPLE (ssa,guessed_local(1073741824))
+main (int argc)
+{
+ int _1;
+ int _2;
+ int _4;
+
+ __BB(2,guessed_local(1073741824)):
+ _1 = a;
+ _2 = b;
+ _4 = __MAX (_1, _2);
+ return _4;
+
+}
+
+/* { dg-final { scan-tree-dump "MAX_EXPR" "optimized" } } */
--
2.21.0
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 2/2] Support {MIN,MAX}_EXPR in GIMPLE FE.
2019-05-06 8:00 ` [PATCH 2/2] Support {MIN,MAX}_EXPR " Martin Liška
@ 2019-05-06 11:35 ` Richard Biener
2019-05-07 12:01 ` Martin Liška
0 siblings, 1 reply; 22+ messages in thread
From: Richard Biener @ 2019-05-06 11:35 UTC (permalink / raw)
To: Martin Liška; +Cc: Joseph S. Myers, Jan Hubicka, GCC Patches
On Mon, May 6, 2019 at 10:00 AM Martin Liška <mliska@suse.cz> wrote:
>
> Hi.
>
> The patch is about support of a new GIMPLE expr.
>
> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
>
> Ready to be installed?
Can you please avoid using/changing parser_build_binary_op? The other
binary expression handling just does
if (lhs.value != error_mark_node && rhs.value != error_mark_node)
ret.value = build2_loc (ret_loc, code, ret_type, lhs.value, rhs.value);
which should work equally well here. I think for future expansion
splitting out the ( op, op ) parsing and expression building into
a function might be nicer so that c_parser_gimple_unary_expression
reads
if (strcmp (INDENTIFIER_POINTER (id), "__MIN") == 0)
return c_parser_gimple_parentized_binary_expression (op_loc, MIN_EXPR);
else if (...)
OK with such change/factoring.
Thanks,
Richard.
> Thanks,
> Martin
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH][stage1] Support profile (BB counts and edge probabilities) in GIMPLE FE.
2019-05-06 7:59 ` Martin Liška
2019-05-06 8:00 ` [PATCH 2/2] Support {MIN,MAX}_EXPR " Martin Liška
@ 2019-05-06 14:02 ` Richard Biener
2019-05-07 12:00 ` Martin Liška
1 sibling, 1 reply; 22+ messages in thread
From: Richard Biener @ 2019-05-06 14:02 UTC (permalink / raw)
To: Martin Liška; +Cc: Joseph S. Myers, Jan Hubicka, GCC Patches
On Mon, May 6, 2019 at 9:59 AM Martin Liška <mliska@suse.cz> wrote:
>
> On 5/2/19 2:31 PM, Richard Biener wrote:
> > On Mon, Apr 29, 2019 at 2:51 PM Martin Liška <mliska@suse.cz> wrote:
> >>
> >> On 4/26/19 3:18 PM, Richard Biener wrote:
> >>> On Wed, Apr 10, 2019 at 10:12 AM Martin Liška <mliska@suse.cz> wrote:
> >>>>
> >>>> On 4/9/19 3:19 PM, Jan Hubicka wrote:
> >>>>>> Hi.
> >>>>>>
> >>>>>> There's updated version that supports profile quality for both counts
> >>>>>> and probabilities. I'm wondering whether ENTRY and EXIT BBs needs to
> >>>>>> have set probability. Apparently, I haven't seen any verifier that
> >>>>>> would complain.
> >>>>>
> >>>>> Well, you do not need to define it but then several cases will
> >>>>> degenerate. In particular BB frequencies (for callgraph profile or
> >>>>> hot/cold decisions) are calculated as ratios of entry BB and given BB
> >>>>> count. If entry BB is undefined you will get those undefined and
> >>>>> heuristics will resort to conservative answers.
> >>>>>
> >>>>> I do not think we use exit block count.
> >>>>>
> >>>>> Honza
> >>>>>
> >>>>
> >>>> Thank you Honza for explanation. I'm sending version of the patch
> >>>> that supports entry BB count.
> >>>>
> >>>> I've been testing the patch right now.
> >>>
> >>> Can you move the GIMPLE/RTL FE specific data in c_declspecs to
> >>> a substructure accessed via indirection? I guess enlarging that
> >>> isn't really what we should do. You'd move gimple_or_rtl_pass
> >>> there and make that pointer one to a struct aux_fe_data
> >>> (lifetime managed by the respective RTL/GIMPLE FE, thus
> >>> to be freed there)? Joseph, do you agree or is adding more
> >>> stuff to c_declspecs OK (I would guess it could be a few more
> >>> elements in the future).
> >>
> >> Let's wait here for Joseph.
> >
> > So looks like it won't matter so let's go with the current approach
> > for the moment.
> >
> >>>
> >>> -c_parser_gimple_parse_bb_spec (tree val, int *index)
> >>> +c_parser_gimple_parse_bb_spec (tree val, gimple_parser &parser,
> >>> + int *index, profile_probability *probablity)
> >>> {
> >>>
> >>> so this will allow specifying probability in PHI node arguments.
> >>> I think we want to split this into the already existing part
> >>> and a c_parser_gimple_parse_bb_spec_with_edge_probability
> >>> to be used at edge sources.
> >>
> >> Yes, that's a good idea!
> >>
> >>>
> >>> + if (cfun->curr_properties & PROP_cfg)
> >>> + {
> >>> + update_max_bb_count ();
> >>> + set_hot_bb_threshold (hot_bb_threshold);
> >>> + ENTRY_BLOCK_PTR_FOR_FN (cfun)->count = entry_bb_count;
> >>>
> >>> I guess the last one should be before update_max_bb_count ()?
> >>
> >> Same here.
> >>
> >>>
> >>> + }
> >>>
> >>> + /* 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;
> >>>
> >>> peek next token before the if/else and do
> >>>
> >>> else if (!strcmp (...))
> >>>
> >>> as in the loop_header case. I expected we can somehow share
> >>> parsing of profile quality and BB/edge count/frequency? How's
> >>> the expected syntax btw, comments in the code should tell us.
> >>> I'm guessing it's quality-id '(' number ')' and thus it should be
> >>> really shareable between edge and BB count and also __GIMPLE
> >>> header parsing? So parse_profile_quality should be
> >>> parse_profile () instead, resulting in a combined value
> >>> (we do use the same for edge/bb?).
> >>
> >> It's problematic, there are different error messages for count/frequency.
> >> Moreover call to parse_profile_quality in c_parser_gimple_or_rtl_pass_list
> >> is a way how to test that next 'token' is a profile count.
> >
> > Who cares about error messages... But sure, I'm just proposing to
> > merge testing for next token and actual parsing.
>
> After I've done removal of hot_bb_threshold parsing, there are just 2 usages
> of parse_profile_quality. I would like to leave it as it, not introducing a wrappers.
>
> >
> >>>
> >>> + else if (!strcmp (op, "hot_bb_threshold"))
> >>> + {
> >>>
> >>> I'm not sure about this - it doesn't make sense to specify this
> >>> on a per-function base since it seems to control a global
> >>> variable (booo!)?
> >>
> >> Yep, shame on me!
> >>
> >>> Isn't this instead computed on-demand
> >>> based on profile_info->sum_max?
> >>
> >> No it's a global value shared among functions.
> >>
> >>> If not then I think
> >>> we need an alternate way of funneling in global state into
> >>> the GIMPLE FE.
> >>
> >> What about --param gimple-fe-hot-bb-threshold ?
> >
> > I thought about that, yes ... in absence can it actually be
> > "computed"?
>
> Renamed to it.
>
> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
>
> Ready to be installed?
@@ -470,7 +576,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::uninitialized ());
/* We leave the proper setting to fixup. */
struct loop *loop_father = loops_for_fn (cfun)->tree_root;
the fallthru edge from ENTRY to the single-succ of ENTRY should have
100% probability and be "known", no? Or do we actually use uninitialized
for fallthru edges?
diff --git a/gcc/params.def b/gcc/params.def
index 3c9c5fc0f13..840b81f43cc 100644
--- a/gcc/params.def
+++ b/gcc/params.def
@@ -1414,6 +1414,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:
diff --git a/gcc/predict.c b/gcc/predict.c
index b010c20ff7d..12a484a799a 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -132,8 +132,11 @@ get_hot_bb_threshold ()
{
if (min_count == -1)
{
- min_count
- = profile_info->sum_max / PARAM_VALUE (HOT_BB_COUNT_FRACTION);
+ if (flag_gimple)
+ min_count = PARAM_VALUE (PARAM_GIMPLE_FE_COMPUTED_HOT_BB_THRESHOLD);
+ else
+ min_count
+ = profile_info->sum_max / PARAM_VALUE (HOT_BB_COUNT_FRACTION);
if (dump_file)
fprintf (dump_file, "Setting hotness threshold to %" PRId64 ".\n",
min_count);
Ick. I'd rather do this somewhere in the frontend where PARAM_VALUE
is initialized
via set_hot_bb_threshold. Even redundantly for each parsed GIMPLE
function would
be OK and better IMHO. That way you don't need get_current_hot_bb_threshold(?).
OK with that changes.
We need to think about switch stmt parsing where we currently have
switch (argc_2(D)) {default: L2; case 0: L0; case 1: L0; case 2: L1; }
__BB(3):
L0:
a_4 = 0;
goto __BB6;
...
extending this to
switch (argc_2(D)) { default: L2 (guessed(10)); ...
might be possible so we have profile on the edges.
After the patch all -gimple dumps have profile - probably good
but also visually disturbing. Ah well.
Hope to do loop flags as followup soon.
Thanks,
Richard.
> Thanks,
> Martin
>
> >
> > Richard.
> >
> >> Thanks,
> >> Martin
> >>
> >>>
> >>> Thanks,
> >>> Richard.
> >>>
> >>>
> >>>>
> >>>> Martin
> >>
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH][stage1] Support profile (BB counts and edge probabilities) in GIMPLE FE.
2019-05-06 14:02 ` [PATCH][stage1] Support profile (BB counts and edge probabilities) " Richard Biener
@ 2019-05-07 12:00 ` Martin Liška
2019-05-07 12:56 ` Richard Biener
2019-05-10 6:39 ` Bernhard Reutner-Fischer
0 siblings, 2 replies; 22+ messages in thread
From: Martin Liška @ 2019-05-07 12:00 UTC (permalink / raw)
To: Richard Biener; +Cc: Joseph S. Myers, Jan Hubicka, GCC Patches
[-- Attachment #1: Type: text/plain, Size: 8339 bytes --]
On 5/6/19 4:02 PM, Richard Biener wrote:
> On Mon, May 6, 2019 at 9:59 AM Martin Liška <mliska@suse.cz> wrote:
>>
>> On 5/2/19 2:31 PM, Richard Biener wrote:
>>> On Mon, Apr 29, 2019 at 2:51 PM Martin Liška <mliska@suse.cz> wrote:
>>>>
>>>> On 4/26/19 3:18 PM, Richard Biener wrote:
>>>>> On Wed, Apr 10, 2019 at 10:12 AM Martin Liška <mliska@suse.cz> wrote:
>>>>>>
>>>>>> On 4/9/19 3:19 PM, Jan Hubicka wrote:
>>>>>>>> Hi.
>>>>>>>>
>>>>>>>> There's updated version that supports profile quality for both counts
>>>>>>>> and probabilities. I'm wondering whether ENTRY and EXIT BBs needs to
>>>>>>>> have set probability. Apparently, I haven't seen any verifier that
>>>>>>>> would complain.
>>>>>>>
>>>>>>> Well, you do not need to define it but then several cases will
>>>>>>> degenerate. In particular BB frequencies (for callgraph profile or
>>>>>>> hot/cold decisions) are calculated as ratios of entry BB and given BB
>>>>>>> count. If entry BB is undefined you will get those undefined and
>>>>>>> heuristics will resort to conservative answers.
>>>>>>>
>>>>>>> I do not think we use exit block count.
>>>>>>>
>>>>>>> Honza
>>>>>>>
>>>>>>
>>>>>> Thank you Honza for explanation. I'm sending version of the patch
>>>>>> that supports entry BB count.
>>>>>>
>>>>>> I've been testing the patch right now.
>>>>>
>>>>> Can you move the GIMPLE/RTL FE specific data in c_declspecs to
>>>>> a substructure accessed via indirection? I guess enlarging that
>>>>> isn't really what we should do. You'd move gimple_or_rtl_pass
>>>>> there and make that pointer one to a struct aux_fe_data
>>>>> (lifetime managed by the respective RTL/GIMPLE FE, thus
>>>>> to be freed there)? Joseph, do you agree or is adding more
>>>>> stuff to c_declspecs OK (I would guess it could be a few more
>>>>> elements in the future).
>>>>
>>>> Let's wait here for Joseph.
>>>
>>> So looks like it won't matter so let's go with the current approach
>>> for the moment.
>>>
>>>>>
>>>>> -c_parser_gimple_parse_bb_spec (tree val, int *index)
>>>>> +c_parser_gimple_parse_bb_spec (tree val, gimple_parser &parser,
>>>>> + int *index, profile_probability *probablity)
>>>>> {
>>>>>
>>>>> so this will allow specifying probability in PHI node arguments.
>>>>> I think we want to split this into the already existing part
>>>>> and a c_parser_gimple_parse_bb_spec_with_edge_probability
>>>>> to be used at edge sources.
>>>>
>>>> Yes, that's a good idea!
>>>>
>>>>>
>>>>> + if (cfun->curr_properties & PROP_cfg)
>>>>> + {
>>>>> + update_max_bb_count ();
>>>>> + set_hot_bb_threshold (hot_bb_threshold);
>>>>> + ENTRY_BLOCK_PTR_FOR_FN (cfun)->count = entry_bb_count;
>>>>>
>>>>> I guess the last one should be before update_max_bb_count ()?
>>>>
>>>> Same here.
>>>>
>>>>>
>>>>> + }
>>>>>
>>>>> + /* 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;
>>>>>
>>>>> peek next token before the if/else and do
>>>>>
>>>>> else if (!strcmp (...))
>>>>>
>>>>> as in the loop_header case. I expected we can somehow share
>>>>> parsing of profile quality and BB/edge count/frequency? How's
>>>>> the expected syntax btw, comments in the code should tell us.
>>>>> I'm guessing it's quality-id '(' number ')' and thus it should be
>>>>> really shareable between edge and BB count and also __GIMPLE
>>>>> header parsing? So parse_profile_quality should be
>>>>> parse_profile () instead, resulting in a combined value
>>>>> (we do use the same for edge/bb?).
>>>>
>>>> It's problematic, there are different error messages for count/frequency.
>>>> Moreover call to parse_profile_quality in c_parser_gimple_or_rtl_pass_list
>>>> is a way how to test that next 'token' is a profile count.
>>>
>>> Who cares about error messages... But sure, I'm just proposing to
>>> merge testing for next token and actual parsing.
>>
>> After I've done removal of hot_bb_threshold parsing, there are just 2 usages
>> of parse_profile_quality. I would like to leave it as it, not introducing a wrappers.
>>
>>>
>>>>>
>>>>> + else if (!strcmp (op, "hot_bb_threshold"))
>>>>> + {
>>>>>
>>>>> I'm not sure about this - it doesn't make sense to specify this
>>>>> on a per-function base since it seems to control a global
>>>>> variable (booo!)?
>>>>
>>>> Yep, shame on me!
>>>>
>>>>> Isn't this instead computed on-demand
>>>>> based on profile_info->sum_max?
>>>>
>>>> No it's a global value shared among functions.
>>>>
>>>>> If not then I think
>>>>> we need an alternate way of funneling in global state into
>>>>> the GIMPLE FE.
>>>>
>>>> What about --param gimple-fe-hot-bb-threshold ?
>>>
>>> I thought about that, yes ... in absence can it actually be
>>> "computed"?
>>
>> Renamed to it.
>>
>> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
>>
>> Ready to be installed?
>
> @@ -470,7 +576,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::uninitialized ());
>
> /* We leave the proper setting to fixup. */
> struct loop *loop_father = loops_for_fn (cfun)->tree_root;
>
> the fallthru edge from ENTRY to the single-succ of ENTRY should have
> 100% probability and be "known", no? Or do we actually use uninitialized
> for fallthru edges?
Fixed by setting to ::always ().
>
> diff --git a/gcc/params.def b/gcc/params.def
> index 3c9c5fc0f13..840b81f43cc 100644
> --- a/gcc/params.def
> +++ b/gcc/params.def
> @@ -1414,6 +1414,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:
> diff --git a/gcc/predict.c b/gcc/predict.c
> index b010c20ff7d..12a484a799a 100644
> --- a/gcc/predict.c
> +++ b/gcc/predict.c
> @@ -132,8 +132,11 @@ get_hot_bb_threshold ()
> {
> if (min_count == -1)
> {
> - min_count
> - = profile_info->sum_max / PARAM_VALUE (HOT_BB_COUNT_FRACTION);
> + if (flag_gimple)
> + min_count = PARAM_VALUE (PARAM_GIMPLE_FE_COMPUTED_HOT_BB_THRESHOLD);
> + else
> + min_count
> + = profile_info->sum_max / PARAM_VALUE (HOT_BB_COUNT_FRACTION);
> if (dump_file)
> fprintf (dump_file, "Setting hotness threshold to %" PRId64 ".\n",
> min_count);
>
> Ick. I'd rather do this somewhere in the frontend where PARAM_VALUE
> is initialized
> via set_hot_bb_threshold. Even redundantly for each parsed GIMPLE
> function would
> be OK and better IMHO.
I've done that in c_parser_parse_gimple_body.
> That way you don't need get_current_hot_bb_threshold(?).
We still want it for dump_function_to_file that prints the value in a comment.
>
> OK with that changes.
>
> We need to think about switch stmt parsing where we currently have
>
> switch (argc_2(D)) {default: L2; case 0: L0; case 1: L0; case 2: L1; }
>
> __BB(3):
> L0:
> a_4 = 0;
> goto __BB6;
> ...
>
> extending this to
>
> switch (argc_2(D)) { default: L2 (guessed(10)); ...
>
> might be possible so we have profile on the edges.
I can work on that during this stage1.
Martin
>
> After the patch all -gimple dumps have profile - probably good
> but also visually disturbing. Ah well.
>
> Hope to do loop flags as followup soon.
>
> Thanks,
> Richard.
>
>> Thanks,
>> Martin
>>
>>>
>>> Richard.
>>>
>>>> Thanks,
>>>> Martin
>>>>
>>>>>
>>>>> Thanks,
>>>>> Richard.
>>>>>
>>>>>
>>>>>>
>>>>>> Martin
>>>>
>>
[-- Attachment #2: 0001-Support-profile-BB-counts-and-edge-probabilities-in-.patch --]
[-- Type: text/x-patch, Size: 27568 bytes --]
From cf363e50fec0810bf167c01916c6b758d04e966c Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Thu, 4 Apr 2019 14:46:15 +0200
Subject: [PATCH 1/2] Support profile (BB counts and edge probabilities) in
GIMPLE FE.
gcc/ChangeLog:
2019-04-05 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 (get_current_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.
(get_current_hot_bb_threshold): New.
gcc/c/ChangeLog:
2019-04-05 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.
gcc/testsuite/ChangeLog:
2019-04-05 Martin Liska <mliska@suse.cz>
* gcc.dg/gimplefe-37.c: New test.
* gcc.dg/gimplefe-33.c: Likewise.
---
gcc/c/c-parser.c | 3 +-
gcc/c/c-tree.h | 2 +
gcc/c/gimple-parser.c | 183 +++++++++++++++++++++++++----
gcc/c/gimple-parser.h | 3 +-
gcc/gimple-pretty-print.c | 13 ++
gcc/params.def | 6 +
gcc/predict.c | 12 +-
gcc/predict.h | 1 +
gcc/profile-count.c | 88 +++++++-------
gcc/profile-count.h | 22 +++-
gcc/testsuite/gcc.dg/gimplefe-37.c | 27 +++++
gcc/testsuite/gcc.dg/gimplefe-38.c | 27 +++++
gcc/tree-cfg.c | 25 +++-
13 files changed, 341 insertions(+), 71 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/gimplefe-37.c
create mode 100644 gcc/testsuite/gcc.dg/gimplefe-38.c
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 854cd6ce8c6..3aa85125cf1 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -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
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index 7e35ab1f0bc..346f46a5207 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -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. */
diff --git a/gcc/c/gimple-parser.c b/gcc/c/gimple-parser.c
index fff34606dae..ede5a927c3d 100644
--- a/gcc/c/gimple-parser.c
+++ b/gcc/c/gimple-parser.c
@@ -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;
}
diff --git a/gcc/c/gimple-parser.h b/gcc/c/gimple-parser.h
index 383ad768759..cc28c0f7bf9 100644
--- a/gcc/c/gimple-parser.h
+++ b/gcc/c/gimple-parser.h
@@ -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
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index 69bae0d10d0..7e3916bff86 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -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
diff --git a/gcc/params.def b/gcc/params.def
index 904b3cbdf16..5830cb5d6e4 100644
--- a/gcc/params.def
+++ b/gcc/params.def
@@ -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:
diff --git a/gcc/predict.c b/gcc/predict.c
index b010c20ff7d..87467482e91 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -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);
@@ -141,6 +141,14 @@ get_hot_bb_threshold ()
return min_count;
}
+/* Determine the threshold for hot BB counts and do not set the value. */
+
+gcov_type
+get_current_hot_bb_threshold ()
+{
+ return min_count;
+}
+
/* Set the threshold for hot BB counts. */
void
diff --git a/gcc/predict.h b/gcc/predict.h
index c1f2f0307dd..fe87dd6fc92 100644
--- a/gcc/predict.h
+++ b/gcc/predict.h
@@ -52,6 +52,7 @@ enum prediction
extern profile_probability split_branch_probability;
extern gcov_type get_hot_bb_threshold (void);
+extern gcov_type get_current_hot_bb_threshold (void);
extern void set_hot_bb_threshold (gcov_type);
extern bool maybe_hot_count_p (struct function *, profile_count);
extern bool maybe_hot_bb_p (struct function *, const_basic_block);
diff --git a/gcc/profile-count.c b/gcc/profile-count.c
index 8c58f8666f0..4f0bac002d7 100644
--- a/gcc/profile-count.c
+++ b/gcc/profile-count.c
@@ -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;
}
diff --git a/gcc/profile-count.h b/gcc/profile-count.h
index d6de61f0a61..2669f0d5fff 100644
--- a/gcc/profile-count.h
+++ b/gcc/profile-count.h
@@ -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 *);
diff --git a/gcc/testsuite/gcc.dg/gimplefe-37.c b/gcc/testsuite/gcc.dg/gimplefe-37.c
new file mode 100644
index 00000000000..d3ea186d7f9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gimplefe-37.c
@@ -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" } } */
diff --git a/gcc/testsuite/gcc.dg/gimplefe-38.c b/gcc/testsuite/gcc.dg/gimplefe-38.c
new file mode 100644
index 00000000000..64532d87da5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gimplefe-38.c
@@ -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" } } */
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 587408150fb..f7ebac674db 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -7872,13 +7872,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 (get_current_hot_bb_threshold () != -1
+ && !hotness_bb_param_printed)
+ {
+ hotness_bb_param_printed = true;
+ fprintf (file,
+ "/* --param=gimple-fe-computed-hot-bb-threshold=%" PRId64
+ " */\n", get_current_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] " : "");
--
2.21.0
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 2/2] Support {MIN,MAX}_EXPR in GIMPLE FE.
2019-05-06 11:35 ` Richard Biener
@ 2019-05-07 12:01 ` Martin Liška
2019-05-07 12:58 ` Richard Biener
0 siblings, 1 reply; 22+ messages in thread
From: Martin Liška @ 2019-05-07 12:01 UTC (permalink / raw)
To: Richard Biener; +Cc: Joseph S. Myers, Jan Hubicka, GCC Patches
[-- Attachment #1: Type: text/plain, Size: 1056 bytes --]
On 5/6/19 1:35 PM, Richard Biener wrote:
> On Mon, May 6, 2019 at 10:00 AM Martin Liška <mliska@suse.cz> wrote:
>>
>> Hi.
>>
>> The patch is about support of a new GIMPLE expr.
>>
>> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
>>
>> Ready to be installed?
>
> Can you please avoid using/changing parser_build_binary_op? The other
> binary expression handling just does
>
> if (lhs.value != error_mark_node && rhs.value != error_mark_node)
> ret.value = build2_loc (ret_loc, code, ret_type, lhs.value, rhs.value);
>
> which should work equally well here. I think for future expansion
> splitting out the ( op, op ) parsing and expression building into
> a function might be nicer so that c_parser_gimple_unary_expression
> reads
>
> if (strcmp (INDENTIFIER_POINTER (id), "__MIN") == 0)
> return c_parser_gimple_parentized_binary_expression (op_loc, MIN_EXPR);
> else if (...)
>
> OK with such change/factoring.
I've done all what you pointed out.
Martin
>
> Thanks,
> Richard.
>
>> Thanks,
>> Martin
[-- Attachment #2: 0002-Support-MIN-MAX-_EXPR-in-GIMPLE-FE.patch --]
[-- Type: text/x-patch, Size: 4775 bytes --]
From fe7fc3a153e404c485fa1d8dcd428c4a8ebc8f67 Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Fri, 3 May 2019 13:54:40 +0200
Subject: [PATCH 2/2] Support {MIN,MAX}_EXPR in GIMPLE FE.
gcc/ChangeLog:
2019-05-03 Martin Liska <mliska@suse.cz>
* gimple-pretty-print.c (dump_binary_rhs): Dump MIN_EXPR
and MAX_EXPR in GIMPLE FE format.
gcc/c/ChangeLog:
2019-05-03 Martin Liska <mliska@suse.cz>
* gimple-parser.c (c_parser_gimple_statement): Support __MIN and
__MAX.
(c_parser_gimple_unary_expression): Parse also binary expression
__MIN and __MAX.
(c_parser_gimple_parentized_binary_expression): New function.
gcc/testsuite/ChangeLog:
2019-05-03 Martin Liska <mliska@suse.cz>
* gcc.dg/gimplefe-39.c: New test.
---
gcc/c/gimple-parser.c | 38 +++++++++++++++++++++++++++++-
gcc/gimple-pretty-print.c | 15 +++++++++++-
gcc/testsuite/gcc.dg/gimplefe-39.c | 21 +++++++++++++++++
3 files changed, 72 insertions(+), 2 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/gimplefe-39.c
diff --git a/gcc/c/gimple-parser.c b/gcc/c/gimple-parser.c
index ede5a927c3d..99f764710b2 100644
--- a/gcc/c/gimple-parser.c
+++ b/gcc/c/gimple-parser.c
@@ -750,7 +750,9 @@ c_parser_gimple_statement (gimple_parser &parser, gimple_seq *seq)
{
tree id = c_parser_peek_token (parser)->value;
if (strcmp (IDENTIFIER_POINTER (id), "__ABS") == 0
- || strcmp (IDENTIFIER_POINTER (id), "__ABSU") == 0)
+ || strcmp (IDENTIFIER_POINTER (id), "__ABSU") == 0
+ || strcmp (IDENTIFIER_POINTER (id), "__MIN") == 0
+ || strcmp (IDENTIFIER_POINTER (id), "__MAX") == 0)
goto build_unary_expr;
break;
}
@@ -989,6 +991,32 @@ c_parser_gimple_binary_expression (gimple_parser &parser)
return ret;
}
+/* Parse a gimple parentized binary expression. */
+
+static c_expr
+c_parser_gimple_parentized_binary_expression (gimple_parser &parser,
+ location_t op_loc,
+ tree_code code)
+{
+ struct c_expr ret;
+ ret.set_error ();
+
+ c_parser_consume_token (parser);
+ if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
+ return ret;
+ c_expr op1 = c_parser_gimple_postfix_expression (parser);
+ if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
+ return ret;
+ c_expr op2 = c_parser_gimple_postfix_expression (parser);
+ if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
+ return ret;
+
+ if (op1.value != error_mark_node && op2.value != error_mark_node)
+ ret.value = build2_loc (op_loc,
+ code, TREE_TYPE (op1.value), op1.value, op2.value);
+ return ret;
+}
+
/* Parse gimple unary expression.
gimple-unary-expression:
@@ -1078,6 +1106,14 @@ c_parser_gimple_unary_expression (gimple_parser &parser)
op = c_parser_gimple_postfix_expression (parser);
return parser_build_unary_op (op_loc, ABSU_EXPR, op);
}
+ else if (strcmp (IDENTIFIER_POINTER (id), "__MIN") == 0)
+ return c_parser_gimple_parentized_binary_expression (parser,
+ op_loc,
+ MIN_EXPR);
+ else if (strcmp (IDENTIFIER_POINTER (id), "__MAX") == 0)
+ return c_parser_gimple_parentized_binary_expression (parser,
+ op_loc,
+ MAX_EXPR);
else
return c_parser_gimple_postfix_expression (parser);
}
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index 7e3916bff86..58212c4dcc1 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -423,9 +423,22 @@ dump_binary_rhs (pretty_printer *buffer, gassign *gs, int spc,
enum tree_code code = gimple_assign_rhs_code (gs);
switch (code)
{
- case COMPLEX_EXPR:
case MIN_EXPR:
case MAX_EXPR:
+ if (flags & TDF_GIMPLE)
+ {
+ pp_string (buffer, code == MIN_EXPR ? "__MIN (" : "__MAX (");
+ dump_generic_node (buffer, gimple_assign_rhs1 (gs), spc, flags,
+ false);
+ pp_string (buffer, ", ");
+ dump_generic_node (buffer, gimple_assign_rhs2 (gs), spc, flags,
+ false);
+ pp_string (buffer, ")");
+ break;
+ }
+ else
+ gcc_fallthrough ();
+ case COMPLEX_EXPR:
case VEC_WIDEN_MULT_HI_EXPR:
case VEC_WIDEN_MULT_LO_EXPR:
case VEC_WIDEN_MULT_EVEN_EXPR:
diff --git a/gcc/testsuite/gcc.dg/gimplefe-39.c b/gcc/testsuite/gcc.dg/gimplefe-39.c
new file mode 100644
index 00000000000..30677356d5b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gimplefe-39.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fgimple -fdump-tree-optimized" } */
+
+int a, b;
+
+int __GIMPLE (ssa,guessed_local(1073741824))
+main (int argc)
+{
+ int _1;
+ int _2;
+ int _4;
+
+ __BB(2,guessed_local(1073741824)):
+ _1 = a;
+ _2 = b;
+ _4 = __MAX (_1, _2);
+ return _4;
+
+}
+
+/* { dg-final { scan-tree-dump "MAX_EXPR" "optimized" } } */
--
2.21.0
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH][stage1] Support profile (BB counts and edge probabilities) in GIMPLE FE.
2019-05-07 12:00 ` Martin Liška
@ 2019-05-07 12:56 ` Richard Biener
2019-05-07 14:33 ` Martin Liška
2019-05-10 6:39 ` Bernhard Reutner-Fischer
1 sibling, 1 reply; 22+ messages in thread
From: Richard Biener @ 2019-05-07 12:56 UTC (permalink / raw)
To: Martin Liška; +Cc: Joseph S. Myers, Jan Hubicka, GCC Patches
On Tue, May 7, 2019 at 2:00 PM Martin Liška <mliska@suse.cz> wrote:
>
> On 5/6/19 4:02 PM, Richard Biener wrote:
> > On Mon, May 6, 2019 at 9:59 AM Martin Liška <mliska@suse.cz> wrote:
> >>
> >> On 5/2/19 2:31 PM, Richard Biener wrote:
> >>> On Mon, Apr 29, 2019 at 2:51 PM Martin Liška <mliska@suse.cz> wrote:
> >>>>
> >>>> On 4/26/19 3:18 PM, Richard Biener wrote:
> >>>>> On Wed, Apr 10, 2019 at 10:12 AM Martin Liška <mliska@suse.cz> wrote:
> >>>>>>
> >>>>>> On 4/9/19 3:19 PM, Jan Hubicka wrote:
> >>>>>>>> Hi.
> >>>>>>>>
> >>>>>>>> There's updated version that supports profile quality for both counts
> >>>>>>>> and probabilities. I'm wondering whether ENTRY and EXIT BBs needs to
> >>>>>>>> have set probability. Apparently, I haven't seen any verifier that
> >>>>>>>> would complain.
> >>>>>>>
> >>>>>>> Well, you do not need to define it but then several cases will
> >>>>>>> degenerate. In particular BB frequencies (for callgraph profile or
> >>>>>>> hot/cold decisions) are calculated as ratios of entry BB and given BB
> >>>>>>> count. If entry BB is undefined you will get those undefined and
> >>>>>>> heuristics will resort to conservative answers.
> >>>>>>>
> >>>>>>> I do not think we use exit block count.
> >>>>>>>
> >>>>>>> Honza
> >>>>>>>
> >>>>>>
> >>>>>> Thank you Honza for explanation. I'm sending version of the patch
> >>>>>> that supports entry BB count.
> >>>>>>
> >>>>>> I've been testing the patch right now.
> >>>>>
> >>>>> Can you move the GIMPLE/RTL FE specific data in c_declspecs to
> >>>>> a substructure accessed via indirection? I guess enlarging that
> >>>>> isn't really what we should do. You'd move gimple_or_rtl_pass
> >>>>> there and make that pointer one to a struct aux_fe_data
> >>>>> (lifetime managed by the respective RTL/GIMPLE FE, thus
> >>>>> to be freed there)? Joseph, do you agree or is adding more
> >>>>> stuff to c_declspecs OK (I would guess it could be a few more
> >>>>> elements in the future).
> >>>>
> >>>> Let's wait here for Joseph.
> >>>
> >>> So looks like it won't matter so let's go with the current approach
> >>> for the moment.
> >>>
> >>>>>
> >>>>> -c_parser_gimple_parse_bb_spec (tree val, int *index)
> >>>>> +c_parser_gimple_parse_bb_spec (tree val, gimple_parser &parser,
> >>>>> + int *index, profile_probability *probablity)
> >>>>> {
> >>>>>
> >>>>> so this will allow specifying probability in PHI node arguments.
> >>>>> I think we want to split this into the already existing part
> >>>>> and a c_parser_gimple_parse_bb_spec_with_edge_probability
> >>>>> to be used at edge sources.
> >>>>
> >>>> Yes, that's a good idea!
> >>>>
> >>>>>
> >>>>> + if (cfun->curr_properties & PROP_cfg)
> >>>>> + {
> >>>>> + update_max_bb_count ();
> >>>>> + set_hot_bb_threshold (hot_bb_threshold);
> >>>>> + ENTRY_BLOCK_PTR_FOR_FN (cfun)->count = entry_bb_count;
> >>>>>
> >>>>> I guess the last one should be before update_max_bb_count ()?
> >>>>
> >>>> Same here.
> >>>>
> >>>>>
> >>>>> + }
> >>>>>
> >>>>> + /* 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;
> >>>>>
> >>>>> peek next token before the if/else and do
> >>>>>
> >>>>> else if (!strcmp (...))
> >>>>>
> >>>>> as in the loop_header case. I expected we can somehow share
> >>>>> parsing of profile quality and BB/edge count/frequency? How's
> >>>>> the expected syntax btw, comments in the code should tell us.
> >>>>> I'm guessing it's quality-id '(' number ')' and thus it should be
> >>>>> really shareable between edge and BB count and also __GIMPLE
> >>>>> header parsing? So parse_profile_quality should be
> >>>>> parse_profile () instead, resulting in a combined value
> >>>>> (we do use the same for edge/bb?).
> >>>>
> >>>> It's problematic, there are different error messages for count/frequency.
> >>>> Moreover call to parse_profile_quality in c_parser_gimple_or_rtl_pass_list
> >>>> is a way how to test that next 'token' is a profile count.
> >>>
> >>> Who cares about error messages... But sure, I'm just proposing to
> >>> merge testing for next token and actual parsing.
> >>
> >> After I've done removal of hot_bb_threshold parsing, there are just 2 usages
> >> of parse_profile_quality. I would like to leave it as it, not introducing a wrappers.
> >>
> >>>
> >>>>>
> >>>>> + else if (!strcmp (op, "hot_bb_threshold"))
> >>>>> + {
> >>>>>
> >>>>> I'm not sure about this - it doesn't make sense to specify this
> >>>>> on a per-function base since it seems to control a global
> >>>>> variable (booo!)?
> >>>>
> >>>> Yep, shame on me!
> >>>>
> >>>>> Isn't this instead computed on-demand
> >>>>> based on profile_info->sum_max?
> >>>>
> >>>> No it's a global value shared among functions.
> >>>>
> >>>>> If not then I think
> >>>>> we need an alternate way of funneling in global state into
> >>>>> the GIMPLE FE.
> >>>>
> >>>> What about --param gimple-fe-hot-bb-threshold ?
> >>>
> >>> I thought about that, yes ... in absence can it actually be
> >>> "computed"?
> >>
> >> Renamed to it.
> >>
> >> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
> >>
> >> Ready to be installed?
> >
> > @@ -470,7 +576,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::uninitialized ());
> >
> > /* We leave the proper setting to fixup. */
> > struct loop *loop_father = loops_for_fn (cfun)->tree_root;
> >
> > the fallthru edge from ENTRY to the single-succ of ENTRY should have
> > 100% probability and be "known", no? Or do we actually use uninitialized
> > for fallthru edges?
>
> Fixed by setting to ::always ().
>
> >
> > diff --git a/gcc/params.def b/gcc/params.def
> > index 3c9c5fc0f13..840b81f43cc 100644
> > --- a/gcc/params.def
> > +++ b/gcc/params.def
> > @@ -1414,6 +1414,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:
> > diff --git a/gcc/predict.c b/gcc/predict.c
> > index b010c20ff7d..12a484a799a 100644
> > --- a/gcc/predict.c
> > +++ b/gcc/predict.c
> > @@ -132,8 +132,11 @@ get_hot_bb_threshold ()
> > {
> > if (min_count == -1)
> > {
> > - min_count
> > - = profile_info->sum_max / PARAM_VALUE (HOT_BB_COUNT_FRACTION);
> > + if (flag_gimple)
> > + min_count = PARAM_VALUE (PARAM_GIMPLE_FE_COMPUTED_HOT_BB_THRESHOLD);
> > + else
> > + min_count
> > + = profile_info->sum_max / PARAM_VALUE (HOT_BB_COUNT_FRACTION);
> > if (dump_file)
> > fprintf (dump_file, "Setting hotness threshold to %" PRId64 ".\n",
> > min_count);
> >
> > Ick. I'd rather do this somewhere in the frontend where PARAM_VALUE
> > is initialized
> > via set_hot_bb_threshold. Even redundantly for each parsed GIMPLE
> > function would
> > be OK and better IMHO.
>
> I've done that in c_parser_parse_gimple_body.
>
> > That way you don't need get_current_hot_bb_threshold(?).
>
> We still want it for dump_function_to_file that prints the value in a comment.
But that can use the existing get_hot_bb_threshold since we never want
to dump -1 in case min_count was never initialized.
> >
> > OK with that changes.
> >
> > We need to think about switch stmt parsing where we currently have
> >
> > switch (argc_2(D)) {default: L2; case 0: L0; case 1: L0; case 2: L1; }
> >
> > __BB(3):
> > L0:
> > a_4 = 0;
> > goto __BB6;
> > ...
> >
> > extending this to
> >
> > switch (argc_2(D)) { default: L2 (guessed(10)); ...
> >
> > might be possible so we have profile on the edges.
>
> I can work on that during this stage1.
>
> Martin
>
> >
> > After the patch all -gimple dumps have profile - probably good
> > but also visually disturbing. Ah well.
> >
> > Hope to do loop flags as followup soon.
> >
> > Thanks,
> > Richard.
> >
> >> Thanks,
> >> Martin
> >>
> >>>
> >>> Richard.
> >>>
> >>>> Thanks,
> >>>> Martin
> >>>>
> >>>>>
> >>>>> Thanks,
> >>>>> Richard.
> >>>>>
> >>>>>
> >>>>>>
> >>>>>> Martin
> >>>>
> >>
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 2/2] Support {MIN,MAX}_EXPR in GIMPLE FE.
2019-05-07 12:01 ` Martin Liška
@ 2019-05-07 12:58 ` Richard Biener
0 siblings, 0 replies; 22+ messages in thread
From: Richard Biener @ 2019-05-07 12:58 UTC (permalink / raw)
To: Martin Liška; +Cc: Joseph S. Myers, Jan Hubicka, GCC Patches
On Tue, May 7, 2019 at 2:01 PM Martin Liška <mliska@suse.cz> wrote:
>
> On 5/6/19 1:35 PM, Richard Biener wrote:
> > On Mon, May 6, 2019 at 10:00 AM Martin Liška <mliska@suse.cz> wrote:
> >>
> >> Hi.
> >>
> >> The patch is about support of a new GIMPLE expr.
> >>
> >> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
> >>
> >> Ready to be installed?
> >
> > Can you please avoid using/changing parser_build_binary_op? The other
> > binary expression handling just does
> >
> > if (lhs.value != error_mark_node && rhs.value != error_mark_node)
> > ret.value = build2_loc (ret_loc, code, ret_type, lhs.value, rhs.value);
> >
> > which should work equally well here. I think for future expansion
> > splitting out the ( op, op ) parsing and expression building into
> > a function might be nicer so that c_parser_gimple_unary_expression
> > reads
> >
> > if (strcmp (INDENTIFIER_POINTER (id), "__MIN") == 0)
> > return c_parser_gimple_parentized_binary_expression (op_loc, MIN_EXPR);
> > else if (...)
> >
> > OK with such change/factoring.
>
> I've done all what you pointed out.
OK.
Thanks,
Richard.
> Martin
>
> >
> > Thanks,
> > Richard.
> >
> >> Thanks,
> >> Martin
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH][stage1] Support profile (BB counts and edge probabilities) in GIMPLE FE.
2019-05-07 12:56 ` Richard Biener
@ 2019-05-07 14:33 ` Martin Liška
2019-05-07 14:44 ` Richard Biener
0 siblings, 1 reply; 22+ messages in thread
From: Martin Liška @ 2019-05-07 14:33 UTC (permalink / raw)
To: Richard Biener; +Cc: Joseph S. Myers, Jan Hubicka, GCC Patches
On 5/7/19 2:56 PM, Richard Biener wrote:
> But that can use the existing get_hot_bb_threshold since we never want
> to dump -1 in case min_count was never initialized.
Yes. But the function will call:
get_hot_bb_threshold ()
{
if (min_count == -1)
{
gcov_type t = profile_info->sum_max / PARAM_VALUE (HOT_BB_COUNT_FRACTION);
set_hot_bb_threshold (t);
...
which will cause a segfault in non-PGO run. Note that:
static gcov_type min_count = -1;
is a non-exported variable so that's why I simply added the getter.
Hope it's fine as is?
Martin
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH][stage1] Support profile (BB counts and edge probabilities) in GIMPLE FE.
2019-05-07 14:33 ` Martin Liška
@ 2019-05-07 14:44 ` Richard Biener
2019-05-09 10:01 ` Martin Liška
0 siblings, 1 reply; 22+ messages in thread
From: Richard Biener @ 2019-05-07 14:44 UTC (permalink / raw)
To: Martin Liška; +Cc: Joseph S. Myers, Jan Hubicka, GCC Patches
On May 7, 2019 4:33:08 PM GMT+02:00, "Martin Liška" <mliska@suse.cz> wrote:
>On 5/7/19 2:56 PM, Richard Biener wrote:
>> But that can use the existing get_hot_bb_threshold since we never
>want
>> to dump -1 in case min_count was never initialized.
>
>Yes. But the function will call:
>
>get_hot_bb_threshold ()
>{
> if (min_count == -1)
> {
>gcov_type t = profile_info->sum_max / PARAM_VALUE
>(HOT_BB_COUNT_FRACTION);
> set_hot_bb_threshold (t);
>...
>
>which will cause a segfault in non-PGO run. Note that:
>static gcov_type min_count = -1;
>
>is a non-exported variable so that's why I simply added the getter.
>
>Hope it's fine as is?
Oh, I see. Hmm, so we should get away with no min_coubt when all counter kinds are non-pgo?
Richard.
>
>Martin
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH][stage1] Support profile (BB counts and edge probabilities) in GIMPLE FE.
2019-05-07 14:44 ` Richard Biener
@ 2019-05-09 10:01 ` Martin Liška
0 siblings, 0 replies; 22+ messages in thread
From: Martin Liška @ 2019-05-09 10:01 UTC (permalink / raw)
To: Richard Biener; +Cc: Joseph S. Myers, Jan Hubicka, GCC Patches
On 5/7/19 4:44 PM, Richard Biener wrote:
> On May 7, 2019 4:33:08 PM GMT+02:00, "Martin Liška" <mliska@suse.cz> wrote:
>> On 5/7/19 2:56 PM, Richard Biener wrote:
>>> But that can use the existing get_hot_bb_threshold since we never
>> want
>>> to dump -1 in case min_count was never initialized.
>>
>> Yes. But the function will call:
>>
>> get_hot_bb_threshold ()
>> {
>> if (min_count == -1)
>> {
>> gcov_type t = profile_info->sum_max / PARAM_VALUE
>> (HOT_BB_COUNT_FRACTION);
>> set_hot_bb_threshold (t);
>> ...
>>
>> which will cause a segfault in non-PGO run. Note that:
>> static gcov_type min_count = -1;
>>
>> is a non-exported variable so that's why I simply added the getter.
>>
>> Hope it's fine as is?
>
> Oh, I see. Hmm, so we should get away with no min_coubt when all counter kinds are non-pgo?
Yes, in that situation we don't want to print:
/* --param=gimple-fe-computed-hot-bb-threshold=xyz */
Martin
>
> Richard.
>
>>
>> Martin
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH][stage1] Support profile (BB counts and edge probabilities) in GIMPLE FE.
2019-05-07 12:00 ` Martin Liška
2019-05-07 12:56 ` Richard Biener
@ 2019-05-10 6:39 ` Bernhard Reutner-Fischer
1 sibling, 0 replies; 22+ messages in thread
From: Bernhard Reutner-Fischer @ 2019-05-10 6:39 UTC (permalink / raw)
To: gcc-patches, Martin Liška, Richard Biener
Cc: Joseph S. Myers, Jan Hubicka, GCC Patches
On 7 May 2019 14:00:32 CEST, "Martin Liška" <mliska@suse.cz> wrote:
/The parameters is/s/parameters/parameter/
thanks,
^ permalink raw reply [flat|nested] 22+ messages in thread
end of thread, other threads:[~2019-05-10 6:39 UTC | newest]
Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-05 12:32 [PATCH][stage1] Support profile (BB counts and edge probabilities) in GIMPLE FE Martin Liška
2019-04-08 9:11 ` Richard Biener
2019-04-08 13:35 ` Martin Liška
2019-04-09 13:15 ` Martin Liška
2019-04-09 14:02 ` Jan Hubicka
2019-04-10 9:57 ` Martin Liška
2019-04-26 13:29 ` Richard Biener
2019-04-29 12:54 ` Martin Liška
2019-05-02 12:31 ` Richard Biener
2019-05-06 7:59 ` Martin Liška
2019-05-06 8:00 ` [PATCH 2/2] Support {MIN,MAX}_EXPR " Martin Liška
2019-05-06 11:35 ` Richard Biener
2019-05-07 12:01 ` Martin Liška
2019-05-07 12:58 ` Richard Biener
2019-05-06 14:02 ` [PATCH][stage1] Support profile (BB counts and edge probabilities) " Richard Biener
2019-05-07 12:00 ` Martin Liška
2019-05-07 12:56 ` Richard Biener
2019-05-07 14:33 ` Martin Liška
2019-05-07 14:44 ` Richard Biener
2019-05-09 10:01 ` Martin Liška
2019-05-10 6:39 ` Bernhard Reutner-Fischer
2019-04-30 2:05 ` Joseph Myers
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).