From add6b58ae5d18ef9645c9135ada6dbe679812293 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Thu, 27 Mar 2014 12:22:33 -0400
Subject: [PATCH 77/89] Concretize various expressions from gimple to
 gimple_cond

gcc/
	* ipa-split.c (check_forbidden_calls): Replace check against
	GIMPLE_COND with a dyn_cast_gimple_cond, introducing a gimple_cond
	local.
	* predict.c (predict_extra_loop_exits): Likewise.
	* tree-vrp.c (fold_predicate_in): Likewise.
	(simplify_stmt_for_jump_threading): Likewise.

	* predict.c (is_comparison_with_loop_invariant_p): Require a
	gimple_cond.
	(predict_iv_comparison): Add checked cast to gimple_cond once we
	know the code is GIMPLE_COND.
	(predict_loops): Change type of "stmt" to gimple_cond,
	adding checked casts to its assignments (which are both guarded by
	checks against GIMPLE_COND).

	* tree-vrp.c (find_conditional_asserts): Require a gimple_cond.
	(vrp_evaluate_conditional): Likewise.
	(find_assert_locations_1): Add checked cast to gimple_cond.
	(vrp_visit_stmt): Likewise.
---
 gcc/ipa-split.c |  5 +++--
 gcc/predict.c   | 21 ++++++++++++++-------
 gcc/tree-vrp.c  | 25 +++++++++++++------------
 3 files changed, 30 insertions(+), 21 deletions(-)

diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
index 1287757..0808f9c 100644
--- a/gcc/ipa-split.c
+++ b/gcc/ipa-split.c
@@ -326,9 +326,10 @@ check_forbidden_calls (gimple stmt)
       basic_block use_bb, forbidden_bb;
       enum tree_code code;
       edge true_edge, false_edge;
-      gimple use_stmt = USE_STMT (use_p);
+      gimple_cond use_stmt;
 
-      if (gimple_code (use_stmt) != GIMPLE_COND)
+      use_stmt = USE_STMT (use_p)->dyn_cast_gimple_cond ();
+      if (!use_stmt)
 	continue;
 
       /* Assuming canonical form for GIMPLE_COND here, with constant
diff --git a/gcc/predict.c b/gcc/predict.c
index 7fa31d8..c3ab183 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -1107,7 +1107,7 @@ get_base_value (tree t)
    Otherwise return false and set LOOP_INVAIANT to NULL.  */
 
 static bool
