From 4c1ca1a143c63a7d9bdb29b282e11e0cd60da8ef Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Thu, 29 May 2014 14:38:27 -0400
Subject: [PATCH 5/5] Introduce rtx_jump_insn subclass of rtx_base_insn

gcc/
	* coretypes.h (rtx_jump_insn): Add forward declaration.

	* rtl.h (struct rtx_jump_insn): New subclass of rtx_base_insn,
	adding the invariant (GET_CODE (X) == JUMP_INSN).
	(is_a_helper <rtx_jump_insn *>::test): New.
	(emit_jump_insn_before): Strengthen return type from rtx to
	rtx_jump_insn *.
	(emit_jump_insn_before_noloc): Likewise.
	(emit_jump_insn_before_setloc): Likewise.
	(emit_jump_insn_after): Likewise.
	(emit_jump_insn_after_noloc): Likewise.
	(emit_jump_insn_after_setloc): Likewise.

	* emit-rtl.c (make_jump_insn_raw): Strengthen local "insn" from
	rtx to rtx_jump_insn *.
	(emit_jump_insn_before_noloc): Strengthen return type from rtx to
	rtx_jump_insn *, adding a checked cast on the result of the
	emit_pattern call.  We know this cast is legal since the result of
	emit pattern is the insn built using make_jump_insn_raw.
	(emit_jump_insn_after_noloc): Likewise.
	(emit_jump_insn_after_setloc): Likewise.
	(emit_jump_insn_after): Likewise.
	(emit_jump_insn_before_setloc): Likewise.
	(emit_jump_insn_before): Likewise.
---
 gcc/coretypes.h |  1 +
 gcc/emit-rtl.c  | 40 +++++++++++++++++++++++-----------------
 gcc/rtl.h       | 29 +++++++++++++++++++++++------
 3 files changed, 47 insertions(+), 23 deletions(-)

diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index 7b40e00..24ac50b 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -66,6 +66,7 @@ typedef const struct hwivec_def *const_hwivec;
    hierarchy.
    Where possible, keep this list in the same order as in rtl.def.  */
 class rtx_base_insn;
+  class rtx_jump_insn;
   class rtx_code_label;
   class rtx_note;
 
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 2060f3a..a6fa9ec 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -3802,9 +3802,9 @@ make_debug_insn_raw (rtx pattern)
 static rtx
 make_jump_insn_raw (rtx pattern)
 {
-  rtx insn;
+  rtx_jump_insn *insn;
 
-  insn = rtx_alloc (JUMP_INSN);
+  insn = as_a <rtx_jump_insn *> (rtx_alloc (JUMP_INSN));
   INSN_UID (insn) = cur_insn_uid++;
 
   PATTERN (insn) = pattern;
@@ -4312,11 +4312,12 @@ emit_insn_before_noloc (rtx x, rtx before, basic_block bb)
 /* Make an instruction with body X and code JUMP_INSN
    and output it before the instruction BEFORE.  */
 
-rtx
+rtx_jump_insn *
 emit_jump_insn_before_noloc (rtx x, rtx before)
 {
-  return emit_pattern_before_noloc (x, before, NULL_RTX, NULL,
-				    make_jump_insn_raw);
+  return as_a <rtx_jump_insn *> (
+	   emit_pattern_before_noloc (x, before, NULL_RTX, NULL,
+				      make_jump_insn_raw));
 }
 
 /* Make an instruction with body X and code CALL_INSN
@@ -4461,10 +4462,11 @@ emit_insn_after_noloc (rtx x, rtx after, basic_block bb)
 /* Make an insn of code JUMP_INSN with body X
    and output it after the insn AFTER.  */
 
-rtx
+rtx_jump_insn *
 emit_jump_insn_after_noloc (rtx x, rtx after)
 {
-  return emit_pattern_after_noloc (x, after, NULL, make_jump_insn_raw);
+  return as_a <rtx_jump_insn *> (
+	   emit_pattern_after_noloc (x, after, NULL, make_jump_insn_raw));
 }
 
 /* Make an instruction with body X and code CALL_INSN
@@ -4634,17 +4636,19 @@ emit_insn_after (rtx pattern, rtx after)
 }
 
 /* Like emit_jump_insn_after_noloc, but set INSN_LOCATION according to LOC.  */
-rtx
+rtx_jump_insn *
 emit_jump_insn_after_setloc (rtx pattern, rtx after, int loc)
 {
-  return emit_pattern_after_setloc (pattern, after, loc, make_jump_insn_raw);
+  return as_a <rtx_jump_insn *> (
+	   emit_pattern_after_setloc (pattern, after, loc, make_jump_insn_raw));
 }
 
 /* Like emit_jump_insn_after_noloc, but set INSN_LOCATION according to AFTER.  */
-rtx
+rtx_jump_insn *
 emit_jump_insn_after (rtx pattern, rtx after)
 {
-  return emit_pattern_after (pattern, after, true, make_jump_insn_raw);
+  return as_a <rtx_jump_insn *> (
+	   emit_pattern_after (pattern, after, true, make_jump_insn_raw));
 }
 
 /* Like emit_call_insn_after_noloc, but set INSN_LOCATION according to LOC.  */
@@ -4747,19 +4751,21 @@ emit_insn_before (rtx pattern, rtx before)
 }
 
 /* like emit_insn_before_noloc, but set INSN_LOCATION according to LOC.  */
