From 1bfdbb292206491f4874a8b3dfa2dbb2d0c833e3 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 8 May 2009 06:51:12 +0000 Subject: [PATCH] re PR rtl-optimization/33928 (30% performance slowdown in floating-point code caused by r118475) 2009-05-08 Paolo Bonzini 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. From-SVN: r147270 --- gcc/ChangeLog | 12 ++++++++++++ gcc/loop-invariant.c | 37 ++++++++++++++++++++++++++----------- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index abe7059..e959348 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2009-05-08 Paolo Bonzini + + 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 * config/sh/sh.c: Do not include c-pragma.h. diff --git a/gcc/loop-invariant.c b/gcc/loop-invariant.c index 82e1829..3d718b1 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 { -- 2.7.4