-is_comparison_with_loop_invariant_p (gimple stmt, struct loop *loop,
+is_comparison_with_loop_invariant_p (gimple_cond stmt, struct loop *loop,
 				     tree *loop_invariant,
 				     enum tree_code *compare_code,
 				     tree *loop_step,
@@ -1272,7 +1272,8 @@ predict_iv_comparison (struct loop *loop, basic_block bb,
   stmt = last_stmt (bb);
   if (!stmt || gimple_code (stmt) != GIMPLE_COND)
     return;
-  if (!is_comparison_with_loop_invariant_p (stmt, loop, &compare_var,
+  if (!is_comparison_with_loop_invariant_p (stmt->as_a_gimple_cond (),
+					    loop, &compare_var,
 					    &compare_code,
 					    &compare_step_var,
 					    &compare_base))
@@ -1465,10 +1466,16 @@ predict_extra_loop_exits (edge exit_edge)
   gimple lhs_def_stmt;
   gimple_phi phi_stmt;
   tree cmp_rhs, cmp_lhs;
-  gimple cmp_stmt = last_stmt (exit_edge->src);
+  gimple last;
+  gimple_cond cmp_stmt;
 
-  if (!cmp_stmt || gimple_code (cmp_stmt) != GIMPLE_COND)
+  last = last_stmt (exit_edge->src);
+  if (!last)
+    return;
+  cmp_stmt = last->dyn_cast_gimple_cond ();
+  if (!cmp_stmt)
     return;
+
   cmp_rhs = gimple_cond_rhs (cmp_stmt);
   cmp_lhs = gimple_cond_lhs (cmp_stmt);
   if (!TREE_CONSTANT (cmp_rhs)
@@ -1535,7 +1542,7 @@ predict_loops (void)
       tree loop_bound_step = NULL;
       tree loop_bound_var = NULL;
       tree loop_iv_base = NULL;
-      gimple stmt = NULL;
+      gimple_cond stmt = NULL;
 
       exits = get_loop_exit_edges (loop);
       n_exits = exits.length ();
@@ -1602,12 +1609,12 @@ predict_loops (void)
 	if (nb_iter->stmt
 	    && gimple_code (nb_iter->stmt) == GIMPLE_COND)
 	  {
-	    stmt = nb_iter->stmt;
+	    stmt = nb_iter->stmt->as_a_gimple_cond ();
 	    break;
 	  }
       if (!stmt && last_stmt (loop->header)
 	  && gimple_code (last_stmt (loop->header)) == GIMPLE_COND)
-	stmt = last_stmt (loop->header);
+	stmt = last_stmt (loop->header)->as_a_gimple_cond ();
       if (stmt)
 	is_comparison_with_loop_invariant_p (stmt, loop,
 					     &loop_bound_var,
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 62ec9f5..5b701a6 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -5584,7 +5584,7 @@ register_edge_assert_for (tree name, edge e, gimple_stmt_iterator si,
    list of assertions for the corresponding operands.  */
 
 static bool
-find_conditional_asserts (basic_block bb, gimple last)
+find_conditional_asserts (basic_block bb, gimple_cond last)
 {
   bool need_assert;
   gimple_stmt_iterator bsi;
@@ -5826,7 +5826,7 @@ find_assert_locations_1 (basic_block bb, sbitmap live)
       && gimple_code (last) == GIMPLE_COND
       && !fp_predicate (last)
       && !ZERO_SSA_OPERANDS (last, SSA_OP_USE))
-    need_assert |= find_conditional_asserts (bb, last);
+    need_assert |= find_conditional_asserts (bb, last->as_a_gimple_cond ());
 
   /* If BB's last statement is a switch statement involving integer
      operands, determine if we need to add ASSERT_EXPRs.  */
@@ -7200,7 +7200,7 @@ vrp_evaluate_conditional (enum tree_code code, tree op0, tree op1, gimple stmt)
    SSA_PROP_VARYING.  */
 
 static enum ssa_prop_result
-vrp_visit_cond_stmt (gimple stmt, edge *taken_edge_p)
+vrp_visit_cond_stmt (gimple_cond stmt, edge *taken_edge_p)
 {
   tree val;
   bool sop;
@@ -7613,7 +7613,7 @@ vrp_visit_stmt (gimple stmt, edge *taken_edge_p, tree *output_p)
   else if (is_gimple_assign (stmt) || is_gimple_call (stmt))
     return vrp_visit_assignment_or_call (stmt, output_p);
   else if (gimple_code (stmt) == GIMPLE_COND)
-    return vrp_visit_cond_stmt (stmt, taken_edge_p);
+    return vrp_visit_cond_stmt (stmt->as_a_gimple_cond (), taken_edge_p);
   else if (gimple_code (stmt) == GIMPLE_SWITCH)
     return vrp_visit_switch_stmt (stmt->as_a_gimple_switch (), taken_edge_p);
 
@@ -9490,10 +9490,10 @@ fold_predicate_in (gimple_stmt_iterator *si)
 				      gimple_assign_rhs2 (stmt),
 				      stmt);
     }
-  else if (gimple_code (stmt) == GIMPLE_COND)
-    val = vrp_evaluate_conditional (gimple_cond_code (stmt),
-				    gimple_cond_lhs (stmt),
-				    gimple_cond_rhs (stmt),
+  else if (gimple_cond cond_stmt = stmt->dyn_cast_gimple_cond ())
+    val = vrp_evaluate_conditional (gimple_cond_code (cond_stmt),
+				    gimple_cond_lhs (cond_stmt),
+				    gimple_cond_rhs (cond_stmt),
 				    stmt);
   else
     return false;
@@ -9558,10 +9558,11 @@ static vec<tree> equiv_stack;
 static tree
 simplify_stmt_for_jump_threading (gimple stmt, gimple within_stmt)
 {
-  if (gimple_code (stmt) == GIMPLE_COND)
-    return vrp_evaluate_conditional (gimple_cond_code (stmt),
-				     gimple_cond_lhs (stmt),
-				     gimple_cond_rhs (stmt), within_stmt);
+  if (gimple_cond cond_stmt = stmt->dyn_cast_gimple_cond ())
+    return vrp_evaluate_conditional (gimple_cond_code (cond_stmt),
+				     gimple_cond_lhs (cond_stmt),
+				     gimple_cond_rhs (cond_stmt),
+				     within_stmt);
 
   if (gimple_assign assign_stmt = stmt->dyn_cast_gimple_assign ())
     {
-- 
1.8.5.3

