diff mbox

[gimple-classes,committed,10/10] Introduce gpredict subclass and use it for all gimple_predict_ accessors

Message ID 1414608480-32461-11-git-send-email-dmalcolm@redhat.com
State New
Headers show

Commit Message

David Malcolm Oct. 29, 2014, 6:48 p.m. UTC
gcc/ChangeLog.gimple-classes:
	* coretypes.h (struct gpredict): Add forward declaration.
	* doc/gimple.texi (Class hierarchy of GIMPLE statements): Add
	gpredict.
	* gimple-pretty-print.c (pp_gimple_stmt_1): Within case
	GIMPLE_PREDICT, add local "predict_stmt" via a checked cast and
	use it in place of "stmt".
	* gimple.c (gimple_build_predict): Strengthen return type and
	local "p" from gimple to gpredict *.
	* gimple.h (struct gpredict): New subclass of
	gimple_statement_base, adding invariant that code is
	GIMPLE_PREDICT.
	(is_a_helper <gpredict *>::test): New.
	(gimple_build_predict): Strengthen return type from gimple to
	gpredict *.
	(gimple_predict_predictor): Strengthen param from const_gimple to
	const gpredict *.
	(gimple_predict_outcome): Likewise.
	(gimple_predict_set_predictor): Strengthen param from gimple to
	gpredict *.
	(gimple_predict_set_outcome): Likewise.
	* predict.c (tree_bb_level_predictions): Convert check for
	GIMPLE_PREDICT to a dyn_cast, introducing local "predict_stmt" and
	using it in place of "stmt" for typesafety.
---
 gcc/ChangeLog.gimple-classes | 26 ++++++++++++++++++++++++++
 gcc/coretypes.h              |  1 +
 gcc/doc/gimple.texi          |  3 ++-
 gcc/gimple-pretty-print.c    | 18 +++++++++++-------
 gcc/gimple.c                 |  4 ++--
 gcc/gimple.h                 | 31 +++++++++++++++++++++++--------
 gcc/predict.c                |  7 ++++---
 7 files changed, 69 insertions(+), 21 deletions(-)
diff mbox

Patch

diff --git a/gcc/ChangeLog.gimple-classes b/gcc/ChangeLog.gimple-classes
index 07c12cd..7d9dfb3 100644
--- a/gcc/ChangeLog.gimple-classes
+++ b/gcc/ChangeLog.gimple-classes
@@ -1,5 +1,31 @@ 
 2014-10-29  David Malcolm  <dmalcolm@redhat.com>
 
+	* coretypes.h (struct gpredict): Add forward declaration.
+	* doc/gimple.texi (Class hierarchy of GIMPLE statements): Add
+	gpredict.
+	* gimple-pretty-print.c (pp_gimple_stmt_1): Within case
+	GIMPLE_PREDICT, add local "predict_stmt" via a checked cast and
+	use it in place of "stmt".
+	* gimple.c (gimple_build_predict): Strengthen return type and
+	local "p" from gimple to gpredict *.
+	* gimple.h (struct gpredict): New subclass of
+	gimple_statement_base, adding invariant that code is
+	GIMPLE_PREDICT.
+	(is_a_helper <gpredict *>::test): New.
+	(gimple_build_predict): Strengthen return type from gimple to
+	gpredict *.
+	(gimple_predict_predictor): Strengthen param from const_gimple to
+	const gpredict *.
+	(gimple_predict_outcome): Likewise.
+	(gimple_predict_set_predictor): Strengthen param from gimple to
+	gpredict *.
+	(gimple_predict_set_outcome): Likewise.
+	* predict.c (tree_bb_level_predictions): Convert check for
+	GIMPLE_PREDICT to a dyn_cast, introducing local "predict_stmt" and
+	using it in place of "stmt" for typesafety.
+
+2014-10-29  David Malcolm  <dmalcolm@redhat.com>
+
 	* gimple.h (gimple_eh_filter_types): Strengthen param from
 	const_gimple to const geh_filter *.
 	(gimple_eh_filter_types_ptr): Strengthen param from gimple to
diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index 6e9f7b2..190d9a1 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -120,6 +120,7 @@  struct gomp_sections;
 struct gomp_single;
 struct gomp_target;
 struct gomp_teams;
+struct gpredict;
 
 union section;
 typedef union section section;
diff --git a/gcc/doc/gimple.texi b/gcc/doc/gimple.texi
index de7345e..887710a 100644
--- a/gcc/doc/gimple.texi
+++ b/gcc/doc/gimple.texi
@@ -305,7 +305,8 @@  kinds, along with their relationships to @code{GSS_} values (layouts) and
      |    used for 4 codes: GIMPLE_ERROR_MARK
      |                      GIMPLE_NOP
      |                      GIMPLE_OMP_SECTIONS_SWITCH
-     |                      GIMPLE_PREDICT
+     + gpredict
+     |   code: GIMPLE_PREDICT
      |
      + gimple_statement_with_ops_base
      |   |    (no GSS layout)
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index 864f636..91a20d5 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -2248,13 +2248,17 @@  pp_gimple_stmt_1 (pretty_printer *buffer, gimple gs, int spc, int flags)
       break;
 
     case GIMPLE_PREDICT:
-      pp_string (buffer, "// predicted ");
-      if (gimple_predict_outcome (gs))
-	pp_string (buffer, "likely by ");
-      else
-	pp_string (buffer, "unlikely by ");
-      pp_string (buffer, predictor_name (gimple_predict_predictor (gs)));
-      pp_string (buffer, " predictor.");
+      {
+	gpredict *predict_stmt = as_a <gpredict *> (gs);
+	pp_string (buffer, "// predicted ");
+	if (gimple_predict_outcome (predict_stmt))
+	  pp_string (buffer, "likely by ");
+	else
+	  pp_string (buffer, "unlikely by ");
+	pp_string (buffer,
+		   predictor_name (gimple_predict_predictor (predict_stmt)));
+	pp_string (buffer, " predictor.");
+      }
       break;
 
     case GIMPLE_TRANSACTION:
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 1421afe..b58c9db 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -1136,10 +1136,10 @@  gimple_build_transaction (gimple_seq body, tree label)
 /* Build a GIMPLE_PREDICT statement.  PREDICT is one of the predictors from
    predict.def, OUTCOME is NOT_TAKEN or TAKEN.  */
 
-gimple
+gpredict *
 gimple_build_predict (enum br_predictor predictor, enum prediction outcome)
 {
-  gimple p = gimple_alloc (GIMPLE_PREDICT, 0);
+  gpredict *p = as_a <gpredict *> (gimple_alloc (GIMPLE_PREDICT, 0));
   /* Ensure all the predictors fit into the lower bits of the subcode.  */
   gcc_assert ((int) END_PREDICTORS <= GF_PREDICT_TAKEN);
   gimple_predict_set_predictor (p, predictor);
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 0b09165..582bbbb 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -834,6 +834,16 @@  struct GTY((tag("GSS_WITH_MEM_OPS")))
   /* no additional fields; this uses the layout for GSS_WITH_MEM_OPS. */
 };
 
+/* A statement with the invariant that
+      stmt->code == GIMPLE_PREDICT
+   i.e. a hint for branch prediction.  */
+
+struct GTY(())
+  gpredict : public gimple_statement_base
+{
+  /* no additional fields; this uses the layout for GSS_BASE. */
+};
+
 template <>
 template <>
 inline bool
@@ -1061,6 +1071,14 @@  is_a_helper <gphi *>::test (gimple gs)
 template <>
 template <>
 inline bool
