This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[tuples] Tuplify PREDICT_EXPR


Hi!

This patch gimplifies PREDICT_EXPR into a new GIMPLE_PREDICT gimple stmt
and handles it throughout the gimple passes.

Bootstrapped/regtested on x86_64-linux.  Ok for tuples?

2008-07-04  Jakub Jelinek  <jakub@redhat.com>

	* gimple.def (GIMPLE_PREDICT): New.
	* gimple.h: Update comment above GF_* flags.
	(GF_PREDICT_TAKEN): New.
	(gimple_build_predict): New prototype.
	(gimple_predict_predictor, gimple_predict_outcome,
	gimple_predict_set_predictor, gimple_predict_set_outcome): New
	inlines.
	* gimple.c (gss_for_code): Handle GIMPLE_PREDICT.
	(gimple_size, walk_gimple_op): Likewise.
	(gimple_build_predict): New function.
	* gimple-pretty-print.c (dump_gimple_stmt): Handle GIMPLE_PREDICT.
	* predict.c (tree_bb_level_predictions): Likewise.
	* cfgexpand.c (gimple_to_tree): Likewise.
	* tree-inline.c (estimate_num_insns): Likewise.
	* tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Likewise.
	* gimple-low.c (lower_stmt): Likewise.
	* tree-cfg.c (verify_types_in_gimple_seq_2): Likewise.
	(verify_types_in_gimple_stmt): Likewise.  Don't handle PREDICT_EXPR.
	* gimplify.c (gimplify_expr): Gimplify PREDICT_EXPR into
	GIMPLE_PREDICT.
	* expr.c (expand_expr_real): Don't handle PREDICT_EXPR.

--- gcc/gimple.c.jj	2008-07-02 14:25:10.000000000 +0200
+++ gcc/gimple.c	2008-07-04 13:08:18.000000000 +0200
@@ -129,6 +129,7 @@ gss_for_code (enum gimple_code code)
     case GIMPLE_CHANGE_DYNAMIC_TYPE:	return GSS_CHANGE_DYNAMIC_TYPE;
     case GIMPLE_OMP_ATOMIC_LOAD:	return GSS_OMP_ATOMIC_LOAD;
     case GIMPLE_OMP_ATOMIC_STORE:	return GSS_OMP_ATOMIC_STORE;
+    case GIMPLE_PREDICT:		return GSS_BASE;
     default:				gcc_unreachable ();
     }
 }
@@ -193,6 +194,8 @@ gimple_size (enum gimple_code code)
       return sizeof (struct gimple_statement_wce);
     case GIMPLE_CHANGE_DYNAMIC_TYPE:
       return sizeof (struct gimple_statement_with_ops);
+    case GIMPLE_PREDICT:
+      return sizeof (struct gimple_statement_base);
     default:
       break;
     }
@@ -1058,6 +1061,17 @@ gimple_build_omp_atomic_store (tree val)
   return p;
 }
 
+/* Build a GIMPLE_PREDICT statement.  */
+
+gimple
+gimple_build_predict (enum br_predictor predictor, enum prediction outcome)
+{
+  gimple p = gimple_alloc (GIMPLE_PREDICT, 0);
+  gimple_predict_set_predictor (p, predictor);
+  gimple_predict_set_outcome (p, outcome);
+  return p;
+}
+
 /* Return which gimple structure is used by T.  The enums here are defined
    in gsstruct.def.  */
 
