+Fri Feb 5 07:09:29 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * 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.
+
Fri Feb 5 06:55:15 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
* unroll.c (entire file): Remove tabs / spaces at end of lines.
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. */
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;
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
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;