diff options
Diffstat (limited to 'gcc/tree-ssa-loop-ivopts.c')
-rw-r--r-- | gcc/tree-ssa-loop-ivopts.c | 36 |
1 files changed, 27 insertions, 9 deletions
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c index 094e9cc8fe2..46356588c94 100644 --- a/gcc/tree-ssa-loop-ivopts.c +++ b/gcc/tree-ssa-loop-ivopts.c @@ -813,7 +813,7 @@ determine_base_object (tree expr) if (!base) return expr; - if (TREE_CODE (base) == INDIRECT_REF) + if (TREE_CODE (base) == MEM_REF) return determine_base_object (TREE_OPERAND (base, 0)); return fold_convert (ptr_type_node, @@ -1694,9 +1694,11 @@ find_interesting_uses_address (struct ivopts_data *data, gimple stmt, tree *op_p tree *ref = &TREE_OPERAND (base, 0); while (handled_component_p (*ref)) ref = &TREE_OPERAND (*ref, 0); - if (TREE_CODE (*ref) == INDIRECT_REF) + if (TREE_CODE (*ref) == MEM_REF) { - tree tem = gimple_fold_indirect_ref (TREE_OPERAND (*ref, 0)); + tree tem = fold_binary (MEM_REF, TREE_TYPE (*ref), + TREE_OPERAND (*ref, 0), + TREE_OPERAND (*ref, 1)); if (tem) *ref = tem; } @@ -2018,7 +2020,8 @@ strip_offset_1 (tree expr, bool inside_addr, bool top_compref, expr = build_fold_addr_expr (op0); return fold_convert (orig_type, expr); - case INDIRECT_REF: + case MEM_REF: + /* ??? Offset operand? */ inside_addr = false; break; @@ -2936,6 +2939,20 @@ get_computation (struct loop *loop, struct iv_use *use, struct iv_cand *cand) return get_computation_at (loop, use, cand, use->stmt); } +/* Adjust the cost COST for being in loop setup rather than loop body. + If we're optimizing for space, the loop setup overhead is constant; + if we're optimizing for speed, amortize it over the per-iteration cost. */ +static unsigned +adjust_setup_cost (struct ivopts_data *data, unsigned cost) +{ + if (cost == INFTY) + return cost; + else if (optimize_loop_for_speed_p (data->current_loop)) + return cost / AVG_LOOP_NITER (data->current_loop); + else + return cost; +} + /* Returns cost of addition in MODE. */ static unsigned @@ -3848,8 +3865,8 @@ get_computation_cost_at (struct ivopts_data *data, /* Symbol + offset should be compile-time computable so consider that they are added once to the variable, if present. */ if (var_present && (symbol_present || offset)) - cost.cost += add_cost (TYPE_MODE (ctype), speed) - / AVG_LOOP_NITER (data->current_loop); + cost.cost += adjust_setup_cost (data, + add_cost (TYPE_MODE (ctype), speed)); /* Having offset does not affect runtime cost in case it is added to symbol, but it increases complexity. */ @@ -3861,6 +3878,7 @@ get_computation_cost_at (struct ivopts_data *data, aratio = ratio > 0 ? ratio : -ratio; if (aratio != 1) cost.cost += multiply_by_cost (aratio, TYPE_MODE (ctype), speed); + return cost; fallback: if (can_autoinc) @@ -3874,7 +3892,7 @@ fallback: return infinite_cost; if (address_p) - comp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (comp)), comp); + comp = build_simple_mem_ref (comp); return new_cost (computation_cost (comp, speed), 0); } @@ -4114,7 +4132,7 @@ determine_use_iv_cost_condition (struct ivopts_data *data, elim_cost = force_var_cost (data, bound, &depends_on_elim); /* The bound is a loop invariant, so it will be only computed once. */ - elim_cost.cost /= AVG_LOOP_NITER (data->current_loop); + elim_cost.cost = adjust_setup_cost (data, elim_cost.cost); } else elim_cost = infinite_cost; @@ -4361,7 +4379,7 @@ determine_iv_cost (struct ivopts_data *data, struct iv_cand *cand) cost_base = force_var_cost (data, base, NULL); cost_step = add_cost (TYPE_MODE (TREE_TYPE (base)), data->speed); - cost = cost_step + cost_base.cost / AVG_LOOP_NITER (current_loop); + cost = cost_step + adjust_setup_cost (data, cost_base.cost); /* Prefer the original ivs unless we may gain something by replacing it. The reason is to make debugging simpler; so this is not relevant for |