aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/jump.c87
-rw-r--r--gcc/rtl.h4
3 files changed, 99 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 684cf11..05c917f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+Mon May 15 21:45:36 MET DST 2000 Jan Hubicka <jh@suse.cz>
+
+ * jump.c (condjump_p): Mark as depreached.
+ (any_condump_p): New.
+ (any_uncondump_p): New.
+ (pc_set): New.
+ (safe_to_remove_jump_p): New.
+ * rtl.h (any_condump_p, any_uncondjump_p, pc_set
+ safe_to_remove_jump_p): Declare.
+
Mon May 15 21:07:20 MET DST 2000 Jan Hubicka <jh@suse.cz>
* calls.c: Re-install both patches reverted by last patch.
diff --git a/gcc/jump.c b/gcc/jump.c
index 4296759..3ea0767 100644
--- a/gcc/jump.c
+++ b/gcc/jump.c
@@ -2097,7 +2097,12 @@ simplejump_p (insn)
}
/* Return nonzero if INSN is a (possibly) conditional jump
- and nothing more. */
+ and nothing more.
+
+ Use this function is depreached, since we need to support
+ branch and compare insns. Use nontrivial_condjump_p instead
+ whenever possible.
+ */
int
condjump_p (insn)
@@ -2124,7 +2129,12 @@ condjump_p (insn)
}
/* Return nonzero if INSN is a (possibly) conditional jump inside a
- PARALLEL. */
+ PARALLEL.
+
+ Use this function is depreached, since we need to support
+ branch and compare insns. Use any_condjump_p instead
+ whenever possible.
+ */
int
condjump_in_parallel_p (insn)
@@ -2156,6 +2166,79 @@ condjump_in_parallel_p (insn)
return 0;
}
+/* Return set of PC if available NULL otherwise. */
+rtx
+pc_set (insn)
+ rtx insn;
+{
+ rtx pat;
+ if (GET_CODE (insn) != JUMP_INSN)
+ return NULL;
+ pat = PATTERN (insn);
+ /* The set is allowed to appear eighter as insn pattern or the first in
+ PARALLEL expression. */
+ if (GET_CODE (pat) == SET && GET_CODE (SET_DEST (pat)) == PC)
+ return pat;
+ if (GET_CODE (pat) == PARALLEL)
+ {
+ rtx set = XVECEXP (pat, 0, 0);
+ if (GET_CODE (set) == SET && GET_CODE (SET_DEST (set)) == PC)
+ return set;
+ }
+ return NULL;
+}
+
+/* Return true when insn in unconditional jump possibly boundled inside
+ PARALLEL. */
+int
+any_uncondjump_p (insn)
+ rtx insn;
+{
+ rtx x = pc_set (insn);
+ if (!x)
+ return 0;
+ if (GET_CODE (SET_SRC (x)) != LABEL_REF)
+ return 0;
+ return 1;
+}
+
+/* Return true when insn is conditional jump. This function work for
+ instructions containing PC sets in PARALLELs. The instruction may have
+ various other effects so before removing the jump you must verify
+ safe_to_remove_jump_p.
+
+ Note that unlike condjump_p it returns 0 for unconditionals jumps.
+ */
+int
+any_condjump_p (insn)
+ rtx insn;
+{
+ rtx x = pc_set (insn);
+ if (!x)
+ return 0;
+ if (XEXP (SET_SRC (x), 2) == pc_rtx
+ && (GET_CODE (XEXP (SET_SRC (x), 1)) == LABEL_REF
+ || GET_CODE (XEXP (SET_SRC (x), 1)) == RETURN))
+ return 1;
+ if (XEXP (SET_SRC (x), 1) == pc_rtx
+ && (GET_CODE (XEXP (SET_SRC (x), 2)) == LABEL_REF
+ || GET_CODE (XEXP (SET_SRC (x), 2)) == RETURN))
+ return 1;
+ return 0;
+}
+
+
+/* Return true when the condjump is safe to remove. */
+int
+safe_to_remove_jump_p (insn)
+ rtx insn;
+{
+ /* For non-single set insns we may remove set of the other registers. */
+ if (!pc_set (insn) || !single_set (insn))
+ return 0;
+ return 1;
+}
+
/* Return the label of a conditional jump. */
rtx
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 089d48b..1a42d90 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1511,6 +1511,10 @@ extern void cse_end_of_basic_block PARAMS ((rtx,
/* In jump.c */
extern int comparison_dominates_p PARAMS ((enum rtx_code, enum rtx_code));
extern int condjump_p PARAMS ((rtx));
+extern int any_condjump_p PARAMS ((rtx));
+extern int any_uncondjump_p PARAMS ((rtx));
+extern int safe_to_remove_jump_p PARAMS ((rtx));
+extern rtx pc_set PARAMS ((rtx));
extern rtx condjump_label PARAMS ((rtx));
extern int simplejump_p PARAMS ((rtx));
extern int returnjump_p PARAMS ((rtx));