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.c...@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. 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) 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; }