diff mbox

[loop2_invariant,2/2] Change heuristics for identical invariants

Message ID CACgzC7BP1O2-VY-fgrSpE+fB+QcmYbVPibcUX_gpVDkS6YmA5A@mail.gmail.com
State New
Headers show

Commit Message

Zhenqiang Chen June 10, 2014, 9:23 a.m. UTC
Hi,

When analysing logs of loop2-invariant of eembc, I found the same
invariant occurred lots of times in a loop. But it was not selected
since its cost was not high and register pressure was high. Logs show
performance improvement by giving them higher priority to move.

The patch changes the heuristics to move identical invariants:
* add a new member eqno, which records the number of invariants eqto the inv.
* set its cost to: inv->cost * inv->eqno;
* compare with spill_cost if register pressure is high.

Bootstrap and no make check regression on X86-64.
Bootstrap and no make check regression on X86-64 with
flag_ira_loop_pressure = true.

OK for trunk?

Thanks!
-Zhenqiang

ChangeLog:
2014-06-10  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 wiht eqno;
        (gain_for_invariant): Take spill cost into account.

     return;
@@ -513,7 +517,12 @@ find_identical_invariants (invariant_htab_type
eq, struct invariant *inv)
   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,
@@ -725,6 +734,10 @@ create_new_invariant (struct def *def, rtx insn,
bitmap depends_on,

   inv->invno = invariants.length ();
   inv->eqto = ~0u;
+
+  /* Itself.  */
+  inv->eqno = 1;
+
   if (def)
     def->invno = inv->invno;
   invariants.safe_push (inv);
@@ -1107,7 +1120,7 @@ get_inv_cost (struct invariant *inv, int
*comp_cost, unsigned *regs_needed,

   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
   {
@@ -1243,7 +1256,13 @@ gain_for_invariant (struct invariant *inv,
unsigned *regs_needed,
                 + IRA_LOOP_RESERVED_REGS
                 - ira_class_hard_regs_num[cl];
       if (size_cost > 0)
-       return -1;
+       {
+         int spill_cost = target_spill_cost [speed] * (int) regs_needed[cl];
+         if (comp_cost <= spill_cost)
+           return -1;
+
+         return 2;
+       }
       else
        size_cost = 0;
     }

Comments

Steven Bosscher June 10, 2014, 11:16 a.m. UTC | #1
On Tue, Jun 10, 2014 at 11:23 AM, Zhenqiang Chen wrote:
>         * 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 wiht eqno;
>         (gain_for_invariant): Take spill cost into account.

Look OK except ...

> @@ -1243,7 +1256,13 @@ gain_for_invariant (struct invariant *inv,
> unsigned *regs_needed,
>                  + IRA_LOOP_RESERVED_REGS
>                  - ira_class_hard_regs_num[cl];
>        if (size_cost > 0)
> -       return -1;
> +       {
> +         int spill_cost = target_spill_cost [speed] * (int) regs_needed[cl];
> +         if (comp_cost <= spill_cost)
> +           return -1;
> +
> +         return 2;
> +       }
>        else
>         size_cost = 0;
>      }

... why "return 2", instead of just falling through to "return
comp_cost - size_cost;"?

Ciao!
Steven
diff mbox

Patch

diff --git a/gcc/loop-invariant.c b/gcc/loop-invariant.c
index 92388f5..c43206a 100644
--- a/gcc/loop-invariant.c
+++ b/gcc/loop-invariant.c
@@ -104,6 +104,9 @@  struct invariant
   /* 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;
@@ -498,6 +501,7 @@  find_identical_invariants (invariant_htab_type eq,
struct invariant *inv)
   struct invariant *dep;
   rtx expr, set;
   enum machine_mode mode;
+  struct invariant *tmp;

   if (inv->eqto != ~0u)