summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorbonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4>2009-05-08 06:51:12 +0000
committerbonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4>2009-05-08 06:51:12 +0000
commit68461c19b1f78e47c00a0b74b8b5ff2162d00112 (patch)
tree25983327877f8281329815e9a674e6f487f23d30 /gcc
parent6bcf3f711636e451acb6e02bf079ea9413ae924b (diff)
downloadgcc-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/ChangeLog12
-rw-r--r--gcc/loop-invariant.c37
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
{