diff mbox

[gimple-classes,committed,03/92] Introduce gimple_cond and use it in various places

Message ID 1414442490-14841-4-git-send-email-dmalcolm@redhat.com
State New
Headers show

Commit Message

David Malcolm Oct. 27, 2014, 8:40 p.m. UTC
This corresponds to:
  [PATCH 04/89] Introduce gimple_cond and use it in various places
  https://gcc.gnu.org/ml/gcc-patches/2014-04/msg01153.html
from the original 89-patch kit

That earlier patch was approved by Jeff:
> 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.
in https://gcc.gnu.org/ml/gcc-patches/2014-05/msg00595.html

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.
	(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-ssa-pre.c (eliminate_dom_walker::before_dom_children):
	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/ChangeLog.gimple-classes | 66 ++++++++++++++++++++++++++++++++++++++++++++
 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                 | 31 +++++++++++++++++----
 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-pre.c           |  4 +--
 gcc/tree-ssa-threadedge.c    |  8 +++---
 gcc/tree-ssa-threadedge.h    |  2 +-
 gcc/tree-vrp.c               |  6 ++--
 17 files changed, 149 insertions(+), 49 deletions(-)
diff mbox

Patch

diff --git a/gcc/ChangeLog.gimple-classes b/gcc/ChangeLog.gimple-classes
index dc1edc86..a7d756e 100644
--- a/gcc/ChangeLog.gimple-classes
+++ b/gcc/ChangeLog.gimple-classes
@@ -1,5 +1,71 @@ 
 2014-10-24  David Malcolm  <dmalcolm@redhat.com>
 
+	Introduce gimple_cond and use it in various places
+
+	* 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.
+	(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-ssa-pre.c (eliminate_dom_walker::before_dom_children):
+	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.
+
+2014-10-24  David Malcolm  <dmalcolm@redhat.com>
+
 	Introduce gimple_bind and use it for accessors.
 
 	* coretypes.h (gimple_bind): New typedef.
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index b32dc15..200cda6 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -2070,7 +2070,7 @@  maybe_cleanup_end_of_block (edge e, rtx_insn *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;
@@ -5071,7 +5071,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, as_a <gimple_cond> (stmt));
 	  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 9beb07c..ae60592 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -90,6 +90,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 48a0658..9be0ab2 100644
--- a/gcc/gdbhooks.py
+++ b/gcc/gdbhooks.py
@@ -458,6 +458,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 a0ce0db..34dd32b 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -547,7 +547,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),
@@ -2925,7 +2925,7 @@  fold_stmt_1 (gimple_stmt_iterator *gsi, bool inplace)
       }
 
     case GIMPLE_COND:
-      changed |= fold_gimple_cond (stmt);
+      changed |= fold_gimple_cond (as_a <gimple_cond> (stmt));
       break;
 
     case GIMPLE_CALL:
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index d47236f..9995c87 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -819,7 +819,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,
@@ -2101,7 +2101,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, as_a <gimple_cond> (gs), spc, flags);
       break;
 
     case GIMPLE_LABEL:
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 64201f0..a75479a 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 = as_a <gimple_cond> (gimple_build_with_ops (GIMPLE_COND, pred_code, 4));
   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 812fc2a..9683bc2 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -770,6 +770,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.  */
 
@@ -814,6 +824,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;
@@ -1198,9 +1216,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);
@@ -3041,7 +3059,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);
@@ -3066,7 +3084,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);
@@ -3090,7 +3108,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 9f51a4d..d26596b 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -831,7 +831,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.
@@ -1003,7 +1003,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;
@@ -2326,7 +2326,7 @@  optimize_stmt (basic_block bb, gimple_stmt_iterator si)
     }
 
   if (gimple_code (stmt) == GIMPLE_COND)
-    canonicalize_comparison (stmt);
+    canonicalize_comparison (as_a <gimple_cond> (stmt));
 
   update_stmt_if_modified (stmt);
   opt_stats.num_stmts++;
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index d491bde..5d17f7b 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -503,7 +503,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);
@@ -3836,7 +3836,8 @@  pass_forwprop::execute (function *fun)
 	    case GIMPLE_COND:
 	      {
 		int did_something;
-		did_something = forward_propagate_into_gimple_cond (stmt);
+		did_something =
+		  forward_propagate_into_gimple_cond (as_a <gimple_cond> (stmt));
 		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 118e99c..43fd50b 100644
--- a/gcc/tree-ssa-ifcombine.c
+++ b/gcc/tree-ssa-ifcombine.c
@@ -202,7 +202,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;
 
@@ -311,7 +311,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;
 
@@ -342,18 +342,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 = as_a <gimple_cond> (inner_stmt);
 
-  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 = as_a <gimple_cond> (outer_stmt);
 
   /* 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 06f4a12..49631f6 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 = as_a <gimple_cond> (last);
 
   /* 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 (as_a <gimple_cond> (stmt),
+					       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 (as_a <gimple_cond> (stmt),
+					       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 = as_a <gimple_cond> (stmt);
+		  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-pre.c b/gcc/tree-ssa-pre.c
index 60ff70f..9deaa5e 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -4365,8 +4365,8 @@  eliminate_dom_walker::before_dom_children (basic_block b)
 	      fold_stmt (&gsi);
 	      stmt = gsi_stmt (gsi);
 	      if ((gimple_code (stmt) == GIMPLE_COND
-		   && (gimple_cond_true_p (stmt)
-		       || gimple_cond_false_p (stmt)))
+		   && (gimple_cond_true_p (as_a <gimple_cond> (stmt))
+		       || gimple_cond_false_p (as_a <gimple_cond> (stmt))))
 		  || (gimple_code (stmt) == GIMPLE_SWITCH
 		      && TREE_CODE (gimple_switch_index (stmt)) == INTEGER_CST))
 		el_todo |= TODO_cleanup_cfg;
diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
index 3dee5ba..0a04787 100644
--- a/gcc/tree-ssa-threadedge.c
+++ b/gcc/tree-ssa-threadedge.c
@@ -521,7 +521,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)
 {
@@ -802,7 +802,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,
@@ -950,7 +950,7 @@  thread_around_empty_blocks (edge taken_edge,
 
 static int
 thread_through_normal_block (edge e,
-			     gimple dummy_cond,
+			     gimple_cond dummy_cond,
 			     bool handle_dominating_asserts,
 			     vec<tree> *stack,
 			     tree (*simplify) (gimple, gimple),
@@ -1078,7 +1078,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 a014f21..3248ceb 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -9073,7 +9073,7 @@  range_fits_type_p (value_range_t *vr, unsigned dest_precision, signop dest_sgn)
    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);
@@ -9613,7 +9613,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 (as_a <gimple_cond> (stmt));
   else if (gimple_code (stmt) == GIMPLE_SWITCH)
     return simplify_switch_using_ranges (as_a <gimple_switch> (stmt));
   else if (is_gimple_call (stmt)
@@ -9757,7 +9757,7 @@  static void
 identify_jump_threads (void)
 {
   basic_block bb;
-  gimple dummy;
+  gimple_cond dummy;
   int i;
   edge e;