public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [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

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).