+2014-07-03 Zhenqiang Chen <zhenqiang.chen@linaro.org>
+
+ * loop-invariant.c (struct invariant): Add a new member: eqno;
+ (find_identical_invariants): Update eqno;
+ (create_new_invariant): Init eqno;
+ (get_inv_cost): Compute comp_cost with eqno;
+
2014-07-02 Segher Boessenkool <segher@kernel.crashing.org>
* genconfig.c (have_rotate_flag, have_rotatert_flag): New variables.
/* The number of the invariant with the same value. */
unsigned eqto;
+ /* The number of invariants which eqto this. */
+ unsigned eqno;
+
/* If we moved the invariant out of the loop, the register that contains its
value. */
rtx reg;
struct invariant *dep;
rtx expr, set;
enum machine_mode mode;
+ struct invariant *tmp;
if (inv->eqto != ~0u)
return;
mode = GET_MODE (expr);
if (mode == VOIDmode)
mode = GET_MODE (SET_DEST (set));
- inv->eqto = find_or_insert_inv (eq, expr, mode, inv)->invno;
+
+ tmp = find_or_insert_inv (eq, expr, mode, inv);
+ inv->eqto = tmp->invno;
+
+ if (tmp->invno != inv->invno && inv->always_executed)
+ tmp->eqno++;
if (dump_file && inv->eqto != inv->invno)
fprintf (dump_file,
inv->invno = invariants.length ();
inv->eqto = ~0u;
+
+ /* Itself. */
+ inv->eqno = 1;
+
if (def)
def->invno = inv->invno;
invariants.safe_push (inv);
if (!inv->cheap_address
|| inv->def->n_addr_uses < inv->def->n_uses)
- (*comp_cost) += inv->cost;
+ (*comp_cost) += inv->cost * inv->eqno;
#ifdef STACK_REGS
{
--- /dev/null
+/* { dg-do compile { target { arm_thumb2_ok } } } */
+/* { dg-options "-O2 -fdump-rtl-loop2_invariant " } */
+
+int t1, t2, t3, t4, t5, t6, t7, t8, t9, t10;
+extern void foo2 (int *, int *, int *, int *, int *, int *);
+extern int foo3 (int, int, int, int, int, int);
+int foo (int a, int b, int c, int d)
+{
+ int i = a;
+
+ for (; i > 0; i += b)
+ {
+ if (a > 0x1234567)
+ foo2 (&t1, &t2, &t3, &t4, &t5, &t6);
+ foo2 (&t1, &t2, &t3, &t4, &t5, &t6);
+ if (b > 0x1234567)
+ foo2 (&t7, &t2, &t8, &t4, &t5, &t6);
+ foo2 (&t1, &t2, &t3, &t4, &t5, &t6);
+ if (c > 0x1234567)
+ foo2 (&t1, &t9, &t10, &t4, &t5, &t6);
+ t2 = t5 - d;
+ }
+
+ return foo3 (t1, t2, t3, t4, t5, t6);
+}
+
+/* { dg-final { scan-rtl-dump "Decided to move invariant 0" "loop2_invariant" } } */
+/* { dg-final { cleanup-rtl-dump "loop2_invariant" } } */
+