diff mbox

[04/89] Introduce gimple_cond and use it in various places

Message ID 1398099480-49147-5-git-send-email-dmalcolm@redhat.com
State New
Headers show

Commit Message

David Malcolm April 21, 2014, 4:56 p.m. UTC
gcc/
	* coretypes.h (gimple_cond): New typedef.
	(const_gimple_cond): Likewise.

	* gimple.h (struct gimple_statement_cond): New subclass of
	gimple_statement_with_ops, adding the invariant that
	stmt->code == GIMPLE_COND.
	(gimple_statement_base::as_a_gimple_cond): New.
	(gimple_statement_base::dyn_cast_gimple_cond): New.
	(is_a_helper <gimple_statement_cond>::test): New.
	(gimple_build_cond): Return a gimple_cond, rather than just
	a gimple.
	(gimple_build_cond_from_tree): Likewise.

	* gdbhooks.py (build_pretty_printer): Add gimple_cond and its
	variants, using the gimple printer.

	* cfgexpand.c (expand_gimple_cond): Require a gimple_cond rather
	than just a gimple.
	* gimple.h (gimple_cond_set_condition_from_tree): Likewise.
	(gimple_cond_true_p): Likewise.
	(gimple_cond_false_p): Likewise.
	(gimple_cond_set_condition): Likewise.
	* gimple.c (gimple_cond_set_condition_from_tree): Likewise.
	* gimple-fold.c (fold_gimple_cond): Likewise.
	* gimple-pretty-print.c (dump_gimple_cond): Likewise.
	* tree-ssa-dom.c (canonicalize_comparison): Likewise.
	* tree-ssa-forwprop.c (forward_propagate_into_gimple_cond): Likewise.
	* tree-ssa-ifcombine.c (recognize_single_bit_test): Likewise.
	(recognize_bits_test): Likewise.
	* tree-ssa-threadedge.c (simplify_control_stmt_condition): Likewise.
	(thread_around_empty_blocks): Likewise.
	(thread_through_normal_block): Likewise.
	(thread_across_edge): Likewise.
	* tree-ssa-threadedge.h (thread_across_edge): Likewise.
	* tree-vrp.c (range_fits_type_p): Likewise.

	* cfgexpand.c (expand_gimple_basic_block): Add checked cast to
	gimple_cond in regions where a stmt is known to have code GIMPLE_COND.
	* gimple-fold.c (fold_stmt_1): Likewise.
	* gimple-pretty-print.c (pp_gimple_stmt_1): Likewise.
	* tree-ssa-dom.c (optimize_stmt): Likewise.
	* tree-ssa-forwprop.c (ssa_forward_propagate_and_combine): Likewise.
	* tree-ssa-loop-unswitch.c (tree_unswitch_single_loop): Likewise.
	* tree-vrp.c (simplify_stmt_using_ranges): Likewise.

	* cfgloopmanip.c (create_empty_loop_on_edge): Update local to be a
	gimple_cond.
	* tree-vrp.c (identify_jump_threads): Likewise.

	* gimple.c (gimple_build_cond): Return a gimple_cond, rather than
	just a gimple.
	(gimple_build_cond_from_tree): Likewise.

	* tree-ssa-dom.c (class dom_opt_dom_walker): Strengthen type of
	field "m_dummy_cond" from a plain gimple to a gimple_cond.

	* tree-ssa-ifcombine.c (ifcombine_ifandif): Introduce locals
	inner_stmt and outer_stmt so that inner_cond and outer_cond can be
	of type gimple_cond once we know that we have code == GIMPLE_COND.
	* tree-ssa-loop-unswitch.c (tree_may_unswitch_on): Introduce local
	"last" so that stmt can be of type gimple_cond.
---
 gcc/cfgexpand.c              |  4 ++--
 gcc/cfgloopmanip.c           |  2 +-
 gcc/coretypes.h              |  4 ++++
 gcc/gdbhooks.py              |  2 ++
 gcc/gimple-fold.c            |  4 ++--
 gcc/gimple-pretty-print.c    |  4 ++--
 gcc/gimple.c                 | 10 +++++-----
 gcc/gimple.h                 | 43 +++++++++++++++++++++++++++++++++++++------
 gcc/tree-ssa-dom.c           |  6 +++---
 gcc/tree-ssa-forwprop.c      |  5 +++--
 gcc/tree-ssa-ifcombine.c     | 21 ++++++++++++---------
 gcc/tree-ssa-loop-unswitch.c | 19 ++++++++++++-------
 gcc/tree-ssa-threadedge.c    |  8 ++++----
 gcc/tree-ssa-threadedge.h    |  2 +-
 gcc/tree-vrp.c               |  6 +++---
 15 files changed, 93 insertions(+), 47 deletions(-)

