From 2c5123744bae39d080ca33d9463a517417ebafbe Mon Sep 17 00:00:00 2001
From: Jan Hubicka <hubicka@ucw.cz>
Date: Sun, 1 Jan 2017 16:40:29 +0100
Subject: [PATCH] re PR middle-end/77484 (Static branch predictor causes ~6-8%
 regression of SPEC2000 GAP)

	PR middle-end/77484
	* predict.def (PRED_CALL): Update hitrate.
	(PRED_INDIR_CALL, PRED_POLYMORPHIC_CALL): New predictors.
	* predict.c (tree_estimate_probability_bb): Split CALL predictor
	into direct/indirect/polymorphic variants.

From-SVN: r243995
---
 gcc/ChangeLog   | 8 ++++++++
 gcc/predict.c   | 7 ++++++-
 gcc/predict.def | 8 +++++++-
 3 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 07e5c3e592a3..a5767870bcab 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2017-01-01  Jan Hubicka  <hubicka@ucw.cz>
+
+	PR middle-end/77484
+	* predict.def (PRED_CALL): Update hitrate.
+	(PRED_INDIR_CALL, PRED_POLYMORPHIC_CALL): New predictors.
+	* predict.c (tree_estimate_probability_bb): Split CALL predictor
+	into direct/indirect/polymorphic variants.
+
 2017-01-01  Jakub Jelinek  <jakub@redhat.com>
 
 	Update copyright years.
diff --git a/gcc/predict.c b/gcc/predict.c
index 82177abeb891..e85573bc51dd 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -2786,7 +2786,12 @@ tree_estimate_probability_bb (basic_block bb)
 		     something exceptional.  */
 		  && gimple_has_side_effects (stmt))
 		{
-		  predict_edge_def (e, PRED_CALL, NOT_TAKEN);
+		  if (gimple_call_fndecl (stmt))
+		    predict_edge_def (e, PRED_CALL, NOT_TAKEN);
+		  else if (virtual_method_call_p (gimple_call_fn (stmt)))
+		    predict_edge_def (e, PRED_POLYMORPHIC_CALL, TAKEN);
+		  else
+		    predict_edge_def (e, PRED_INDIR_CALL, TAKEN);
 		  break;
 		}
 	    }
diff --git a/gcc/predict.def b/gcc/predict.def
index c151ce2104fc..b6b2a402b22e 100644
--- a/gcc/predict.def
+++ b/gcc/predict.def
@@ -116,7 +116,13 @@ DEF_PREDICTOR (PRED_TREE_OPCODE_NONEQUAL, "opcode values nonequal (on trees)",
 DEF_PREDICTOR (PRED_TREE_FPOPCODE, "fp_opcode (on trees)", HITRATE (90), 0)
 
 /* Branch guarding call is probably taken.  */
-DEF_PREDICTOR (PRED_CALL, "call", HITRATE (67), 0)
+DEF_PREDICTOR (PRED_CALL, "call", HITRATE (55), 0)
+
+/* PRED_CALL is not very reliable predictor and it turns out to be even
+   less reliable for indirect calls and polymorphic calls.  For spec2k6
+   the predictio nis slightly in the direction of taking the call.  */
+DEF_PREDICTOR (PRED_INDIR_CALL, "indirect call", HITRATE (51), 0)
+DEF_PREDICTOR (PRED_POLYMORPHIC_CALL, "polymorphic call", HITRATE (58), 0)
 
 /* Recursive calls are usually not taken or the function will recurse
    indefinitely.  */
-- 
GitLab