From aaf3ce3e553c3bb85fe447691c9309f9522facb5 Mon Sep 17 00:00:00 2001 From: Dale Johannesen Date: Mon, 22 Dec 2003 18:23:15 +0000 Subject: [PATCH] re PR rtl-optimization/12828 (-floop-optimize is unstable on PowerPC (float to int conversion problem)) 2003-12-21 Dale Johannesen 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). From-SVN: r74935 --- gcc/ChangeLog | 7 +++++++ gcc/loop.c | 35 ++++++++++++++++++++++++++++++++++- gcc/regclass.c | 2 ++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 60244baf0c1..6d077413ed3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2003-12-22 Dale Johannesen + + 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). + 2003-12-22 Andrew Pinski PR c/9163 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)); } } diff --git a/gcc/regclass.c b/gcc/regclass.c index 439f9f6b773..2e4dc61be32 100644 --- a/gcc/regclass.c +++ b/gcc/regclass.c @@ -2406,6 +2406,8 @@ reg_scan_mark_refs (rtx x, rtx insn, int note_flag, unsigned int min_regno) REG_N_SETS (REGNO (reg))++; REG_N_REFS (REGNO (reg))++; } + else if (GET_CODE (reg) == MEM) + reg_scan_mark_refs (XEXP (reg, 0), insn, note_flag, min_regno); } break; -- 2.30.2