Comments

Jeff Law May 9, 2014, 2:13 p.m. UTC | #1
On 04/21/14 10:56, David Malcolm wrote:
> gcc/
> 	* coretypes.h (gimple_cond): New typedef.
> 	(const_gimple_cond): Likewise.
>
> 	* gimple.h (struct gimple_statement_cond): New subclass of
> 	gimple_statement_with_ops, adding the invariant that
> 	stmt->code == GIMPLE_COND.
> 	(gimple_statement_base::as_a_gimple_cond): New.
> 	(gimple_statement_base::dyn_cast_gimple_cond): New.
> 	(is_a_helper <gimple_statement_cond>::test): New.
> 	(gimple_build_cond): Return a gimple_cond, rather than just
> 	a gimple.
> 	(gimple_build_cond_from_tree): Likewise.
>
> 	* gdbhooks.py (build_pretty_printer): Add gimple_cond and its
> 	variants, using the gimple printer.
>
> 	* cfgexpand.c (expand_gimple_cond): Require a gimple_cond rather
> 	than just a gimple.
> 	* gimple.h (gimple_cond_set_condition_from_tree): Likewise.
> 	(gimple_cond_true_p): Likewise.
> 	(gimple_cond_false_p): Likewise.
> 	(gimple_cond_set_condition): Likewise.
> 	* gimple.c (gimple_cond_set_condition_from_tree): Likewise.
> 	* gimple-fold.c (fold_gimple_cond): Likewise.
> 	* gimple-pretty-print.c (dump_gimple_cond): Likewise.
> 	* tree-ssa-dom.c (canonicalize_comparison): Likewise.
> 	* tree-ssa-forwprop.c (forward_propagate_into_gimple_cond): Likewise.
> 	* tree-ssa-ifcombine.c (recognize_single_bit_test): Likewise.
> 	(recognize_bits_test): Likewise.
> 	* tree-ssa-threadedge.c (simplify_control_stmt_condition): Likewise.
> 	(thread_around_empty_blocks): Likewise.
> 	(thread_through_normal_block): Likewise.
> 	(thread_across_edge): Likewise.
> 	* tree-ssa-threadedge.h (thread_across_edge): Likewise.
> 	* tree-vrp.c (range_fits_type_p): Likewise.
>
> 	* cfgexpand.c (expand_gimple_basic_block): Add checked cast to
> 	gimple_cond in regions where a stmt is known to have code GIMPLE_COND.
> 	* gimple-fold.c (fold_stmt_1): Likewise.
> 	* gimple-pretty-print.c (pp_gimple_stmt_1): Likewise.
> 	* tree-ssa-dom.c (optimize_stmt): Likewise.
> 	* tree-ssa-forwprop.c (ssa_forward_propagate_and_combine): Likewise.
> 	* tree-ssa-loop-unswitch.c (tree_unswitch_single_loop): Likewise.
> 	* tree-vrp.c (simplify_stmt_using_ranges): Likewise.
>
> 	* cfgloopmanip.c (create_empty_loop_on_edge): Update local to be a
> 	gimple_cond.
> 	* tree-vrp.c (identify_jump_threads): Likewise.
>
> 	* gimple.c (gimple_build_cond): Return a gimple_cond, rather than
> 	just a gimple.
> 	(gimple_build_cond_from_tree): Likewise.
>
> 	* tree-ssa-dom.c (class dom_opt_dom_walker): Strengthen type of
> 	field "m_dummy_cond" from a plain gimple to a gimple_cond.
>
> 	* tree-ssa-ifcombine.c (ifcombine_ifandif): Introduce locals
> 	inner_stmt and outer_stmt so that inner_cond and outer_cond can be
> 	of type gimple_cond once we know that we have code == GIMPLE_COND.
> 	* tree-ssa-loop-unswitch.c (tree_may_unswitch_on): Introduce local
> 	"last" so that stmt can be of type gimple_cond.
This is generally fine.  It needs minor tweaks due to the change in how 
we're handling const stuff, but otherwise it looks ready to go.

