From 5b92e1895eea1ea9a7eb69553af8d173bd62e134 Mon Sep 17 00:00:00 2001 From: Bin Cheng Date: Tue, 27 Oct 2015 05:26:27 +0000 Subject: [PATCH] loop-invariant.c (struct def): New field can_prop_to_addr_uses. * loop-invariant.c (struct def): New field can_prop_to_addr_uses. (inv_can_prop_to_addr_use): New function. (record_use): Call can_prop_to_addr_uses, set the new field. (get_inv_cost): Count cost if inv can't be propagated into its address uses. From-SVN: r229402 --- gcc/ChangeLog | 8 ++++++++ gcc/loop-invariant.c | 45 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9eb9f6c414f..0a2e2ad6232 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2015-10-27 Bin Cheng + + * loop-invariant.c (struct def): New field can_prop_to_addr_uses. + (inv_can_prop_to_addr_use): New function. + (record_use): Call can_prop_to_addr_uses, set the new field. + (get_inv_cost): Count cost if inv can't be propagated into its + address uses. + 2015-10-26 Doug Evans * config/linux.h (INCLUDE_DEFAULTS): Add INCLUDE_DEFAULTS_MUSL_LOCAL. diff --git a/gcc/loop-invariant.c b/gcc/loop-invariant.c index 52c8ae857c1..7ac38c68a94 100644 --- a/gcc/loop-invariant.c +++ b/gcc/loop-invariant.c @@ -99,6 +99,8 @@ struct def unsigned n_uses; /* Number of such uses. */ unsigned n_addr_uses; /* Number of uses in addresses. */ unsigned invno; /* The corresponding invariant. */ + bool can_prop_to_addr_uses; /* True if the corresponding inv can be + propagated into its address uses. */ }; /* The data stored for each invariant. */ @@ -762,6 +764,34 @@ create_new_invariant (struct def *def, rtx_insn *insn, bitmap depends_on, return inv; } +/* Given invariant DEF and its address USE, check if the corresponding + invariant expr can be propagated into the use or not. */ + +static bool +inv_can_prop_to_addr_use (struct def *def, df_ref use) +{ + struct invariant *inv; + rtx *pos = DF_REF_REAL_LOC (use), def_set; + rtx_insn *use_insn = DF_REF_INSN (use); + rtx_insn *def_insn; + bool ok; + + inv = invariants[def->invno]; + /* No need to check if address expression is expensive. */ + if (!inv->cheap_address) + return false; + + def_insn = inv->insn; + def_set = single_set (def_insn); + if (!def_set) + return false; + + validate_unshare_change (use_insn, pos, SET_SRC (def_set), true); + ok = verify_changes (0); + cancel_changes (0); + return ok; +} + /* Record USE at DEF. */ static void @@ -777,7 +807,16 @@ record_use (struct def *def, df_ref use) def->uses = u; def->n_uses++; if (u->addr_use_p) - def->n_addr_uses++; + { + /* Initialize propagation information if this is the first addr + use of the inv def. */ + if (def->n_addr_uses == 0) + def->can_prop_to_addr_uses = true; + + def->n_addr_uses++; + if (def->can_prop_to_addr_uses && !inv_can_prop_to_addr_use (def, use)) + def->can_prop_to_addr_uses = false; + } } /* Finds the invariants USE depends on and store them to the DEPENDS_ON @@ -1158,7 +1197,9 @@ get_inv_cost (struct invariant *inv, int *comp_cost, unsigned *regs_needed, if (!inv->cheap_address || inv->def->n_uses == 0 - || inv->def->n_addr_uses < inv->def->n_uses) + || inv->def->n_addr_uses < inv->def->n_uses + /* Count cost if the inv can't be propagated into address uses. */ + || !inv->def->can_prop_to_addr_uses) (*comp_cost) += inv->cost * inv->eqno; #ifdef STACK_REGS -- 2.30.2