+is_a_helper <gpredict *>::test (gimple gs)
+{
+  return gs->code == GIMPLE_PREDICT;
+}
+
+template <>
+template <>
+inline bool
 is_a_helper <greturn *>::test (gimple gs)
 {
   return gs->code == GIMPLE_RETURN;
@@ -1348,7 +1366,7 @@  gomp_teams *gimple_build_omp_teams (gimple_seq, tree);
 gomp_atomic_load *gimple_build_omp_atomic_load (tree, tree);
 gomp_atomic_store *gimple_build_omp_atomic_store (tree);
 gtransaction *gimple_build_transaction (gimple_seq, tree);
-gimple gimple_build_predict (enum br_predictor, enum prediction);
+gpredict *gimple_build_predict (enum br_predictor, enum prediction);
 extern void gimple_seq_add_stmt (gimple_seq *, gimple);
 extern void gimple_seq_add_stmt_without_update (gimple_seq *, gimple);
 void gimple_seq_add_seq (gimple_seq *, gimple_seq);
@@ -5438,9 +5456,8 @@  is_gimple_resx (const_gimple gs)
 /* Return the predictor of GIMPLE_PREDICT statement GS.  */
 
 static inline enum br_predictor
-gimple_predict_predictor (gimple gs)
+gimple_predict_predictor (const gpredict *gs)
 {
-  GIMPLE_CHECK (gs, GIMPLE_PREDICT);
   return (enum br_predictor) (gs->subcode & ~GF_PREDICT_TAKEN);
 }
 
@@ -5448,9 +5465,8 @@  gimple_predict_predictor (gimple gs)
 /* Set the predictor of GIMPLE_PREDICT statement GS to PREDICT.  */
 
 static inline void
-gimple_predict_set_predictor (gimple gs, enum br_predictor predictor)
+gimple_predict_set_predictor (gpredict *gs, enum br_predictor predictor)
 {
-  GIMPLE_CHECK (gs, GIMPLE_PREDICT);
   gs->subcode = (gs->subcode & GF_PREDICT_TAKEN)
 		       | (unsigned) predictor;
 }
@@ -5459,9 +5475,8 @@  gimple_predict_set_predictor (gimple gs, enum br_predictor predictor)
 /* Return the outcome of GIMPLE_PREDICT statement GS.  */
 
 static inline enum prediction
-gimple_predict_outcome (gimple gs)
+gimple_predict_outcome (const gpredict *gs)
 {
-  GIMPLE_CHECK (gs, GIMPLE_PREDICT);
   return (gs->subcode & GF_PREDICT_TAKEN) ? TAKEN : NOT_TAKEN;
 }
 
@@ -5469,7 +5484,7 @@  gimple_predict_outcome (gimple gs)
 /* Set the outcome of GIMPLE_PREDICT statement GS to OUTCOME.  */
 
 static inline void
-gimple_predict_set_outcome (gimple gs, enum prediction outcome)
+gimple_predict_set_outcome (gpredict *gs, enum prediction outcome)
 {
   GIMPLE_CHECK (gs, GIMPLE_PREDICT);
   if (outcome == TAKEN)
diff --git a/gcc/predict.c b/gcc/predict.c
index 352417a..fad0f10 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -2204,10 +2204,11 @@  tree_bb_level_predictions (void)
 		predict_paths_leading_to (bb, PRED_COLD_FUNCTION,
 					  NOT_TAKEN);
 	    }
-	  else if (gimple_code (stmt) == GIMPLE_PREDICT)
+	  else if (gpredict *predict_stmt = dyn_cast <gpredict *> (stmt))
 	    {
-	      predict_paths_leading_to (bb, gimple_predict_predictor (stmt),
-					gimple_predict_outcome (stmt));
+	      predict_paths_leading_to (bb,
+					gimple_predict_predictor (predict_stmt),
+					gimple_predict_outcome (predict_stmt));
 	      /* Keep GIMPLE_PREDICT around so early inlining will propagate
 	         hints to callers.  */
 	    }