diff options
author | mrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-01-13 19:14:33 +0000 |
---|---|---|
committer | mrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-01-13 19:14:33 +0000 |
commit | 0dd8cf9cc8350069e94a624959d1ad4487c46a8c (patch) | |
tree | 63472a8da3b4d5a6c33190c256b60a5710d30a18 /gcc/tree-ssa-loop-ivopts.c | |
parent | fe644b69d013e77c7fc2db2a9863969d4f564561 (diff) | |
parent | 69888cc76b4873822f5e48b66f69e9d20d19fc50 (diff) | |
download | gcc-0dd8cf9cc8350069e94a624959d1ad4487c46a8c.tar.gz |
Merge in trunk.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/wide-int@206584 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-loop-ivopts.c')
-rw-r--r-- | gcc/tree-ssa-loop-ivopts.c | 91 |
1 files changed, 40 insertions, 51 deletions
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c index d5b08566f6e..049da5fcdfa 100644 --- a/gcc/tree-ssa-loop-ivopts.c +++ b/gcc/tree-ssa-loop-ivopts.c @@ -1668,50 +1668,30 @@ constant_multiple_of (tree top, tree bot, widest_int *mul) } } -/* Returns true if memory reference REF with step STEP may be unaligned. */ +/* Return true if memory reference REF with step STEP may be unaligned. */ static bool may_be_unaligned_p (tree ref, tree step) { - tree base; - tree base_type; - HOST_WIDE_INT bitsize; - HOST_WIDE_INT bitpos; - tree toffset; - enum machine_mode mode; - int unsignedp, volatilep; - unsigned base_align; - /* TARGET_MEM_REFs are translated directly to valid MEMs on the target, thus they are not misaligned. */ if (TREE_CODE (ref) == TARGET_MEM_REF) return false; - /* The test below is basically copy of what expr.c:normal_inner_ref - does to check whether the object must be loaded by parts when - STRICT_ALIGNMENT is true. */ - base = get_inner_reference (ref, &bitsize, &bitpos, &toffset, &mode, - &unsignedp, &volatilep, true); - base_type = TREE_TYPE (base); - base_align = get_object_alignment (base); - base_align = MAX (base_align, TYPE_ALIGN (base_type)); + unsigned int align = TYPE_ALIGN (TREE_TYPE (ref)); - if (mode != BLKmode) - { - unsigned mode_align = GET_MODE_ALIGNMENT (mode); - - if (base_align < mode_align - || (bitpos % mode_align) != 0 - || (bitpos % BITS_PER_UNIT) != 0) - return true; - - if (toffset - && (highest_pow2_factor (toffset) * BITS_PER_UNIT) < mode_align) - return true; + unsigned HOST_WIDE_INT bitpos; + unsigned int ref_align; + get_object_alignment_1 (ref, &ref_align, &bitpos); + if (ref_align < align + || (bitpos % align) != 0 + || (bitpos % BITS_PER_UNIT) != 0) + return true; - if ((highest_pow2_factor (step) * BITS_PER_UNIT) < mode_align) - return true; - } + unsigned int trailing_zeros = tree_ctz (step); + if (trailing_zeros < HOST_BITS_PER_INT + && (1U << trailing_zeros) * BITS_PER_UNIT < align) + return true; return false; } @@ -5733,18 +5713,20 @@ iv_ca_extend (struct ivopts_data *data, struct iv_ca *ivs, } /* Try narrowing set IVS by removing CAND. Return the cost of - the new set and store the differences in DELTA. */ + the new set and store the differences in DELTA. START is + the candidate with which we start narrowing. */ static comp_cost iv_ca_narrow (struct ivopts_data *data, struct iv_ca *ivs, - struct iv_cand *cand, struct iv_ca_delta **delta) + struct iv_cand *cand, struct iv_cand *start, + struct iv_ca_delta **delta) { unsigned i, ci; struct iv_use *use; struct cost_pair *old_cp, *new_cp, *cp; bitmap_iterator bi; struct iv_cand *cnd; - comp_cost cost; + comp_cost cost, best_cost, acost; *delta = NULL; for (i = 0; i < n_iv_uses (data); i++) @@ -5755,13 +5737,15 @@ iv_ca_narrow (struct ivopts_data *data, struct iv_ca *ivs, if (old_cp->cand != cand) continue; - new_cp = NULL; + best_cost = iv_ca_cost (ivs); + /* Start narrowing with START. */ + new_cp = get_use_iv_cost (data, use, start); if (data->consider_all_candidates) { EXECUTE_IF_SET_IN_BITMAP (ivs->cands, 0, ci, bi) { - if (ci == cand->id) + if (ci == cand->id || (start && ci == start->id)) continue; cnd = iv_cand (data, ci); @@ -5770,20 +5754,21 @@ iv_ca_narrow (struct ivopts_data *data, struct iv_ca *ivs, if (!cp) continue; - if (!iv_ca_has_deps (ivs, cp)) - continue; - - if (!cheaper_cost_pair (cp, new_cp)) - continue; + iv_ca_set_cp (data, ivs, use, cp); + acost = iv_ca_cost (ivs); - new_cp = cp; + if (compare_costs (acost, best_cost) < 0) + { + best_cost = acost; + new_cp = cp; + } } } else { EXECUTE_IF_AND_IN_BITMAP (use->related_cands, ivs->cands, 0, ci, bi) { - if (ci == cand->id) + if (ci == cand->id || (start && ci == start->id)) continue; cnd = iv_cand (data, ci); @@ -5791,15 +5776,19 @@ iv_ca_narrow (struct ivopts_data *data, struct iv_ca *ivs, cp = get_use_iv_cost (data, use, cnd); if (!cp) continue; - if (!iv_ca_has_deps (ivs, cp)) - continue; - if (!cheaper_cost_pair (cp, new_cp)) - continue; + iv_ca_set_cp (data, ivs, use, cp); + acost = iv_ca_cost (ivs); - new_cp = cp; + if (compare_costs (acost, best_cost) < 0) + { + best_cost = acost; + new_cp = cp; + } } } + /* Restore to old cp for use. */ + iv_ca_set_cp (data, ivs, use, old_cp); if (!new_cp) { @@ -5841,7 +5830,7 @@ iv_ca_prune (struct ivopts_data *data, struct iv_ca *ivs, if (cand == except_cand) continue; - acost = iv_ca_narrow (data, ivs, cand, &act_delta); + acost = iv_ca_narrow (data, ivs, cand, except_cand, &act_delta); if (compare_costs (acost, best_cost) < 0) { |