-rtx
+rtx_jump_insn *
 emit_jump_insn_before_setloc (rtx pattern, rtx before, int loc)
 {
-  return emit_pattern_before_setloc (pattern, before, loc, false,
-				     make_jump_insn_raw);
+  return as_a <rtx_jump_insn *> (
+	   emit_pattern_before_setloc (pattern, before, loc, false,
+				       make_jump_insn_raw));
 }
 
 /* Like emit_jump_insn_before_noloc, but set INSN_LOCATION according to BEFORE.  */
-rtx
+rtx_jump_insn *
 emit_jump_insn_before (rtx pattern, rtx before)
 {
-  return emit_pattern_before (pattern, before, true, false,
-			      make_jump_insn_raw);
+  return as_a <rtx_jump_insn *> (
+	   emit_pattern_before (pattern, before, true, false,
+				make_jump_insn_raw));
 }
 
 /* Like emit_insn_before_noloc, but set INSN_LOCATION according to LOC.  */
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 89b48a2..3845153 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -426,6 +426,23 @@ struct GTY(()) rtx_base_insn : public rtx_def
 };
 
 /* An expression with the invariant that:
+     GET_CODE (X) == JUMP_INSN
+   i.e. a "jump_insn".  */
+
+struct GTY(()) rtx_jump_insn : public rtx_base_insn
+{
+  /* No extra fields, but adds invariant: (GET_CODE (X) == JUMP_INSN).  */
+};
+
+template <>
+template <>
+inline bool
+is_a_helper <rtx_jump_insn *>::test (rtx rt)
+{
+  return rt->code == JUMP_INSN;
+}
+
+/* An expression with the invariant that:
      GET_CODE (X) == CODE_LABEL
    i.e. a "code_label".  */
 
@@ -2139,9 +2156,9 @@ extern rtx assign_temp (tree, int, int);
 extern rtx emit_insn_before (rtx, rtx);
 extern rtx emit_insn_before_noloc (rtx, rtx, basic_block);
 extern rtx emit_insn_before_setloc (rtx, rtx, int);
-extern rtx emit_jump_insn_before (rtx, rtx);
-extern rtx emit_jump_insn_before_noloc (rtx, rtx);
-extern rtx emit_jump_insn_before_setloc (rtx, rtx, int);
+extern rtx_jump_insn *emit_jump_insn_before (rtx, rtx);
+extern rtx_jump_insn *emit_jump_insn_before_noloc (rtx, rtx);
+extern rtx_jump_insn *emit_jump_insn_before_setloc (rtx, rtx, int);
 extern rtx emit_call_insn_before (rtx, rtx);
 extern rtx emit_call_insn_before_noloc (rtx, rtx);
 extern rtx emit_call_insn_before_setloc (rtx, rtx, int);
@@ -2154,9 +2171,9 @@ extern rtx_note *emit_note_before (enum insn_note, rtx);
 extern rtx emit_insn_after (rtx, rtx);
 extern rtx emit_insn_after_noloc (rtx, rtx, basic_block);
 extern rtx emit_insn_after_setloc (rtx, rtx, int);
-extern rtx emit_jump_insn_after (rtx, rtx);
-extern rtx emit_jump_insn_after_noloc (rtx, rtx);
-extern rtx emit_jump_insn_after_setloc (rtx, rtx, int);
+extern rtx_jump_insn *emit_jump_insn_after (rtx, rtx);
+extern rtx_jump_insn *emit_jump_insn_after_noloc (rtx, rtx);
+extern rtx_jump_insn *emit_jump_insn_after_setloc (rtx, rtx, int);
 extern rtx emit_call_insn_after (rtx, rtx);
 extern rtx emit_call_insn_after_noloc (rtx, rtx);
 extern rtx emit_call_insn_after_setloc (rtx, rtx, int);
-- 
1.8.5.3

