diff options
author | dalej <dalej@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-12-22 18:23:15 +0000 |
---|---|---|
committer | dalej <dalej@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-12-22 18:23:15 +0000 |
commit | 39fd0bce02fdba0eda01e58a107d8429693b394e (patch) | |
tree | 54dffb12fe06c5056af9026e7ba7552d76a17f05 /gcc/loop.c | |
parent | fcbb2ca14b39556029f347b8e5c4ff52396db404 (diff) | |
download | gcc-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.c | 35 |
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)); } } |