@@ -1605,6 +1619,7 @@ walk_gimple_op (gimple stmt, walk_tree_f
     case GIMPLE_NOP:
     case GIMPLE_RESX:
     case GIMPLE_OMP_RETURN:
+    case GIMPLE_PREDICT:
       break;
 
     default:
--- gcc/gimple-pretty-print.c.jj	2008-06-27 18:54:54.000000000 +0200
+++ gcc/gimple-pretty-print.c	2008-07-04 13:16:44.000000000 +0200
@@ -1548,6 +1548,16 @@ dump_gimple_stmt (pretty_printer *buffer
       dump_gimple_resx (buffer, gs, spc, 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.");
+      break;
+
     default:
       GIMPLE_NIY;
     }
--- gcc/predict.c.jj	2008-07-02 11:37:20.000000000 +0200
+++ gcc/predict.c	2008-07-04 13:25:32.000000000 +0200
@@ -1346,13 +1346,12 @@ tree_bb_level_predictions (void)
 
   FOR_EACH_BB (bb)
     {
-      gimple_stmt_iterator bsi;
+      gimple_stmt_iterator gsi;
 
-      for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi);)
+      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
 	{
-	  gimple stmt = gsi_stmt (bsi);
+	  gimple stmt = gsi_stmt (gsi);
 	  tree decl;
-	  bool next = false;
 
 	  if (gimple_code (stmt) == GIMPLE_CALL)
 	    {
@@ -1366,19 +1365,15 @@ tree_bb_level_predictions (void)
 		predict_paths_leading_to (bb, PRED_COLD_FUNCTION,
 					  NOT_TAKEN);
 	    }
+	  else if (gimple_code (stmt) == GIMPLE_PREDICT)
+	    {
+	      predict_paths_leading_to (bb, gimple_predict_predictor (stmt),
+					gimple_predict_outcome (stmt));
+	      gsi_remove (&gsi, true);
+	      continue;
+	    }
 
-/* FIXME tuples */
-#if 0
-	case PREDICT_EXPR:
-	  predict_paths_leading_to (bb, PREDICT_EXPR_PREDICTOR (stmt),
-				    PREDICT_EXPR_OUTCOME (stmt));
-	  bsi_remove (&bsi, true);
-	  next = true;
-	  break;
-#endif
-
-	  if (!next)
-	    gsi_next (&bsi);
+	  gsi_next (&gsi);
 	}
     }
 }
--- gcc/gimple.h.jj	2008-07-03 13:06:31.000000000 +0200
+++ gcc/gimple.h	2008-07-04 13:41:52.000000000 +0200
@@ -86,8 +86,8 @@ enum gimple_rhs_class
    Values for the masks can overlap as long as the overlapping values
    are never used in the same statement class.
 
-   The maximum mask value that can be defined is 1 << 7 (i.e., each
-   statement code can hold up to 8 bitflags).
+   The maximum mask value that can be defined is 1 << 15 (i.e., each
+   statement code can hold up to 16 bitflags).
 
    Keep this list sorted.  */
 static const unsigned int GF_ASM_INPUT			= 1 << 0;
@@ -107,6 +107,8 @@ static const unsigned int GF_OMP_RETURN_
 
 static const unsigned int GF_OMP_SECTION_LAST		= 1 << 0;
 