So, once you've flushed the queue of dependencies and reworked this to 
fit into the new world order, it's OK for the trunk.  Please post the 
final version for archival purposes.

jeff
diff mbox

Patch

diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 05ab95e..679933d 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -2007,7 +2007,7 @@  maybe_cleanup_end_of_block (edge e, rtx last)
    block and created a new one.  */
 
 static basic_block
-expand_gimple_cond (basic_block bb, gimple stmt)
+expand_gimple_cond (basic_block bb, gimple_cond stmt)
 {
   basic_block new_bb, dest;
   edge new_edge;
@@ -5014,7 +5014,7 @@  expand_gimple_basic_block (basic_block bb, bool disable_tail_calls)
 	 fixup the CFG accordingly.  */
       if (gimple_code (stmt) == GIMPLE_COND)
 	{
-	  new_bb = expand_gimple_cond (bb, stmt);
+	  new_bb = expand_gimple_cond (bb, stmt->as_a_gimple_cond ());
 	  if (new_bb)
 	    return new_bb;
 	}
diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c
index 83a0d51..3fa2535 100644
--- a/gcc/cfgloopmanip.c
+++ b/gcc/cfgloopmanip.c
@@ -776,7 +776,7 @@  create_empty_loop_on_edge (edge entry_edge,
   struct loop *loop;
   gimple_stmt_iterator gsi;
   gimple_seq stmts;
-  gimple cond_expr;
+  gimple_cond cond_expr;
   tree exit_test;
   edge exit_e;
   int prob;
diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index a39900f..68172f7 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -69,6 +69,10 @@  struct gimple_stmt_iterator;
 /* Typedefs for leaf gimple subclasses (for individual gimple codes).
    Keep this in the same order as the corresponding codes in gimple.def.  */
 
+struct gimple_statement_cond;
+typedef struct gimple_statement_cond *gimple_cond;
+typedef const struct gimple_statement_cond *const_gimple_cond;
+
 struct gimple_statement_switch;
 typedef struct gimple_statement_switch *gimple_switch;
 typedef const struct gimple_statement_switch *const_gimple_switch;
diff --git a/gcc/gdbhooks.py b/gcc/gdbhooks.py
index 5dcc76f..e45bdd2 100644
--- a/gcc/gdbhooks.py
+++ b/gcc/gdbhooks.py
@@ -457,6 +457,8 @@  def build_pretty_printer():
     pp.add_printer_for_types(['gimple', 'gimple_statement_base *',
 
                               # Keep this in the same order as gimple.def:
+                              'gimple_cond', 'const_gimple_cond',
+                              'gimple_statement_cond *',
                               'gimple_switch', 'const_gimple_switch',
                               'gimple_statement_switch *',
                               'gimple_bind', 'const_gimple_bind',
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 6402cce..59f7ada 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -602,7 +602,7 @@  fold_gimple_assign (gimple_stmt_iterator *si)
    assumed that the operands have been previously folded.  */
 
 static bool
-fold_gimple_cond (gimple stmt)
+fold_gimple_cond (gimple_cond stmt)
 {
   tree result = fold_binary_loc (gimple_location (stmt),
 			     gimple_cond_code (stmt),
@@ -1294,7 +1294,7 @@  fold_stmt_1 (gimple_stmt_iterator *gsi, bool inplace)
       }
 
     case GIMPLE_COND:
-      changed |= fold_gimple_cond (stmt);
+      changed |= fold_gimple_cond (stmt->as_a_gimple_cond ());
       break;
 
     case GIMPLE_CALL:
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index 22d927f..61824a6 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -809,7 +809,7 @@  dump_gimple_switch (pretty_printer *buffer, gimple_switch gs, int spc,
    pp_gimple_stmt_1.  */
 
 static void
-dump_gimple_cond (pretty_printer *buffer, gimple gs, int spc, int flags)
+dump_gimple_cond (pretty_printer *buffer, gimple_cond gs, int spc, int flags)
 {
   if (flags & TDF_RAW)
     dump_gimple_fmt (buffer, spc, flags, "%G <%s, %T, %T, %T, %T>", gs,
@@ -2107,7 +2107,7 @@  pp_gimple_stmt_1 (pretty_printer *buffer, gimple gs, int spc, int flags)
       break;
 
     case GIMPLE_COND:
-      dump_gimple_cond (buffer, gs, spc, flags);
+      dump_gimple_cond (buffer, gs->as_a_gimple_cond (), spc, flags);
       break;
 
     case GIMPLE_LABEL:
diff --git a/gcc/gimple.c b/gcc/gimple.c
index b3fbb0f..2cb5e2e 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -438,14 +438,14 @@  gimple_build_assign_with_ops (enum tree_code subcode, tree lhs, tree op1,
    T_LABEL is the label to jump to if the condition is true.
    F_LABEL is the label to jump to otherwise.  */
 
-gimple
+gimple_cond
 gimple_build_cond (enum tree_code pred_code, tree lhs, tree rhs,
 		   tree t_label, tree f_label)
 {
-  gimple p;
+  gimple_cond p;
 
   gcc_assert (TREE_CODE_CLASS (pred_code) == tcc_comparison);
-  p = gimple_build_with_ops (GIMPLE_COND, pred_code, 4);
+  p = gimple_build_with_ops (GIMPLE_COND, pred_code, 4)->as_a_gimple_cond ();
   gimple_cond_set_lhs (p, lhs);
   gimple_cond_set_rhs (p, rhs);
   gimple_cond_set_true_label (p, t_label);
@@ -456,7 +456,7 @@  gimple_build_cond (enum tree_code pred_code, tree lhs, tree rhs,
 /* Build a GIMPLE_COND statement from the conditional expression tree
    COND.  T_LABEL and F_LABEL are as in gimple_build_cond.  */
 
-gimple
+gimple_cond
 gimple_build_cond_from_tree (tree cond, tree t_label, tree f_label)
 {
   enum tree_code code;
@@ -470,7 +470,7 @@  gimple_build_cond_from_tree (tree cond, tree t_label, tree f_label)
    boolean expression tree COND.  */
 
 void
-gimple_cond_set_condition_from_tree (gimple stmt, tree cond)
+gimple_cond_set_condition_from_tree (gimple_cond stmt, tree cond)
 {
   enum tree_code code;
   tree lhs, rhs;
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 620495d..989f85a 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -214,6 +214,12 @@  public:
      Keep these in the same order as the corresponding entries in
      gimple.def.  */
 
+  inline gimple_cond
+  as_a_gimple_cond ()
+  {
+    return as_a <gimple_statement_cond> (this);
+  }
+
   inline gimple_switch
   as_a_gimple_switch ()
   {
@@ -234,6 +240,12 @@  public:
      is less verbose than
        dyn_cast <gimple_statement_foo> (stmt).  */
 
+  inline gimple_cond
+  dyn_cast_gimple_cond ()
+  {
+    return dyn_cast <gimple_statement_cond> (this);
+  }
+
   inline gimple_switch
   dyn_cast_gimple_switch ()
   {
@@ -812,6 +824,16 @@  enum gimple_statement_structure_enum {
 #undef DEFGSSTRUCT
 
 /* A statement with the invariant that
+      stmt->code == GIMPLE_COND
+   i.e. a conditional jump statement.  */
+
+struct GTY((tag("GSS_WITH_OPS")))
+  gimple_statement_cond : public gimple_statement_with_ops
+{
+  /* no additional fields; this uses the layout for GSS_WITH_OPS. */
+};
+
+/* A statement with the invariant that
       stmt->code == GIMPLE_SWITCH
    i.e. a switch statement.  */
 
@@ -856,6 +878,14 @@  is_a_helper <gimple_statement_catch>::test (gimple gs)
 template <>
 template <>
 inline bool
+is_a_helper <gimple_statement_cond>::test (gimple gs)
+{
+  return gs->code == GIMPLE_COND;
+}
+
+template <>
+template <>
+inline bool
 is_a_helper <gimple_statement_resx>::test (gimple gs)
 {
   return gs->code == GIMPLE_RESX;
@@ -1240,9 +1270,9 @@  gimple gimple_build_assign_with_ops (enum tree_code, tree,
 				     tree, tree, tree CXX_MEM_STAT_INFO);
 gimple gimple_build_assign_with_ops (enum tree_code, tree,
 				     tree, tree CXX_MEM_STAT_INFO);
-gimple gimple_build_cond (enum tree_code, tree, tree, tree, tree);
-gimple gimple_build_cond_from_tree (tree, tree, tree);
-void gimple_cond_set_condition_from_tree (gimple, tree);
+gimple_cond gimple_build_cond (enum tree_code, tree, tree, tree, tree);
+gimple_cond gimple_build_cond_from_tree (tree, tree, tree);
+void gimple_cond_set_condition_from_tree (gimple_cond, tree);
 gimple gimple_build_label (tree label);
 gimple gimple_build_goto (tree dest);
 gimple gimple_build_nop (void);
@@ -3050,7 +3080,7 @@  gimple_cond_make_true (gimple gs)
   'if (0 == 0)', 'if (1 != 0)' or 'if (0 != 1)' */
 
 static inline bool
-gimple_cond_true_p (const_gimple gs)
+gimple_cond_true_p (const_gimple_cond gs)
 {
   tree lhs = gimple_cond_lhs (gs);
   tree rhs = gimple_cond_rhs (gs);
@@ -3075,7 +3105,7 @@  gimple_cond_true_p (const_gimple gs)
    'if (0 != 0)', 'if (1 == 0)' or 'if (0 == 1)' */
 
 static inline bool
-gimple_cond_false_p (const_gimple gs)
+gimple_cond_false_p (const_gimple_cond gs)
 {
   tree lhs = gimple_cond_lhs (gs);
   tree rhs = gimple_cond_rhs (gs);
@@ -3099,7 +3129,8 @@  gimple_cond_false_p (const_gimple gs)
 /* Set the code, LHS and RHS of GIMPLE_COND STMT from CODE, LHS and RHS.  */
 
 static inline void
-gimple_cond_set_condition (gimple stmt, enum tree_code code, tree lhs, tree rhs)
+gimple_cond_set_condition (gimple_cond stmt, enum tree_code code, tree lhs,
+			   tree rhs)
 {
   gimple_cond_set_code (stmt, code);
   gimple_cond_set_lhs (stmt, lhs);
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index 2daddda..24099cc 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -823,7 +823,7 @@  public:
 private:
   void thread_across_edge (edge);
 
-  gimple m_dummy_cond;
+  gimple_cond m_dummy_cond;
 };
 
 /* Jump threading, redundancy elimination and const/copy propagation.
@@ -1004,7 +1004,7 @@  make_pass_dominator (gcc::context *ctxt)
    condition to a canonical form.  */
 
 static void
-canonicalize_comparison (gimple condstmt)
+canonicalize_comparison (gimple_cond condstmt)
 {
   tree op0;
   tree op1;
@@ -2340,7 +2340,7 @@  optimize_stmt (basic_block bb, gimple_stmt_iterator si)
     }
 
   if (gimple_code (stmt) == GIMPLE_COND)
-    canonicalize_comparison (stmt);
+    canonicalize_comparison (stmt->as_a_gimple_cond ());
 
   update_stmt_if_modified (stmt);
   opt_stats.num_stmts++;
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index d34ee1f..87e44b7 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -501,7 +501,7 @@  forward_propagate_into_comparison (gimple_stmt_iterator *gsi)
    This must be kept in sync with forward_propagate_into_cond.  */
 
 static int
-forward_propagate_into_gimple_cond (gimple stmt)
+forward_propagate_into_gimple_cond (gimple_cond stmt)
 {
   tree tmp;
   enum tree_code code = gimple_cond_code (stmt);
@@ -3790,7 +3790,8 @@  ssa_forward_propagate_and_combine (void)
 	    case GIMPLE_COND:
 	      {
 		int did_something;
-		did_something = forward_propagate_into_gimple_cond (stmt);
+		did_something =
+		  forward_propagate_into_gimple_cond (stmt->as_a_gimple_cond ());
 		if (did_something == 2)
 		  cfg_changed = true;
 		changed = did_something != 0;
diff --git a/gcc/tree-ssa-ifcombine.c b/gcc/tree-ssa-ifcombine.c
index be28fb0..1a060b5 100644
--- a/gcc/tree-ssa-ifcombine.c
+++ b/gcc/tree-ssa-ifcombine.c
@@ -198,7 +198,7 @@  get_name_for_bit_test (tree candidate)
    Returns true if the pattern matched, false otherwise.  */
 
 static bool
-recognize_single_bit_test (gimple cond, tree *name, tree *bit, bool inv)
+recognize_single_bit_test (gimple_cond cond, tree *name, tree *bit, bool inv)
 {
   gimple stmt;
 
@@ -306,7 +306,7 @@  recognize_single_bit_test (gimple cond, tree *name, tree *bit, bool inv)
    Returns true if the pattern matched, false otherwise.  */
 
 static bool
-recognize_bits_test (gimple cond, tree *name, tree *bits, bool inv)
+recognize_bits_test (gimple_cond cond, tree *name, tree *bits, bool inv)
 {
   gimple stmt;
 
@@ -337,18 +337,21 @@  ifcombine_ifandif (basic_block inner_cond_bb, bool inner_inv,
 		   basic_block outer_cond_bb, bool outer_inv, bool result_inv)
 {
   gimple_stmt_iterator gsi;
-  gimple inner_cond, outer_cond;
+  gimple inner_stmt, outer_stmt;
+  gimple_cond inner_cond, outer_cond;
   tree name1, name2, bit1, bit2, bits1, bits2;
 
-  inner_cond = last_stmt (inner_cond_bb);
-  if (!inner_cond
-      || gimple_code (inner_cond) != GIMPLE_COND)
+  inner_stmt = last_stmt (inner_cond_bb);
+  if (!inner_stmt
+      || gimple_code (inner_stmt) != GIMPLE_COND)
     return false;
+  inner_cond = inner_stmt->as_a_gimple_cond ();
 
-  outer_cond = last_stmt (outer_cond_bb);
-  if (!outer_cond
-      || gimple_code (outer_cond) != GIMPLE_COND)
+  outer_stmt = last_stmt (outer_cond_bb);
+  if (!outer_stmt
+      || gimple_code (outer_stmt) != GIMPLE_COND)
     return false;
+  outer_cond = outer_stmt->as_a_gimple_cond ();
 
   /* See if we test a single bit of the same name in both tests.  In
      that case remove the outer test, merging both else edges,
diff --git a/gcc/tree-ssa-loop-unswitch.c b/gcc/tree-ssa-loop-unswitch.c
index 5031378..03e6648 100644
--- a/gcc/tree-ssa-loop-unswitch.c
+++ b/gcc/tree-ssa-loop-unswitch.c
@@ -138,15 +138,17 @@  tree_ssa_unswitch_loops (void)
 static tree
 tree_may_unswitch_on (basic_block bb, struct loop *loop)
 {
-  gimple stmt, def;
+  gimple last, def;
+  gimple_cond stmt;
   tree cond, use;
   basic_block def_bb;
   ssa_op_iter iter;
 
   /* BB must end in a simple conditional jump.  */
-  stmt = last_stmt (bb);
-  if (!stmt || gimple_code (stmt) != GIMPLE_COND)
+  last = last_stmt (bb);
+  if (!last || gimple_code (last) != GIMPLE_COND)
     return NULL_TREE;
+  stmt = last->as_a_gimple_cond ();
 
   /* To keep the things simple, we do not directly remove the conditions,
      but just replace tests with 0 != 0 resp. 1 != 0.  Prevent the infinite
@@ -248,13 +250,15 @@  tree_unswitch_single_loop (struct loop *loop, int num)
       if (integer_nonzerop (cond))
 	{
 	  /* Remove false path.  */
-	  gimple_cond_set_condition_from_tree (stmt, boolean_true_node);
+	  gimple_cond_set_condition_from_tree (stmt->as_a_gimple_cond (),
+					       boolean_true_node);
 	  changed = true;
 	}
       else if (integer_zerop (cond))
 	{
 	  /* Remove true path.  */
-	  gimple_cond_set_condition_from_tree (stmt, boolean_false_node);
+	  gimple_cond_set_condition_from_tree (stmt->as_a_gimple_cond (),
+					       boolean_false_node);
 	  changed = true;
 	}
       /* Do not unswitch too much.  */
@@ -316,9 +320,10 @@  tree_unswitch_single_loop (struct loop *loop, int num)
 	      if (stmt
 		  && gimple_code (stmt) == GIMPLE_COND)
 		{
-		  if (gimple_cond_true_p (stmt))
+		  gimple_cond cond_stmt = stmt->as_a_gimple_cond ();
+		  if (gimple_cond_true_p (cond_stmt))
 		    flags = EDGE_FALSE_VALUE;
-		  else if (gimple_cond_false_p (stmt))
+		  else if (gimple_cond_false_p (cond_stmt))
 		    flags = EDGE_TRUE_VALUE;
 		}
 	    }
diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
index c447b72..ce1dee5 100644
--- a/gcc/tree-ssa-threadedge.c
+++ b/gcc/tree-ssa-threadedge.c
@@ -536,7 +536,7 @@  dummy_simplify (gimple stmt1 ATTRIBUTE_UNUSED, gimple stmt2 ATTRIBUTE_UNUSED)
 static tree
 simplify_control_stmt_condition (edge e,
 				 gimple stmt,
-				 gimple dummy_cond,
+				 gimple_cond dummy_cond,
 				 tree (*simplify) (gimple, gimple),
 				 bool handle_dominating_asserts)
 {
@@ -800,7 +800,7 @@  propagate_threaded_block_debug_into (basic_block dest, basic_block src)
    try and simplify the condition at the end of TAKEN_EDGE->dest.  */
 static bool
 thread_around_empty_blocks (edge taken_edge,
-			    gimple dummy_cond,
+			    gimple_cond dummy_cond,
 			    bool handle_dominating_asserts,
 			    tree (*simplify) (gimple, gimple),
 			    bitmap visited,
@@ -943,7 +943,7 @@  thread_around_empty_blocks (edge taken_edge,
 
 static bool
 thread_through_normal_block (edge e,
-			     gimple dummy_cond,
+			     gimple_cond dummy_cond,
 			     bool handle_dominating_asserts,
 			     vec<tree> *stack,
 			     tree (*simplify) (gimple, gimple),
@@ -1064,7 +1064,7 @@  thread_through_normal_block (edge e,
    SIMPLIFY is a pass-specific function used to simplify statements.  */
 
 void
-thread_across_edge (gimple dummy_cond,
+thread_across_edge (gimple_cond dummy_cond,
 		    edge e,
 		    bool handle_dominating_asserts,
 		    vec<tree> *stack,
diff --git a/gcc/tree-ssa-threadedge.h b/gcc/tree-ssa-threadedge.h
index f005607..7ad5691 100644
--- a/gcc/tree-ssa-threadedge.h
+++ b/gcc/tree-ssa-threadedge.h
@@ -30,7 +30,7 @@  extern void threadedge_initialize_values (void);
 extern void threadedge_finalize_values (void);
 extern bool potentially_threadable_block (basic_block);
 extern void propagate_threaded_block_debug_into (basic_block, basic_block);
-extern void thread_across_edge (gimple, edge, bool,
+extern void thread_across_edge (gimple_cond, edge, bool,
 				vec<tree> *, tree (*) (gimple, gimple));
 
 #endif /* GCC_TREE_SSA_THREADEDGE_H */
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 3a31d78..f9366b9 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -8920,7 +8920,7 @@  range_fits_type_p (value_range_t *vr, unsigned precision, bool unsigned_p)
    the original conditional.  */
 
 static bool
-simplify_cond_using_ranges (gimple stmt)
+simplify_cond_using_ranges (gimple_cond stmt)
 {
   tree op0 = gimple_cond_lhs (stmt);
   tree op1 = gimple_cond_rhs (stmt);
@@ -9459,7 +9459,7 @@  simplify_stmt_using_ranges (gimple_stmt_iterator *gsi)
 	}
     }
   else if (gimple_code (stmt) == GIMPLE_COND)
-    return simplify_cond_using_ranges (stmt);
+    return simplify_cond_using_ranges (stmt->as_a_gimple_cond ());
   else if (gimple_code (stmt) == GIMPLE_SWITCH)
     return simplify_switch_using_ranges (stmt->as_a_gimple_switch ());
   else if (is_gimple_call (stmt)
@@ -9603,7 +9603,7 @@  static void
 identify_jump_threads (void)
 {
   basic_block bb;
-  gimple dummy;
+  gimple_cond dummy;
   int i;
   edge e;