From 4963172e22489a83caa866854386b6d8b5a62f7a Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Mon, 19 Jun 2017 15:44:34 +0200
Subject: [PATCH] Recover GOTO predictor.

gcc/c/ChangeLog:

2017-06-21  Jan Hubicka <hubicka@ucw.cz>
	    Martin Liska  <mliska@suse.cz>

	* c-typeck.c (c_finish_goto_label): Build gimple predict
	stament.

gcc/ChangeLog:

2017-06-21  Jan Hubicka <hubicka@ucw.cz>
	    Martin Liska  <mliska@suse.cz>

	* predict.def: Remove old comment and adjust probability.
	* gimplify.c (should_warn_for_implicit_fallthrough): Ignore
	PREDICT statements.

gcc/testsuite/ChangeLog:

2017-06-21  Jan Hubicka <hubicka@ucw.cz>
	    Martin Liska  <mliska@suse.cz>

	* gcc.dg/predict-15.c: New test.
	* gcc.dg/tree-ssa/attr-hotcold-2.c: Update the test-case.

gcc/cp/ChangeLog:

2017-06-21  Jan Hubicka <hubicka@ucw.cz>
	    Martin Liska  <mliska@suse.cz>

	* pt.c (tsubst_copy): Copy PREDICT_EXPR.
	* semantics.c (finish_goto_stmt): Build gimple predict
	stament.
	* constexpr.c (potential_constant_expression_1): Handle
	PREDICT_EXPR.
---
 gcc/c/c-typeck.c                               |  1 +
 gcc/cp/constexpr.c                             |  1 +
 gcc/cp/pt.c                                    |  2 ++
 gcc/cp/semantics.c                             |  2 ++
 gcc/gimplify.c                                 |  4 +++-
 gcc/predict.def                                |  5 ++---
 gcc/testsuite/gcc.dg/predict-15.c              | 17 +++++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/attr-hotcold-2.c | 13 ++++++-------
 8 files changed, 34 insertions(+), 11 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/predict-15.c

diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 4d067e96dd3..c677c3e9ff5 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -9824,6 +9824,7 @@ c_finish_goto_label (location_t loc, tree label)
     return NULL_TREE;
   TREE_USED (decl) = 1;
   {
+    add_stmt (build_predict_expr (PRED_GOTO, NOT_TAKEN));
     tree t = build1 (GOTO_EXPR, void_type_node, decl);
     SET_EXPR_LOCATION (t, loc);
     return add_stmt (t);
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 5a574524866..788e02d7372 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -5784,6 +5784,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict,
 
     case CLEANUP_STMT:
     case EMPTY_CLASS_EXPR:
+    case PREDICT_EXPR:
       return false;
 
     case GOTO_EXPR:
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 69ca9291960..445b46da2de 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -15111,6 +15111,8 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       return tsubst_binary_left_fold (t, args, complain, in_decl);
     case BINARY_RIGHT_FOLD_EXPR:
       return tsubst_binary_right_fold (t, args, complain, in_decl);
+    case PREDICT_EXPR:
+      return t;
 
     default:
       /* We shouldn't get here, but keep going if !flag_checking.  */
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 5fe772a49e3..a5fcc7b2c63 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -41,6 +41,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "omp-general.h"
 #include "convert.h"
 #include "gomp-constants.h"
+#include "predict.h"
 
 /* There routines provide a modular interface to perform many parsing
    operations.  They may therefore be used during actual parsing, or
@@ -630,6 +631,7 @@ finish_goto_stmt (tree destination)
 
   check_goto (destination);
 
+  add_stmt (build_predict_expr (PRED_GOTO, NOT_TAKEN));
   return add_stmt (build_stmt (input_location, GOTO_EXPR, destination));
 }
 
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index f45d3bfd13a..0ea8d4ea07b 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -2042,7 +2042,9 @@ should_warn_for_implicit_fallthrough (gimple_stmt_iterator *gsi_p, tree label)
   gsi = *gsi_p;
 
   /* Skip all immediately following labels.  */
-  while (!gsi_end_p (gsi) && gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL)
+  while (!gsi_end_p (gsi)
+	 && (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
+	     || gimple_code (gsi_stmt (gsi)) == GIMPLE_PREDICT))
     gsi_next (&gsi);
 
   /* { ... something; default:; } */
diff --git a/gcc/predict.def b/gcc/predict.def
index f7b2bf7738c..326c39ae4c9 100644
--- a/gcc/predict.def
+++ b/gcc/predict.def
@@ -132,9 +132,8 @@ DEF_PREDICTOR (PRED_RECURSIVE_CALL, "recursive call", HITRATE (75), 0)
 DEF_PREDICTOR (PRED_TREE_EARLY_RETURN, "early return (on trees)", HITRATE (66),
 	       0)
 
-/* Branch containing goto is probably not taken.
-   FIXME: Currently not used.  */
-DEF_PREDICTOR (PRED_GOTO, "goto", HITRATE (70), 0)
+/* Branch containing goto is probably not taken.  */
+DEF_PREDICTOR (PRED_GOTO, "goto", HITRATE (66), 0)
 
 /* Branch ending with return constant is probably not taken.  */
 DEF_PREDICTOR (PRED_CONST_RETURN, "const return", HITRATE (69), 0)
diff --git a/gcc/testsuite/gcc.dg/predict-15.c b/gcc/testsuite/gcc.dg/predict-15.c
new file mode 100644
index 00000000000..2a8c3ea8597
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/predict-15.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-profile_estimate" } */
+
+int main(int argc, char **argv)
+{
+  if (argc == 123)
+    goto exit;
+  else
+    {
+      return 0;
+    }
+
+exit:
+  return 1;
+}
+
+/* { dg-final { scan-tree-dump "goto heuristics of edge" "profile_estimate"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/attr-hotcold-2.c b/gcc/testsuite/gcc.dg/tree-ssa/attr-hotcold-2.c
index 184dd10ddae..d5999e1bf6f 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/attr-hotcold-2.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/attr-hotcold-2.c
@@ -1,8 +1,7 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-profile_estimate-blocks-details" } */
+/* { dg-options "-O2 -fdump-tree-profile_estimate" } */
 
-void g(void);
-void h(void);
+int v1, v2;
 void f(int x, int y)
 {
   if (x) goto A;
@@ -10,19 +9,19 @@ void f(int x, int y)
   return;
 
  A: __attribute__((cold))
-  g();
+  v1 = x;
   return;
 
  B: __attribute__((hot))
-  h();
+  v2 = y;
   return;
 }
 
 /* { dg-final { scan-tree-dump-times "hot label heuristics" 1 "profile_estimate" } } */
 /* { dg-final { scan-tree-dump-times "cold label heuristics" 1 "profile_estimate" } } */
-/* { dg-final { scan-tree-dump "A \\\[0\\\..*\\\]" "profile_estimate" } } */
+/* { dg-final { scan-tree-dump "combined heuristics: 0\\\..*" "profile_estimate" } } */
 
 /* Note: we're attempting to match some number > 6000, i.e. > 60%.
    The exact number ought to be tweekable without having to juggle
    the testcase around too much.  */
-/* { dg-final { scan-tree-dump "B \\\[\[6-9\]\[0-9\]\\\..*\\\]" "profile_estimate" } } */
+/* { dg-final { scan-tree-dump "combined heuristics: \[6-9\]\[0-9\]\\\..*" "profile_estimate" } } */
-- 
2.13.1

