aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/loop.c7
-rw-r--r--gcc/rtl.h1
-rw-r--r--gcc/rtlanal.c40
4 files changed, 50 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0912e02..e623248 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2000-05-18 Richard Henderson <rth@cygnus.com>
+
+ * rtlanal.c (insn_dependant_p, insn_dependant_p_1): New.
+ * rtl.h (insn_dependant_p): Declare it.
+ * loop.c (strength_reduce): Use it.
+
2000-05-18 Alexandre Oliva <aoliva@cygnus.com>
* config/mn10300/mn10300.c (expand_prologue, expand_epilogue):
diff --git a/gcc/loop.c b/gcc/loop.c
index d31dbeb..70c307a 100644
--- a/gcc/loop.c
+++ b/gcc/loop.c
@@ -4119,10 +4119,9 @@ strength_reduce (loop, insn_count, flags)
for (next = NEXT_INSN (dominator); ; next = NEXT_INSN (next))
{
- if ((INSN_P (next)
- && (reg_mentioned_p (giv, PATTERN (next))
- || reg_set_p (bl2->biv->src_reg, next)))
- || GET_CODE (next) == JUMP_INSN)
+ if (GET_CODE (next) == JUMP_INSN
+ || (INSN_P (next)
+ && insn_dependant_p (giv_insn, next)))
break;
#ifdef HAVE_cc0
if (! INSN_P (next)
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 1a42d90..4ab7407 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1212,6 +1212,7 @@ extern int modified_between_p PARAMS ((rtx, rtx, rtx));
extern int no_labels_between_p PARAMS ((rtx, rtx));
extern int no_jumps_between_p PARAMS ((rtx, rtx));
extern int modified_in_p PARAMS ((rtx, rtx));
+extern int insn_dependant_p PARAMS ((rtx, rtx));
extern int reg_set_p PARAMS ((rtx, rtx));
extern rtx single_set PARAMS ((rtx));
extern int multiple_sets PARAMS ((rtx));
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index 891799b..e9a9816 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -26,6 +26,7 @@ Boston, MA 02111-1307, USA. */
static int rtx_addr_can_trap_p PARAMS ((rtx));
static void reg_set_p_1 PARAMS ((rtx, rtx, void *));
+static void insn_dependant_p_1 PARAMS ((rtx, rtx, void *));
static void reg_set_last_1 PARAMS ((rtx, rtx, void *));
@@ -687,6 +688,45 @@ modified_in_p (x, insn)
return 0;
}
+
+/* Return true if anything in insn X is (anti,output,true) dependant on
+ anything in insn Y. */
+
+int
+insn_dependant_p (x, y)
+ rtx x, y;
+{
+ rtx tmp;
+
+ if (! INSN_P (x) || ! INSN_P (y))
+ abort ();
+
+ tmp = PATTERN (y);
+ note_stores (PATTERN (x), insn_dependant_p_1, &tmp);
+ if (tmp == NULL_RTX)
+ return 1;
+
+ tmp = PATTERN (x);
+ note_stores (PATTERN (y), insn_dependant_p_1, &tmp);
+ if (tmp == NULL_RTX)
+ return 1;
+
+ return 0;
+}
+
+/* A helper routine for insn_dependant_p called through note_stores. */
+
+static void
+insn_dependant_p_1 (x, pat, data)
+ rtx x;
+ rtx pat ATTRIBUTE_UNUSED;
+ void *data;
+{
+ rtx * pinsn = (rtx *) data;
+
+ if (*pinsn && reg_mentioned_p (x, *pinsn))
+ *pinsn = NULL_RTX;
+}
/* Given an INSN, return a SET expression if this insn has only a single SET.
It may also have CLOBBERs, USEs, or SET whose output