+static const unsigned int GF_PREDICT_TAKEN		= 1 << 15;
+
 /* Masks for selecting a pass local flag (PLF) to work on.  These
    masks are used by gimple_set_plf and gimple_plf.  */
 enum plf_mask {
@@ -804,6 +806,7 @@ gimple gimple_build_omp_single (gimple_s
 gimple gimple_build_cdt (tree, tree);
 gimple gimple_build_omp_atomic_load (tree, tree);
 gimple gimple_build_omp_atomic_store (tree);
+gimple gimple_build_predict (enum br_predictor, enum prediction);
 enum gimple_statement_structure_enum gimple_statement_structure (gimple);
 enum gimple_statement_structure_enum gss_for_assign (enum tree_code);
 void sort_case_labels (VEC(tree,heap) *);
@@ -4008,6 +4011,50 @@ gimple_cdt_set_location (gimple gs, tree
 }
 
 
+/* Return the predictor of GIMPLE_PREDICT statement GS.  */
+
+static inline enum br_predictor
+gimple_predict_predictor (gimple gs)
+{
+  GIMPLE_CHECK (gs, GIMPLE_PREDICT);
+  return (enum br_predictor) (gs->gsbase.subcode & ~GF_PREDICT_TAKEN);
+}
+
+
+/* Set the predictor of GIMPLE_PREDICT statement GS to PREDICT.  */
+
+static inline void
+gimple_predict_set_predictor (gimple gs, enum br_predictor predictor)
+{
+  GIMPLE_CHECK (gs, GIMPLE_PREDICT);
+  gs->gsbase.subcode = (gs->gsbase.subcode & GF_PREDICT_TAKEN)
+		       | (unsigned) predictor;
+}
+
+
+/* Return the outcome of GIMPLE_PREDICT statement GS.  */
+
+static inline enum prediction
+gimple_predict_outcome (gimple gs)
+{
+  GIMPLE_CHECK (gs, GIMPLE_PREDICT);
+  return (gs->gsbase.subcode & GF_PREDICT_TAKEN) ? TAKEN : NOT_TAKEN;
+}
+
+
+/* Set the outcome of GIMPLE_PREDICT statement GS to OUTCOME.  */
+
+static inline void
+gimple_predict_set_outcome (gimple gs, enum prediction outcome)
+{
+  GIMPLE_CHECK (gs, GIMPLE_PREDICT);
+  if (outcome == TAKEN)
+    gs->gsbase.subcode |= GF_PREDICT_TAKEN;
+  else
+    gs->gsbase.subcode &= ~GF_PREDICT_TAKEN;
+}
+
+
 /* Return a new iterator pointing to GIMPLE_SEQ's first statement.  */
 
 static inline gimple_stmt_iterator
--- gcc/cfgexpand.c.jj	2008-06-30 10:54:01.000000000 +0200
+++ gcc/cfgexpand.c	2008-07-04 13:29:49.000000000 +0200
@@ -275,6 +275,7 @@ gimple_to_tree (gimple stmt)
     break;
 
     case GIMPLE_NOP:
+    case GIMPLE_PREDICT:
       t = build1 (NOP_EXPR, void_type_node, size_zero_node);
       break;
 
--- gcc/gimplify.c.jj	2008-07-02 12:49:47.000000000 +0200
+++ gcc/gimplify.c	2008-07-04 13:12:48.000000000 +0200
@@ -6417,9 +6417,12 @@ gimplify_expr (tree *expr_p, gimple_seq 
 			  gimple_build_goto (GOTO_DESTINATION (*expr_p)));
 	  break;
 
-	  /* Predictions are always gimplified.  */
 	case PREDICT_EXPR:
-	  goto out;
+	  gimplify_seq_add_stmt (pre_p,
+			gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p),
+					      PREDICT_EXPR_OUTCOME (*expr_p)));
+	  ret = GS_ALL_DONE;
+	  break;
 
 	case LABEL_EXPR:
 	  ret = GS_ALL_DONE;
