aboutsummaryrefslogtreecommitdiff
path: root/gcc/loop.c
diff options
context:
space:
mode:
authorJ"orn Rennecke <amylaar@cygnus.co.uk>1999-02-04 23:10:46 +0000
committerJoern Rennecke <amylaar@gcc.gnu.org>1999-02-04 23:10:46 +0000
commit2d4fde68c33a27b8125ab8afabcfc039eca51ab6 (patch)
treecec55d3649e704607bb5cb8a874ab831735923fb /gcc/loop.c
parenta5af23fe121ce80395777cd066f04699e56240e0 (diff)
downloadgcc-2d4fde68c33a27b8125ab8afabcfc039eca51ab6.zip
gcc-2d4fde68c33a27b8125ab8afabcfc039eca51ab6.tar.gz
gcc-2d4fde68c33a27b8125ab8afabcfc039eca51ab6.tar.bz2
loop.c (first_loop_store_insn): New file-scope variable.
* loop.c (first_loop_store_insn): New file-scope variable. (prescan_loop): Set it. (check_dbra_loop): Check if a store depends on a register that is set after the store. From-SVN: r25034
Diffstat (limited to 'gcc/loop.c')
-rw-r--r--gcc/loop.c29
1 files changed, 26 insertions, 3 deletions
diff --git a/gcc/loop.c b/gcc/loop.c
index f762936..abf90ce 100644
--- a/gcc/loop.c
+++ b/gcc/loop.c
@@ -173,6 +173,9 @@ static char *moved_once;
static rtx loop_store_mems;
+/* The insn where the first of these was found. */
+static rtx first_loop_store_insn;
+
typedef struct loop_mem_info {
rtx mem; /* The MEM itself. */
rtx reg; /* Corresponding pseudo, if any. */
@@ -2404,6 +2407,7 @@ prescan_loop (start, end)
loop_has_volatile = 0;
loop_has_tablejump = 0;
loop_store_mems = NULL_RTX;
+ first_loop_store_insn = NULL_RTX;
loop_mems_idx = 0;
num_mem_sets = 0;
@@ -2456,6 +2460,8 @@ prescan_loop (start, end)
loop_has_tablejump = 1;
note_stores (PATTERN (insn), note_addr_stored);
+ if (! first_loop_store_insn && loop_store_mems)
+ first_loop_store_insn = insn;
if (! loop_has_multiple_exit_targets
&& GET_CODE (insn) == JUMP_INSN
@@ -7682,9 +7688,26 @@ check_dbra_loop (loop_end, insn_count, loop_start, loop_info)
case, the insn should have been moved out of the loop. */
if (num_mem_sets == 1)
- reversible_mem_store
- = (! unknown_address_altered
- && ! invariant_p (XEXP (loop_store_mems, 0)));
+ {
+ struct induction *v;
+
+ reversible_mem_store
+ = (! unknown_address_altered
+ && ! invariant_p (XEXP (loop_store_mems, 0)));
+
+ /* If the store depends on a register that is set after the
+ store, it depends on the initial value, and is thus not
+ reversible. */
+ for (v = bl->giv; reversible_mem_store && v; v = v->next_iv)
+ {
+ if (v->giv_type == DEST_REG
+ && reg_mentioned_p (v->dest_reg,
+ XEXP (loop_store_mems, 0))
+ && (INSN_LUID (v->insn)
+ > INSN_LUID (first_loop_store_insn)))
+ reversible_mem_store = 0;
+ }
+ }
}
else
return 0;