diff options
author | amker <amker@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-03-31 08:57:13 +0000 |
---|---|---|
committer | amker <amker@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-03-31 08:57:13 +0000 |
commit | b020b4407787644f2fe7b1c8c5c8175fd6e06160 (patch) | |
tree | 1967f313b30922e5e778e4db78b085e6d6488726 /gcc/tree-ssa-loop-ivopts.c | |
parent | c689c252371e29c425a2d681c78c75cd07e22ee2 (diff) | |
download | gcc-b020b4407787644f2fe7b1c8c5c8175fd6e06160.tar.gz |
* tree-ssa-loop-ivopts.c (struct comp_cost): New scrach field.
(no_cost, infinite_cost): Initialize the new field.
(get_computation_cost_at): Record setup cost.
(determine_use_iv_cost_address): Skip cost computation for sub
uses if we can estimate it without losing accuracy.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@234612 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-loop-ivopts.c')
-rw-r--r-- | gcc/tree-ssa-loop-ivopts.c | 57 |
1 files changed, 47 insertions, 10 deletions
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c index 29c4ba4cf56..c8a8406134f 100644 --- a/gcc/tree-ssa-loop-ivopts.c +++ b/gcc/tree-ssa-loop-ivopts.c @@ -172,10 +172,11 @@ struct comp_cost the computation (in no concrete units -- complexity field should be larger for more complex expressions and addressing modes). */ + int scratch; /* Scratch used during cost computation. */ }; -static const comp_cost no_cost = {0, 0}; -static const comp_cost infinite_cost = {INFTY, INFTY}; +static const comp_cost no_cost = {0, 0, 0}; +static const comp_cost infinite_cost = {INFTY, INFTY, INFTY}; /* The candidate - cost pair. */ struct cost_pair @@ -4953,6 +4954,8 @@ get_computation_cost_at (struct ivopts_data *data, cost.cost += add_cost (data->speed, TYPE_MODE (ctype)); } + /* Record setup cost in scrach field. */ + cost.scratch = cost.cost; /* Set of invariants depended on by sub use has already been computed for the first use in the group. */ if (use->sub_id) @@ -5088,12 +5091,12 @@ determine_use_iv_cost_address (struct ivopts_data *data, struct iv_use *use, struct iv_cand *cand) { bitmap depends_on; - bool can_autoinc; + bool can_autoinc, first; int inv_expr_id = -1; struct iv_use *sub_use; - comp_cost sub_cost; comp_cost cost = get_computation_cost (data, use, cand, true, &depends_on, &can_autoinc, &inv_expr_id); + comp_cost sub_cost = cost; if (cand->ainc_use == use) { @@ -5105,13 +5108,47 @@ determine_use_iv_cost_address (struct ivopts_data *data, else if (cand->pos == IP_AFTER_USE || cand->pos == IP_BEFORE_USE) cost = infinite_cost; } - for (sub_use = use->next; - sub_use && !infinite_cost_p (cost); - sub_use = sub_use->next) + + if (!infinite_cost_p (cost) && use->next) { - sub_cost = get_computation_cost (data, sub_use, cand, true, NULL, - &can_autoinc, NULL); - cost = add_costs (cost, sub_cost); + first = true; + sub_use = use->next; + /* We don't want to add setup cost for sub-uses. */ + sub_cost.cost -= sub_cost.scratch; + /* Add cost for sub uses in group. */ + do + { + /* Compute cost for the first sub use with different offset to + the main use and add it afterwards. Costs for these uses + could be quite different. Given below uses in a group: + use 0 : {base + A + offset_0, step} + use 0.1: {base + A + offset_0, step} + use 0.2: {base + A + offset_1, step} + use 0.3: {base + A + offset_2, step} + when we need to compute costs with candidate: + cand 1 : {base + B + offset_0, step} + + The first sub use with different offset is use 0.2, its cost + is larger than cost of use 0/0.1 because we need to compute: + A - B + offset_1 - offset_0 + rather than: + A - B. */ + if (first && use->addr_offset != sub_use->addr_offset) + { + first = false; + sub_cost = get_computation_cost (data, sub_use, cand, true, + NULL, &can_autoinc, NULL); + if (infinite_cost_p (sub_cost)) + { + cost = infinite_cost; + break; + } + } + + cost = add_costs (cost, sub_cost); + sub_use = sub_use->next; + } + while (sub_use); } set_use_iv_cost (data, use, cand, cost, depends_on, NULL_TREE, ERROR_MARK, |