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 --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  <dmalc...@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  <dmalc...@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.  */
            }
-- 
1.7.11.7

Reply via email to