--- gcc/tree-inline.c.jj	2008-07-03 18:39:35.000000000 +0200
+++ gcc/tree-inline.c	2008-07-04 13:46:24.000000000 +0200
@@ -2921,6 +2921,7 @@ estimate_num_insns (gimple stmt, eni_wei
     case GIMPLE_PHI:
     case GIMPLE_RETURN:
     case GIMPLE_CHANGE_DYNAMIC_TYPE:
+    case GIMPLE_PREDICT:
       return 0;
 
     case GIMPLE_ASM:
--- gcc/tree-ssa-dce.c.jj	2008-06-13 14:30:50.000000000 +0200
+++ gcc/tree-ssa-dce.c	2008-07-04 13:18:51.000000000 +0200
@@ -1,5 +1,5 @@
 /* Dead code elimination pass for the GNU compiler.
-   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
+   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008
    Free Software Foundation, Inc.
    Contributed by Ben Elliston <bje@redhat.com>
    and Andrew MacLeod <amacleod@redhat.com>
@@ -273,8 +273,8 @@ mark_stmt_if_obviously_necessary (gimple
      can then remove the block and labels.  */
   switch (gimple_code (stmt))
     {
-    /* FIXME tuples: case PREDICT_EXPR:*/
     /* FIXME tuples: remove GIMPLE_BIND*/
+    case GIMPLE_PREDICT:
     case GIMPLE_BIND:
     case GIMPLE_LABEL:
       mark_stmt_necessary (stmt, false);
--- gcc/expr.c.jj	2008-07-02 11:37:18.000000000 +0200
+++ gcc/expr.c	2008-07-04 13:30:37.000000000 +0200
@@ -7046,7 +7046,6 @@ expand_expr_real (tree exp, rtx target, 
 
   /* Handle ERROR_MARK before anybody tries to access its type.  */
   if (TREE_CODE (exp) == ERROR_MARK
-      || TREE_CODE (exp) == PREDICT_EXPR
       || (!GIMPLE_TUPLE_P (exp) && TREE_CODE (TREE_TYPE (exp)) == ERROR_MARK))
     {
       ret = CONST0_RTX (tmode);
--- gcc/gimple.def.jj	2008-06-27 18:54:54.000000000 +0200
+++ gcc/gimple.def	2008-07-04 12:49:03.000000000 +0200
@@ -343,6 +343,13 @@ DEFGSCODE(GIMPLE_OMP_SECTIONS_SWITCH, "g
    CLAUSES is a TREE_LIST node holding the associated clauses.  */
 DEFGSCODE(GIMPLE_OMP_SINGLE, "gimple_omp_single", NULL)
 
+/* GIMPLE_PREDICT <PREDICT, OUTCOME> specifies a hint for branch prediction.
+
+   PREDICT is one of the predictors from predict.def.
+
+   OUTCOME is NOT_TAKEN or TAKEN.  */
+DEFGSCODE(GIMPLE_PREDICT, "gimple_predict", NULL)
+
 /*  This node represents a cleanup expression.  It is ONLY USED INTERNALLY
     by the gimplifier as a placeholder for cleanups, and its uses will be
     cleaned up by the time gimplification is done.
--- gcc/tree-cfg.c.jj	2008-07-02 19:57:49.000000000 +0200
+++ gcc/tree-cfg.c	2008-07-04 13:47:48.000000000 +0200
@@ -3730,6 +3730,7 @@ verify_types_in_gimple_stmt (gimple stmt
       return verify_types_in_gimple_op (gimple_goto_dest (stmt));
 
     case GIMPLE_NOP:
+    case GIMPLE_PREDICT:
       return false;
 
     case GIMPLE_SWITCH:
@@ -3739,7 +3740,6 @@ verify_types_in_gimple_stmt (gimple stmt
       return verify_types_in_gimple_return (stmt);
 
     case GIMPLE_ASM:
-    case PREDICT_EXPR:
       return false;
 
     case GIMPLE_CHANGE_DYNAMIC_TYPE:
@@ -3803,6 +3803,7 @@ verify_types_in_gimple_seq_2 (gimple_seq
           case GIMPLE_NOP:
           case GIMPLE_RESX:
           case GIMPLE_OMP_RETURN:
+	  case GIMPLE_PREDICT:
             break;
 
 	default:
--- gcc/gimple-low.c.jj	2008-06-13 14:30:50.000000000 +0200
+++ gcc/gimple-low.c	2008-07-04 13:22:14.000000000 +0200
@@ -288,7 +288,7 @@ lower_stmt (gimple_stmt_iterator *gsi, s
     case GIMPLE_ASM:
     case GIMPLE_ASSIGN:
     case GIMPLE_GOTO:
-    /* FIXME tuples: case PREDICT_EXPR: */
+    case GIMPLE_PREDICT:
     case GIMPLE_LABEL:
     case GIMPLE_SWITCH:
     case GIMPLE_CHANGE_DYNAMIC_TYPE:

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]