Sat Feb 13 11:53:12 1999 Jeffrey A Law (law@cygnus.com)
+ 1999-02-05 Michael Meissner <meissner@cygnus.com>
+ J"orn Rennecke <amylaar@cygnus.co.uk>
+ * loop.c (check_dbra_loop): A store using an address giv for which
+ we have no life information is not reversible.
+ * 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.
+
Sun Jan 31 13:22:02 1999 John Wehle (john@feith.com)
* i386.md (movsicc, movhicc, movsfcc, movdfcc,
movxfcc, movdicc): Delete unconstrained alternatives.
/* Index of first available slot in above array. */
static int loop_store_mems_idx;
+/* The insn where the first of these was found. */
+static rtx first_loop_store_insn;
+
/* Nonzero if we don't know what MEMs were changed in the current loop.
This happens if the loop contains a call (in which case `loop_has_call'
will also be set) or if we store into more than NUM_STORES MEMs. */
unknown_address_altered = 0;
loop_has_call = 0;
loop_has_volatile = 0;
+ first_loop_store_insn = NULL_RTX;
loop_store_mems_idx = 0;
num_mem_sets = 0;
loop_has_volatile = 1;
note_stores (PATTERN (insn), note_addr_stored);
+ if (! first_loop_store_insn && loop_store_mems_idx != 0)
+ first_loop_store_insn = 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], 0)));
+ {
+ struct induction *v;
+
+ reversible_mem_store
+ = (! unknown_address_altered
+ && ! invariant_p (XEXP (loop_store_mems[0], 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, loop_store_mems[0])
+ && (INSN_UID (v->insn) >= max_uid_for_loop
+ || (INSN_LUID (v->insn)
+ > INSN_LUID (first_loop_store_insn))))
+ reversible_mem_store = 0;
+ }
+ }
/* This code only acts for innermost loops. Also it simplifies
the memory address check by only reversing loops with