aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-loop-ivopts.c
diff options
context:
space:
mode:
authorBin Cheng <bin.cheng@arm.com>2016-03-31 08:57:13 +0000
committerBin Cheng <amker@gcc.gnu.org>2016-03-31 08:57:13 +0000
commit515558b8ff520dc07f1014b29e524b8994f73c9b (patch)
tree1967f313b30922e5e778e4db78b085e6d6488726 /gcc/tree-ssa-loop-ivopts.c
parentefc3536f46d9c96daf1f12b587edc583445c3902 (diff)
downloadgcc-515558b8ff520dc07f1014b29e524b8994f73c9b.zip
gcc-515558b8ff520dc07f1014b29e524b8994f73c9b.tar.gz
gcc-515558b8ff520dc07f1014b29e524b8994f73c9b.tar.bz2
tree-ssa-loop-ivopts.c (struct comp_cost): New scrach field.
* 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. From-SVN: r234612
Diffstat (limited to 'gcc/tree-ssa-loop-ivopts.c')
-rw-r--r--gcc/tree-ssa-loop-ivopts.c57
1 files changed, 47 insertions, 10 deletions
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index 29c4ba4c..c8a8406 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,