diff options
author | bonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-05-08 06:51:12 +0000 |
---|---|---|
committer | bonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-05-08 06:51:12 +0000 |
commit | 68461c19b1f78e47c00a0b74b8b5ff2162d00112 (patch) | |
tree | 25983327877f8281329815e9a674e6f487f23d30 /gcc | |
parent | 6bcf3f711636e451acb6e02bf079ea9413ae924b (diff) | |
download | gcc-68461c19b1f78e47c00a0b74b8b5ff2162d00112.tar.gz |
2009-05-08 Paolo Bonzini <bonzini@gnu.org>
PR rtl-optimization/33928
* loop-invariant.c (struct use): Add addr_use_p.
(struct def): Add n_addr_uses.
(struct invariant): Add cheap_address.
(create_new_invariant): Set cheap_address.
(record_use): Accept df_ref. Set addr_use_p and update n_addr_uses.
(record_uses): Pass df_ref to record_use.
(get_inv_cost): Do not add inv->cost to comp_cost for cheap addresses used
only as such.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@147270 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/loop-invariant.c | 37 |
2 files changed, 38 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index abe70592493..e959348eb5a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2009-05-08 Paolo Bonzini <bonzini@gnu.org> + + PR rtl-optimization/33928 + * loop-invariant.c (struct use): Add addr_use_p. + (struct def): Add n_addr_uses. + (struct invariant): Add cheap_address. + (create_new_invariant): Set cheap_address. + (record_use): Accept df_ref. Set addr_use_p and update n_addr_uses. + (record_uses): Pass df_ref to record_use. + (get_inv_cost): Do not add inv->cost to comp_cost for cheap addresses used + only as such. + 2009-05-08 Kaz Kojima <kkojima@gcc.gnu.org> * config/sh/sh.c: Do not include c-pragma.h. diff --git a/gcc/loop-invariant.c b/gcc/loop-invariant.c index 82e18297e20..3d718b19f1d 100644 --- a/gcc/loop-invariant.c +++ b/gcc/loop-invariant.c @@ -71,7 +71,7 @@ struct use { rtx *pos; /* Position of the use. */ rtx insn; /* The insn in that the use occurs. */ - + unsigned addr_use_p; /* Whether the use occurs in an address. */ struct use *next; /* Next use in the list. */ }; @@ -82,6 +82,7 @@ struct def struct use *uses; /* The list of uses that are uniquely reached by it. */ unsigned n_uses; /* Number of such uses. */ + unsigned n_addr_uses; /* Number of uses in addresses. */ unsigned invno; /* The corresponding invariant. */ }; @@ -111,6 +112,9 @@ struct invariant /* Whether to move the invariant. */ bool move; + /* Whether the invariant is cheap when used as an address. */ + bool cheap_address; + /* Cost of the invariant. */ unsigned cost; @@ -679,9 +683,16 @@ create_new_invariant (struct def *def, rtx insn, bitmap depends_on, /* If the set is simple, usually by moving it we move the whole store out of the loop. Otherwise we save only cost of the computation. */ if (def) - inv->cost = rtx_cost (set, SET, speed); + { + inv->cost = rtx_cost (set, SET, speed); + inv->cheap_address = address_cost (SET_SRC (set), word_mode, + speed) < COSTS_N_INSNS (1); + } else - inv->cost = rtx_cost (SET_SRC (set), SET, speed); + { + inv->cost = rtx_cost (SET_SRC (set), SET, speed); + inv->cheap_address = false; + } inv->move = false; inv->reg = NULL_RTX; @@ -708,17 +719,19 @@ create_new_invariant (struct def *def, rtx insn, bitmap depends_on, /* Record USE at DEF. */ static void -record_use (struct def *def, rtx *use, rtx insn) +record_use (struct def *def, df_ref use) { struct use *u = XNEW (struct use); - gcc_assert (REG_P (*use)); - - u->pos = use; - u->insn = insn; + u->pos = DF_REF_REAL_LOC (use); + u->insn = DF_REF_INSN (use); + u->addr_use_p = (DF_REF_TYPE (use) == DF_REF_REG_MEM_LOAD + && DF_REF_TYPE (use) == DF_REF_REG_MEM_STORE); u->next = def->uses; def->uses = u; def->n_uses++; + if (u->addr_use_p) + def->n_addr_uses++; } /* Finds the invariants USE depends on and store them to the DEPENDS_ON @@ -865,14 +878,14 @@ record_uses (rtx insn) df_ref use = *use_rec; inv = invariant_for_use (use); if (inv) - record_use (inv->def, DF_REF_REAL_LOC (use), DF_REF_INSN (use)); + record_use (inv->def, use); } for (use_rec = DF_INSN_INFO_EQ_USES (insn_info); *use_rec; use_rec++) { df_ref use = *use_rec; inv = invariant_for_use (use); if (inv) - record_use (inv->def, DF_REF_REAL_LOC (use), DF_REF_INSN (use)); + record_use (inv->def, use); } } @@ -992,7 +1005,9 @@ get_inv_cost (struct invariant *inv, int *comp_cost, unsigned *regs_needed) inv->stamp = actual_stamp; (*regs_needed)++; - (*comp_cost) += inv->cost; + if (!inv->cheap_address + || inv->def->n_addr_uses < inv->def->n_uses) + (*comp_cost) += inv->cost; #ifdef STACK_REGS { |