summaryrefslogtreecommitdiff
path: root/gcc/loop.c
diff options
context:
space:
mode:
authordalej <dalej@138bc75d-0d04-0410-961f-82ee72b054a4>2003-12-22 18:23:15 +0000
committerdalej <dalej@138bc75d-0d04-0410-961f-82ee72b054a4>2003-12-22 18:23:15 +0000
commit39fd0bce02fdba0eda01e58a107d8429693b394e (patch)
tree54dffb12fe06c5056af9026e7ba7552d76a17f05 /gcc/loop.c
parentfcbb2ca14b39556029f347b8e5c4ff52396db404 (diff)
downloadgcc-39fd0bce02fdba0eda01e58a107d8429693b394e.tar.gz
2003-12-21 Dale Johannesen <dalej@apple.com>
PR optimization/12828 * loop.c: Add find_regs_nested to look inside CLOBBER(MEM). (scan_loop): Call it. * regclass.c (reg_scan_mark_regs): Look inside CLOBBER(MEM). git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@74935 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/loop.c')
-rw-r--r--gcc/loop.c35
1 files changed, 34 insertions, 1 deletions
diff --git a/gcc/loop.c b/gcc/loop.c
index 58fc1a0ac4e..4ee83447a69 100644
--- a/gcc/loop.c
+++ b/gcc/loop.c
@@ -255,6 +255,7 @@ static void count_one_set (struct loop_regs *, rtx, rtx, rtx *);
static void note_addr_stored (rtx, rtx, void *);
static void note_set_pseudo_multiple_uses (rtx, rtx, void *);
static int loop_reg_used_before_p (const struct loop *, rtx, rtx);
+static rtx find_regs_nested (rtx, rtx);
static void scan_loop (struct loop*, int);
#if 0
static void replace_call_address (rtx, rtx, rtx);
@@ -573,6 +574,32 @@ next_insn_in_loop (const struct loop *loop, rtx insn)
return insn;
}
+/* Find any register references hidden inside X and add them to
+ the dependency list DEPS. This is used to look inside CLOBBER (MEM
+ when checking whether a PARALLEL can be pulled out of a loop. */
+
+static rtx
+find_regs_nested (rtx deps, rtx x)
+{
+ enum rtx_code code = GET_CODE (x);
+ if (code == REG)
+ deps = gen_rtx_EXPR_LIST (VOIDmode, x, deps);
+ else
+ {
+ const char *fmt = GET_RTX_FORMAT (code);
+ int i, j;
+ for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+ {
+ if (fmt[i] == 'e')
+ deps = find_regs_nested (deps, XEXP (x, i));
+ else if (fmt[i] == 'E')
+ for (j = 0; j < XVECLEN (x, i); j++)
+ deps = find_regs_nested (deps, XVECEXP (x, i, j));
+ }
+ }
+ return deps;
+}
+
/* Optimize one loop described by LOOP. */
/* ??? Could also move memory writes out of loops if the destination address
@@ -776,7 +803,9 @@ scan_loop (struct loop *loop, int flags)
}
/* For parallels, add any possible uses to the dependencies, as
- we can't move the insn without resolving them first. */
+ we can't move the insn without resolving them first.
+ MEMs inside CLOBBERs may also reference registers; these
+ count as implicit uses. */
if (GET_CODE (PATTERN (p)) == PARALLEL)
{
for (i = 0; i < XVECLEN (PATTERN (p), 0); i++)
@@ -786,6 +815,10 @@ scan_loop (struct loop *loop, int flags)
dependencies
= gen_rtx_EXPR_LIST (VOIDmode, XEXP (x, 0),
dependencies);
+ else if (GET_CODE (x) == CLOBBER
+ && GET_CODE (XEXP (x, 0)) == MEM)
+ dependencies = find_regs_nested (dependencies,
+ XEXP (XEXP (x, 0), 0));
}
}