Enhance dumps of IVOPTS
* tree-ssa-loop-ivopts.c (avg_loop_niter): Fix coding style. (struct cost_pair): Change inv_expr_id (int) to inv_expr (iv_inv_expr_ent *). (struct iv_inv_expr_ent): Comment struct fields. (sort_iv_inv_expr_ent): New function. (struct ivopts_data): Rename inv_expr_id to max_inv_expr_id. (struct iv_ca): Replace used_inv_expr and num_used_inv_expr with a hash_map between iv_inv_expr_ent and number of usages. (niter_for_exit): Fix coding style. (tree_ssa_iv_optimize_init): Use renamed variable. (determine_base_object): Fix coding style. (alloc_iv): Likewise. (find_interesting_uses_outside): Likewise. (add_candidate_1): Likewise. (add_standard_iv_candidates): Likewise. (set_group_iv_cost): Replace inv_expr_id with inv_expr. (prepare_decl_rtl): Fix coding style. (get_address_cost): Likewise. (get_shiftadd_cost): Likewise. (force_expr_to_var_cost): Likewise. (compare_aff_trees): Likewise. (get_expr_id): Restructure the function. (get_loop_invariant_expr_id): Renamed to get_loop_invariant_expr. (get_computation_cost_at): Replace usage of inv_expr_id with inv_expr. (get_computation_cost): Likewise. (determine_group_iv_cost_generic): Likewise. (determine_group_iv_cost_address): Likewise. (iv_period): Fix coding style. (iv_elimination_compare_lt): Likewise. (may_eliminate_iv): Likewise. (determine_group_iv_cost_cond): Replace usage of inv_expr_id with inv_expr. (determine_group_iv_costs): Dump invariant expressions. (iv_ca_recount_cost): Use the newly added hash_map. (iv_ca_set_remove_invariants): Fix coding style. (iv_ca_set_add_invariants): Fix coding style. (iv_ca_set_no_cp): Utilize the newly added hash_map for used invariants. (iv_ca_set_cp): Likewise. (iv_ca_new): Initialize the newly added hash_map and remove initialization of fields. (iv_ca_free): Delete the hash_map. (iv_ca_dump): Dump invariant expressions. (iv_ca_extend): Fix coding style. (try_add_cand_for): Likewise. (create_new_ivs): Dump information about # of avg iterations and # of used invariant expressions. (rewrite_use_compare): Fix coding style. (free_loop_data): Set default value for max_inv_expr_id. * g++.dg/tree-ssa/ivopts-3.C: Change test-case to follow the new format of dump output. From-SVN: r236200
This commit is contained in:
parent
da7674f6a6
commit
623b8e0a86
4 changed files with 314 additions and 196 deletions
|
@ -1,3 +1,57 @@
|
|||
2016-05-13 Martin Liska <mliska@suse.cz>
|
||||
|
||||
* tree-ssa-loop-ivopts.c (avg_loop_niter): Fix coding style.
|
||||
(struct cost_pair): Change inv_expr_id (int) to inv_expr
|
||||
(iv_inv_expr_ent *).
|
||||
(struct iv_inv_expr_ent): Comment struct fields.
|
||||
(sort_iv_inv_expr_ent): New function.
|
||||
(struct ivopts_data): Rename inv_expr_id to max_inv_expr_id.
|
||||
(struct iv_ca): Replace used_inv_expr and num_used_inv_expr with
|
||||
a hash_map between iv_inv_expr_ent and number of usages.
|
||||
(niter_for_exit): Fix coding style.
|
||||
(tree_ssa_iv_optimize_init): Use renamed variable.
|
||||
(determine_base_object): Fix coding style.
|
||||
(alloc_iv): Likewise.
|
||||
(find_interesting_uses_outside): Likewise.
|
||||
(add_candidate_1): Likewise.
|
||||
(add_standard_iv_candidates): Likewise.
|
||||
(set_group_iv_cost): Replace inv_expr_id with inv_expr.
|
||||
(prepare_decl_rtl): Fix coding style.
|
||||
(get_address_cost): Likewise.
|
||||
(get_shiftadd_cost): Likewise.
|
||||
(force_expr_to_var_cost): Likewise.
|
||||
(compare_aff_trees): Likewise.
|
||||
(get_expr_id): Restructure the function.
|
||||
(get_loop_invariant_expr_id): Renamed to
|
||||
get_loop_invariant_expr.
|
||||
(get_computation_cost_at): Replace usage of inv_expr_id with
|
||||
inv_expr.
|
||||
(get_computation_cost): Likewise.
|
||||
(determine_group_iv_cost_generic): Likewise.
|
||||
(determine_group_iv_cost_address): Likewise.
|
||||
(iv_period): Fix coding style.
|
||||
(iv_elimination_compare_lt): Likewise.
|
||||
(may_eliminate_iv): Likewise.
|
||||
(determine_group_iv_cost_cond): Replace usage of inv_expr_id with
|
||||
inv_expr.
|
||||
(determine_group_iv_costs): Dump invariant expressions.
|
||||
(iv_ca_recount_cost): Use the newly added hash_map.
|
||||
(iv_ca_set_remove_invariants): Fix coding style.
|
||||
(iv_ca_set_add_invariants): Fix coding style.
|
||||
(iv_ca_set_no_cp): Utilize the newly added hash_map for used
|
||||
invariants.
|
||||
(iv_ca_set_cp): Likewise.
|
||||
(iv_ca_new): Initialize the newly added hash_map and remove
|
||||
initialization of fields.
|
||||
(iv_ca_free): Delete the hash_map.
|
||||
(iv_ca_dump): Dump invariant expressions.
|
||||
(iv_ca_extend): Fix coding style.
|
||||
(try_add_cand_for): Likewise.
|
||||
(create_new_ivs): Dump information about # of avg iterations and
|
||||
# of used invariant expressions.
|
||||
(rewrite_use_compare): Fix coding style.
|
||||
(free_loop_data): Set default value for max_inv_expr_id.
|
||||
|
||||
2016-05-13 Ilya Enkovich <ilya.enkovich@intel.com>
|
||||
|
||||
* cse.c (rest_of_handle_cse): Use cleanup_cfg
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2016-05-13 Martin Liska <mliska@suse.cz>
|
||||
|
||||
* g++.dg/tree-ssa/ivopts-3.C: Change test-case to follow
|
||||
the new format of dump output.
|
||||
|
||||
2016-05-13 Ilya Enkovich <ilya.enkovich@intel.com>
|
||||
|
||||
* gcc.dg/pr71084.c: New test.
|
||||
|
|
|
@ -72,4 +72,4 @@ int main ( int , char** ) {
|
|||
|
||||
// Verify that on x86_64 and i?86 we use a single IV for the innermost loop
|
||||
|
||||
// { dg-final { scan-tree-dump "Selected IV set for loop \[0-9\]* at \[^ \]*:64, 1 IVs" "ivopts" { target x86_64-*-* i?86-*-* } } }
|
||||
// { dg-final { scan-tree-dump "Selected IV set for loop \[0-9\]* at \[^ \]*:64, 3 avg niters, 1 expressions, 1 IVs" "ivopts" { target x86_64-*-* i?86-*-* } } }
|
||||
|
|
|
@ -129,7 +129,7 @@ avg_loop_niter (struct loop *loop)
|
|||
{
|
||||
niter = max_stmt_executions_int (loop);
|
||||
if (niter == -1 || niter > AVG_LOOP_NITER (loop))
|
||||
return AVG_LOOP_NITER (loop);
|
||||
return AVG_LOOP_NITER (loop);
|
||||
}
|
||||
|
||||
return niter;
|
||||
|
@ -184,6 +184,8 @@ struct comp_cost
|
|||
static const comp_cost no_cost = {0, 0, 0};
|
||||
static const comp_cost infinite_cost = {INFTY, INFTY, INFTY};
|
||||
|
||||
struct iv_inv_expr_ent;
|
||||
|
||||
/* The candidate - cost pair. */
|
||||
struct cost_pair
|
||||
{
|
||||
|
@ -195,7 +197,7 @@ struct cost_pair
|
|||
the final value of the iv. For iv elimination,
|
||||
the new bound to compare with. */
|
||||
enum tree_code comp; /* For iv elimination, the comparison. */
|
||||
int inv_expr_id; /* Loop invariant expression id. */
|
||||
iv_inv_expr_ent *inv_expr; /* Loop invariant expression. */
|
||||
};
|
||||
|
||||
/* Use. */
|
||||
|
@ -307,13 +309,36 @@ iv_common_cand_hasher::equal (const iv_common_cand *ccand1,
|
|||
}
|
||||
|
||||
/* Loop invariant expression hashtable entry. */
|
||||
|
||||
struct iv_inv_expr_ent
|
||||
{
|
||||
/* Tree expression of the entry. */
|
||||
tree expr;
|
||||
/* Unique indentifier. */
|
||||
int id;
|
||||
/* Hash value. */
|
||||
hashval_t hash;
|
||||
};
|
||||
|
||||
/* Sort iv_inv_expr_ent pair A and B by id field. */
|
||||
|
||||
static int
|
||||
sort_iv_inv_expr_ent (const void *a, const void *b)
|
||||
{
|
||||
const iv_inv_expr_ent * const *e1 = (const iv_inv_expr_ent * const *) (a);
|
||||
const iv_inv_expr_ent * const *e2 = (const iv_inv_expr_ent * const *) (b);
|
||||
|
||||
unsigned id1 = (*e1)->id;
|
||||
unsigned id2 = (*e2)->id;
|
||||
|
||||
if (id1 < id2)
|
||||
return -1;
|
||||
else if (id1 > id2)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Hashtable helpers. */
|
||||
|
||||
struct iv_inv_expr_hasher : free_ptr_hash <iv_inv_expr_ent>
|
||||
|
@ -363,7 +388,7 @@ struct ivopts_data
|
|||
hash_table<iv_inv_expr_hasher> *inv_expr_tab;
|
||||
|
||||
/* Loop invariant expression id. */
|
||||
int inv_expr_id;
|
||||
int max_inv_expr_id;
|
||||
|
||||
/* The bitmap of indices in version_info whose value was changed. */
|
||||
bitmap relevant;
|
||||
|
@ -443,12 +468,8 @@ struct iv_ca
|
|||
/* Number of times each invariant is used. */
|
||||
unsigned *n_invariant_uses;
|
||||
|
||||
/* The array holding the number of uses of each loop
|
||||
invariant expressions created by ivopt. */
|
||||
unsigned *used_inv_expr;
|
||||
|
||||
/* The number of created loop invariants. */
|
||||
unsigned num_used_inv_expr;
|
||||
/* Hash set with used invariant expression. */
|
||||
hash_map <iv_inv_expr_ent *, unsigned> *used_inv_exprs;
|
||||
|
||||
/* Total cost of the assignment. */
|
||||
comp_cost cost;
|
||||
|
@ -840,8 +861,8 @@ niter_for_exit (struct ivopts_data *data, edge exit)
|
|||
if (!slot)
|
||||
{
|
||||
/* Try to determine number of iterations. We cannot safely work with ssa
|
||||
names that appear in phi nodes on abnormal edges, so that we do not
|
||||
create overlapping life ranges for them (PR 27283). */
|
||||
names that appear in phi nodes on abnormal edges, so that we do not
|
||||
create overlapping life ranges for them (PR 27283). */
|
||||
desc = XNEW (struct tree_niter_desc);
|
||||
if (!number_of_iterations_exit (data->current_loop,
|
||||
exit, desc, true)
|
||||
|
@ -888,7 +909,7 @@ tree_ssa_iv_optimize_init (struct ivopts_data *data)
|
|||
data->vgroups.create (20);
|
||||
data->vcands.create (20);
|
||||
data->inv_expr_tab = new hash_table<iv_inv_expr_hasher> (10);
|
||||
data->inv_expr_id = 0;
|
||||
data->max_inv_expr_id = 0;
|
||||
data->name_expansion_cache = NULL;
|
||||
data->iv_common_cand_tab = new hash_table<iv_common_cand_hasher> (10);
|
||||
data->iv_common_cands.create (20);
|
||||
|
@ -930,7 +951,7 @@ determine_base_object (tree expr)
|
|||
return determine_base_object (TREE_OPERAND (base, 0));
|
||||
|
||||
return fold_convert (ptr_type_node,
|
||||
build_fold_addr_expr (base));
|
||||
build_fold_addr_expr (base));
|
||||
|
||||
case POINTER_PLUS_EXPR:
|
||||
return determine_base_object (TREE_OPERAND (expr, 0));
|
||||
|
@ -989,7 +1010,7 @@ alloc_iv (struct ivopts_data *data, tree base, tree step,
|
|||
By doing this:
|
||||
1) More accurate cost can be computed for address expressions;
|
||||
2) Duplicate candidates won't be created for bases in different
|
||||
forms, like &a[0] and &a. */
|
||||
forms, like &a[0] and &a. */
|
||||
STRIP_NOPS (expr);
|
||||
if ((TREE_CODE (expr) == ADDR_EXPR && !DECL_P (TREE_OPERAND (expr, 0)))
|
||||
|| contain_complex_addr_expr (expr))
|
||||
|
@ -2265,7 +2286,7 @@ find_interesting_uses_outside (struct ivopts_data *data, edge exit)
|
|||
phi = psi.phi ();
|
||||
def = PHI_ARG_DEF_FROM_EDGE (phi, exit);
|
||||
if (!virtual_operand_p (def))
|
||||
find_interesting_uses_op (data, def);
|
||||
find_interesting_uses_op (data, def);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2785,8 +2806,8 @@ add_candidate_1 (struct ivopts_data *data,
|
|||
|
||||
if (operand_equal_p (base, cand->iv->base, 0)
|
||||
&& operand_equal_p (step, cand->iv->step, 0)
|
||||
&& (TYPE_PRECISION (TREE_TYPE (base))
|
||||
== TYPE_PRECISION (TREE_TYPE (cand->iv->base))))
|
||||
&& (TYPE_PRECISION (TREE_TYPE (base))
|
||||
== TYPE_PRECISION (TREE_TYPE (cand->iv->base))))
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2936,14 +2957,14 @@ add_standard_iv_candidates (struct ivopts_data *data)
|
|||
|
||||
/* The same for a double-integer type if it is still fast enough. */
|
||||
if (TYPE_PRECISION
|
||||
(long_integer_type_node) > TYPE_PRECISION (integer_type_node)
|
||||
(long_integer_type_node) > TYPE_PRECISION (integer_type_node)
|
||||
&& TYPE_PRECISION (long_integer_type_node) <= BITS_PER_WORD)
|
||||
add_candidate (data, build_int_cst (long_integer_type_node, 0),
|
||||
build_int_cst (long_integer_type_node, 1), true, NULL);
|
||||
|
||||
/* The same for a double-integer type if it is still fast enough. */
|
||||
if (TYPE_PRECISION
|
||||
(long_long_integer_type_node) > TYPE_PRECISION (long_integer_type_node)
|
||||
(long_long_integer_type_node) > TYPE_PRECISION (long_integer_type_node)
|
||||
&& TYPE_PRECISION (long_long_integer_type_node) <= BITS_PER_WORD)
|
||||
add_candidate (data, build_int_cst (long_long_integer_type_node, 0),
|
||||
build_int_cst (long_long_integer_type_node, 1), true, NULL);
|
||||
|
@ -3329,7 +3350,7 @@ static void
|
|||
set_group_iv_cost (struct ivopts_data *data,
|
||||
struct iv_group *group, struct iv_cand *cand,
|
||||
comp_cost cost, bitmap depends_on, tree value,
|
||||
enum tree_code comp, int inv_expr_id)
|
||||
enum tree_code comp, iv_inv_expr_ent *inv_expr)
|
||||
{
|
||||
unsigned i, s;
|
||||
|
||||
|
@ -3346,7 +3367,7 @@ set_group_iv_cost (struct ivopts_data *data,
|
|||
group->cost_map[cand->id].depends_on = depends_on;
|
||||
group->cost_map[cand->id].value = value;
|
||||
group->cost_map[cand->id].comp = comp;
|
||||
group->cost_map[cand->id].inv_expr_id = inv_expr_id;
|
||||
group->cost_map[cand->id].inv_expr = inv_expr;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3367,7 +3388,7 @@ found:
|
|||
group->cost_map[i].depends_on = depends_on;
|
||||
group->cost_map[i].value = value;
|
||||
group->cost_map[i].comp = comp;
|
||||
group->cost_map[i].inv_expr_id = inv_expr_id;
|
||||
group->cost_map[i].inv_expr = inv_expr;
|
||||
}
|
||||
|
||||
/* Gets cost of (GROUP, CAND) pair. */
|
||||
|
@ -3454,7 +3475,7 @@ prepare_decl_rtl (tree *expr_p, int *ws, void *data)
|
|||
continue;
|
||||
obj = *expr_p;
|
||||
if (DECL_P (obj) && HAS_RTL_P (obj) && !DECL_RTL_SET_P (obj))
|
||||
x = produce_memory_decl_rtl (obj, regno);
|
||||
x = produce_memory_decl_rtl (obj, regno);
|
||||
break;
|
||||
|
||||
case SSA_NAME:
|
||||
|
@ -3908,7 +3929,7 @@ get_address_cost (bool symbol_present, bool var_present,
|
|||
}
|
||||
}
|
||||
if (i == -1)
|
||||
off = 0;
|
||||
off = 0;
|
||||
data->max_offset = off;
|
||||
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
|
@ -4040,9 +4061,9 @@ get_address_cost (bool symbol_present, bool var_present,
|
|||
However, the symbol will have to be loaded in any case before the
|
||||
loop (and quite likely we have it in register already), so it does not
|
||||
make much sense to penalize them too heavily. So make some final
|
||||
tweaks for the SYMBOL_PRESENT modes:
|
||||
tweaks for the SYMBOL_PRESENT modes:
|
||||
|
||||
If VAR_PRESENT is false, and the mode obtained by changing symbol to
|
||||
If VAR_PRESENT is false, and the mode obtained by changing symbol to
|
||||
var is cheaper, use this mode with small penalty.
|
||||
If VAR_PRESENT is true, try whether the mode with
|
||||
SYMBOL_PRESENT = false is cheaper even with cost of addition, and
|
||||
|
@ -4159,7 +4180,7 @@ get_address_cost (bool symbol_present, bool var_present,
|
|||
|
||||
static bool
|
||||
get_shiftadd_cost (tree expr, machine_mode mode, comp_cost cost0,
|
||||
comp_cost cost1, tree mult, bool speed, comp_cost *cost)
|
||||
comp_cost cost1, tree mult, bool speed, comp_cost *cost)
|
||||
{
|
||||
comp_cost res;
|
||||
tree op1 = TREE_OPERAND (expr, 1);
|
||||
|
@ -4181,10 +4202,10 @@ get_shiftadd_cost (tree expr, machine_mode mode, comp_cost cost0,
|
|||
/* If the target has a cheap shift-and-add or shift-and-sub instruction,
|
||||
use that in preference to a shift insn followed by an add insn. */
|
||||
sa_cost = (TREE_CODE (expr) != MINUS_EXPR
|
||||
? shiftadd_cost (speed, mode, m)
|
||||
: (mult_in_op1
|
||||
? shiftsub1_cost (speed, mode, m)
|
||||
: shiftsub0_cost (speed, mode, m)));
|
||||
? shiftadd_cost (speed, mode, m)
|
||||
: (mult_in_op1
|
||||
? shiftsub1_cost (speed, mode, m)
|
||||
: shiftsub0_cost (speed, mode, m)));
|
||||
|
||||
res = new_cost (MIN (as_cost, sa_cost), 0);
|
||||
res = add_costs (res, mult_in_op1 ? cost0 : cost1);
|
||||
|
@ -4316,20 +4337,20 @@ force_expr_to_var_cost (tree expr, bool speed)
|
|||
case NEGATE_EXPR:
|
||||
cost = new_cost (add_cost (speed, mode), 0);
|
||||
if (TREE_CODE (expr) != NEGATE_EXPR)
|
||||
{
|
||||
tree mult = NULL_TREE;
|
||||
comp_cost sa_cost;
|
||||
if (TREE_CODE (op1) == MULT_EXPR)
|
||||
mult = op1;
|
||||
else if (TREE_CODE (op0) == MULT_EXPR)
|
||||
mult = op0;
|
||||
{
|
||||
tree mult = NULL_TREE;
|
||||
comp_cost sa_cost;
|
||||
if (TREE_CODE (op1) == MULT_EXPR)
|
||||
mult = op1;
|
||||
else if (TREE_CODE (op0) == MULT_EXPR)
|
||||
mult = op0;
|
||||
|
||||
if (mult != NULL_TREE
|
||||
&& cst_and_fits_in_hwi (TREE_OPERAND (mult, 1))
|
||||
&& get_shiftadd_cost (expr, mode, cost0, cost1, mult,
|
||||
speed, &sa_cost))
|
||||
return sa_cost;
|
||||
}
|
||||
if (mult != NULL_TREE
|
||||
&& cst_and_fits_in_hwi (TREE_OPERAND (mult, 1))
|
||||
&& get_shiftadd_cost (expr, mode, cost0, cost1, mult,
|
||||
speed, &sa_cost))
|
||||
return sa_cost;
|
||||
}
|
||||
break;
|
||||
|
||||
CASE_CONVERT:
|
||||
|
@ -4543,18 +4564,18 @@ compare_aff_trees (aff_tree *aff1, aff_tree *aff2)
|
|||
for (i = 0; i < aff1->n; i++)
|
||||
{
|
||||
if (aff1->elts[i].coef != aff2->elts[i].coef)
|
||||
return false;
|
||||
return false;
|
||||
|
||||
if (!operand_equal_p (aff1->elts[i].val, aff2->elts[i].val, 0))
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Stores EXPR in DATA->inv_expr_tab, and assigns it an inv_expr_id. */
|
||||
/* Stores EXPR in DATA->inv_expr_tab, return pointer to iv_inv_expr_ent. */
|
||||
|
||||
static int
|
||||
get_expr_id (struct ivopts_data *data, tree expr)
|
||||
static iv_inv_expr_ent *
|
||||
record_inv_expr (struct ivopts_data *data, tree expr)
|
||||
{
|
||||
struct iv_inv_expr_ent ent;
|
||||
struct iv_inv_expr_ent **slot;
|
||||
|
@ -4562,25 +4583,27 @@ get_expr_id (struct ivopts_data *data, tree expr)
|
|||
ent.expr = expr;
|
||||
ent.hash = iterative_hash_expr (expr, 0);
|
||||
slot = data->inv_expr_tab->find_slot (&ent, INSERT);
|
||||
if (*slot)
|
||||
return (*slot)->id;
|
||||
|
||||
*slot = XNEW (struct iv_inv_expr_ent);
|
||||
(*slot)->expr = expr;
|
||||
(*slot)->hash = ent.hash;
|
||||
(*slot)->id = data->inv_expr_id++;
|
||||
return (*slot)->id;
|
||||
if (!*slot)
|
||||
{
|
||||
*slot = XNEW (struct iv_inv_expr_ent);
|
||||
(*slot)->expr = expr;
|
||||
(*slot)->hash = ent.hash;
|
||||
(*slot)->id = data->max_inv_expr_id++;
|
||||
}
|
||||
|
||||
return *slot;
|
||||
}
|
||||
|
||||
/* Returns the pseudo expr id if expression UBASE - RATIO * CBASE
|
||||
/* Returns the invariant expression if expression UBASE - RATIO * CBASE
|
||||
requires a new compiler generated temporary. Returns -1 otherwise.
|
||||
ADDRESS_P is a flag indicating if the expression is for address
|
||||
computation. */
|
||||
|
||||
static int
|
||||
get_loop_invariant_expr_id (struct ivopts_data *data, tree ubase,
|
||||
tree cbase, HOST_WIDE_INT ratio,
|
||||
bool address_p)
|
||||
static iv_inv_expr_ent *
|
||||
get_loop_invariant_expr (struct ivopts_data *data, tree ubase,
|
||||
tree cbase, HOST_WIDE_INT ratio,
|
||||
bool address_p)
|
||||
{
|
||||
aff_tree ubase_aff, cbase_aff;
|
||||
tree expr, ub, cb;
|
||||
|
@ -4592,7 +4615,7 @@ get_loop_invariant_expr_id (struct ivopts_data *data, tree ubase,
|
|||
|
||||
if ((TREE_CODE (ubase) == INTEGER_CST)
|
||||
&& (TREE_CODE (cbase) == INTEGER_CST))
|
||||
return -1;
|
||||
return NULL;
|
||||
|
||||
/* Strips the constant part. */
|
||||
if (TREE_CODE (ubase) == PLUS_EXPR
|
||||
|
@ -4600,7 +4623,7 @@ get_loop_invariant_expr_id (struct ivopts_data *data, tree ubase,
|
|||
|| TREE_CODE (ubase) == POINTER_PLUS_EXPR)
|
||||
{
|
||||
if (TREE_CODE (TREE_OPERAND (ubase, 1)) == INTEGER_CST)
|
||||
ubase = TREE_OPERAND (ubase, 0);
|
||||
ubase = TREE_OPERAND (ubase, 0);
|
||||
}
|
||||
|
||||
/* Strips the constant part. */
|
||||
|
@ -4609,60 +4632,60 @@ get_loop_invariant_expr_id (struct ivopts_data *data, tree ubase,
|
|||
|| TREE_CODE (cbase) == POINTER_PLUS_EXPR)
|
||||
{
|
||||
if (TREE_CODE (TREE_OPERAND (cbase, 1)) == INTEGER_CST)
|
||||
cbase = TREE_OPERAND (cbase, 0);
|
||||
cbase = TREE_OPERAND (cbase, 0);
|
||||
}
|
||||
|
||||
if (address_p)
|
||||
{
|
||||
if (((TREE_CODE (ubase) == SSA_NAME)
|
||||
|| (TREE_CODE (ubase) == ADDR_EXPR
|
||||
&& is_gimple_min_invariant (ubase)))
|
||||
&& (TREE_CODE (cbase) == INTEGER_CST))
|
||||
return -1;
|
||||
|| (TREE_CODE (ubase) == ADDR_EXPR
|
||||
&& is_gimple_min_invariant (ubase)))
|
||||
&& (TREE_CODE (cbase) == INTEGER_CST))
|
||||
return NULL;
|
||||
|
||||
if (((TREE_CODE (cbase) == SSA_NAME)
|
||||
|| (TREE_CODE (cbase) == ADDR_EXPR
|
||||
&& is_gimple_min_invariant (cbase)))
|
||||
&& (TREE_CODE (ubase) == INTEGER_CST))
|
||||
return -1;
|
||||
|| (TREE_CODE (cbase) == ADDR_EXPR
|
||||
&& is_gimple_min_invariant (cbase)))
|
||||
&& (TREE_CODE (ubase) == INTEGER_CST))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ratio == 1)
|
||||
{
|
||||
if (operand_equal_p (ubase, cbase, 0))
|
||||
return -1;
|
||||
return NULL;
|
||||
|
||||
if (TREE_CODE (ubase) == ADDR_EXPR
|
||||
&& TREE_CODE (cbase) == ADDR_EXPR)
|
||||
{
|
||||
tree usym, csym;
|
||||
&& TREE_CODE (cbase) == ADDR_EXPR)
|
||||
{
|
||||
tree usym, csym;
|
||||
|
||||
usym = TREE_OPERAND (ubase, 0);
|
||||
csym = TREE_OPERAND (cbase, 0);
|
||||
if (TREE_CODE (usym) == ARRAY_REF)
|
||||
{
|
||||
tree ind = TREE_OPERAND (usym, 1);
|
||||
if (TREE_CODE (ind) == INTEGER_CST
|
||||
&& tree_fits_shwi_p (ind)
|
||||
&& tree_to_shwi (ind) == 0)
|
||||
usym = TREE_OPERAND (usym, 0);
|
||||
}
|
||||
if (TREE_CODE (csym) == ARRAY_REF)
|
||||
{
|
||||
tree ind = TREE_OPERAND (csym, 1);
|
||||
if (TREE_CODE (ind) == INTEGER_CST
|
||||
&& tree_fits_shwi_p (ind)
|
||||
&& tree_to_shwi (ind) == 0)
|
||||
csym = TREE_OPERAND (csym, 0);
|
||||
}
|
||||
if (operand_equal_p (usym, csym, 0))
|
||||
return -1;
|
||||
}
|
||||
usym = TREE_OPERAND (ubase, 0);
|
||||
csym = TREE_OPERAND (cbase, 0);
|
||||
if (TREE_CODE (usym) == ARRAY_REF)
|
||||
{
|
||||
tree ind = TREE_OPERAND (usym, 1);
|
||||
if (TREE_CODE (ind) == INTEGER_CST
|
||||
&& tree_fits_shwi_p (ind)
|
||||
&& tree_to_shwi (ind) == 0)
|
||||
usym = TREE_OPERAND (usym, 0);
|
||||
}
|
||||
if (TREE_CODE (csym) == ARRAY_REF)
|
||||
{
|
||||
tree ind = TREE_OPERAND (csym, 1);
|
||||
if (TREE_CODE (ind) == INTEGER_CST
|
||||
&& tree_fits_shwi_p (ind)
|
||||
&& tree_to_shwi (ind) == 0)
|
||||
csym = TREE_OPERAND (csym, 0);
|
||||
}
|
||||
if (operand_equal_p (usym, csym, 0))
|
||||
return NULL;
|
||||
}
|
||||
/* Now do more complex comparison */
|
||||
tree_to_aff_combination (ubase, TREE_TYPE (ubase), &ubase_aff);
|
||||
tree_to_aff_combination (cbase, TREE_TYPE (cbase), &cbase_aff);
|
||||
if (compare_aff_trees (&ubase_aff, &cbase_aff))
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tree_to_aff_combination (ub, TREE_TYPE (ub), &ubase_aff);
|
||||
|
@ -4671,7 +4694,7 @@ get_loop_invariant_expr_id (struct ivopts_data *data, tree ubase,
|
|||
aff_combination_scale (&cbase_aff, -1 * ratio);
|
||||
aff_combination_add (&ubase_aff, &cbase_aff);
|
||||
expr = aff_combination_to_tree (&ubase_aff);
|
||||
return get_expr_id (data, expr);
|
||||
return record_inv_expr (data, expr);
|
||||
}
|
||||
|
||||
|
||||
|
@ -4689,7 +4712,7 @@ get_computation_cost_at (struct ivopts_data *data,
|
|||
struct iv_use *use, struct iv_cand *cand,
|
||||
bool address_p, bitmap *depends_on, gimple *at,
|
||||
bool *can_autoinc,
|
||||
int *inv_expr_id)
|
||||
iv_inv_expr_ent **inv_expr)
|
||||
{
|
||||
tree ubase = use->iv->base, ustep = use->iv->step;
|
||||
tree cbase, cstep;
|
||||
|
@ -4790,17 +4813,17 @@ get_computation_cost_at (struct ivopts_data *data,
|
|||
|
||||
/* Check to see if any adjustment is needed. */
|
||||
if (cstepi == 0 && stmt_is_after_inc)
|
||||
{
|
||||
aff_tree real_cbase_aff;
|
||||
aff_tree cstep_aff;
|
||||
{
|
||||
aff_tree real_cbase_aff;
|
||||
aff_tree cstep_aff;
|
||||
|
||||
tree_to_aff_combination (cbase, TREE_TYPE (real_cbase),
|
||||
&real_cbase_aff);
|
||||
tree_to_aff_combination (cstep, TREE_TYPE (cstep), &cstep_aff);
|
||||
tree_to_aff_combination (cbase, TREE_TYPE (real_cbase),
|
||||
&real_cbase_aff);
|
||||
tree_to_aff_combination (cstep, TREE_TYPE (cstep), &cstep_aff);
|
||||
|
||||
aff_combination_add (&real_cbase_aff, &cstep_aff);
|
||||
real_cbase = aff_combination_to_tree (&real_cbase_aff);
|
||||
}
|
||||
aff_combination_add (&real_cbase_aff, &cstep_aff);
|
||||
real_cbase = aff_combination_to_tree (&real_cbase_aff);
|
||||
}
|
||||
|
||||
cost = difference_cost (data,
|
||||
ubase, real_cbase,
|
||||
|
@ -4846,13 +4869,13 @@ get_computation_cost_at (struct ivopts_data *data,
|
|||
/* Record setup cost in scrach field. */
|
||||
cost.scratch = cost.cost;
|
||||
|
||||
if (inv_expr_id && depends_on && *depends_on)
|
||||
if (inv_expr && depends_on && *depends_on)
|
||||
{
|
||||
*inv_expr_id =
|
||||
get_loop_invariant_expr_id (data, ubase, cbase, ratio, address_p);
|
||||
*inv_expr = get_loop_invariant_expr (data, ubase, cbase, ratio,
|
||||
address_p);
|
||||
/* Clear depends on. */
|
||||
if (*inv_expr_id != -1)
|
||||
bitmap_clear (*depends_on);
|
||||
if (inv_expr != NULL)
|
||||
bitmap_clear (*depends_on);
|
||||
}
|
||||
|
||||
/* If we are after the increment, the value of the candidate is higher by
|
||||
|
@ -4929,11 +4952,11 @@ static comp_cost
|
|||
get_computation_cost (struct ivopts_data *data,
|
||||
struct iv_use *use, struct iv_cand *cand,
|
||||
bool address_p, bitmap *depends_on,
|
||||
bool *can_autoinc, int *inv_expr_id)
|
||||
bool *can_autoinc, iv_inv_expr_ent **inv_expr)
|
||||
{
|
||||
return get_computation_cost_at (data,
|
||||
use, cand, address_p, depends_on, use->stmt,
|
||||
can_autoinc, inv_expr_id);
|
||||
can_autoinc, inv_expr);
|
||||
}
|
||||
|
||||
/* Determines cost of computing the use in GROUP with CAND in a generic
|
||||
|
@ -4944,7 +4967,7 @@ determine_group_iv_cost_generic (struct ivopts_data *data,
|
|||
struct iv_group *group, struct iv_cand *cand)
|
||||
{
|
||||
comp_cost cost;
|
||||
int inv_expr_id = -1;
|
||||
iv_inv_expr_ent *inv_expr = NULL;
|
||||
bitmap depends_on = NULL;
|
||||
struct iv_use *use = group->vuses[0];
|
||||
|
||||
|
@ -4956,10 +4979,10 @@ determine_group_iv_cost_generic (struct ivopts_data *data,
|
|||
cost = no_cost;
|
||||
else
|
||||
cost = get_computation_cost (data, use, cand, false,
|
||||
&depends_on, NULL, &inv_expr_id);
|
||||
&depends_on, NULL, &inv_expr);
|
||||
|
||||
set_group_iv_cost (data, group, cand, cost, depends_on,
|
||||
NULL_TREE, ERROR_MARK, inv_expr_id);
|
||||
NULL_TREE, ERROR_MARK, inv_expr);
|
||||
return !infinite_cost_p (cost);
|
||||
}
|
||||
|
||||
|
@ -4972,12 +4995,12 @@ determine_group_iv_cost_address (struct ivopts_data *data,
|
|||
unsigned i;
|
||||
bitmap depends_on;
|
||||
bool can_autoinc, first = true;
|
||||
int inv_expr_id = -1;
|
||||
iv_inv_expr_ent *inv_expr = NULL;
|
||||
struct iv_use *use = group->vuses[0];
|
||||
comp_cost sum_cost = no_cost, cost;
|
||||
|
||||
cost = get_computation_cost (data, use, cand, true,
|
||||
&depends_on, &can_autoinc, &inv_expr_id);
|
||||
&depends_on, &can_autoinc, &inv_expr);
|
||||
|
||||
sum_cost = cost;
|
||||
if (!infinite_cost_p (sum_cost) && cand->ainc_use == use)
|
||||
|
@ -5025,7 +5048,7 @@ determine_group_iv_cost_address (struct ivopts_data *data,
|
|||
sum_cost = add_costs (sum_cost, cost);
|
||||
}
|
||||
set_group_iv_cost (data, group, cand, sum_cost, depends_on,
|
||||
NULL_TREE, ERROR_MARK, inv_expr_id);
|
||||
NULL_TREE, ERROR_MARK, inv_expr);
|
||||
|
||||
return !infinite_cost_p (sum_cost);
|
||||
}
|
||||
|
@ -5081,8 +5104,8 @@ iv_period (struct iv *iv)
|
|||
pow2div = num_ending_zeros (step);
|
||||
|
||||
period = build_low_bits_mask (type,
|
||||
(TYPE_PRECISION (type)
|
||||
- tree_to_uhwi (pow2div)));
|
||||
(TYPE_PRECISION (type)
|
||||
- tree_to_uhwi (pow2div)));
|
||||
|
||||
return period;
|
||||
}
|
||||
|
@ -5215,7 +5238,7 @@ difference_cannot_overflow_p (struct ivopts_data *data, tree base, tree offset)
|
|||
|
||||
static bool
|
||||
iv_elimination_compare_lt (struct ivopts_data *data,
|
||||
struct iv_cand *cand, enum tree_code *comp_p,
|
||||
struct iv_cand *cand, enum tree_code *comp_p,
|
||||
struct tree_niter_desc *niter)
|
||||
{
|
||||
tree cand_type, a, b, mbz, nit_type = TREE_TYPE (niter->niter), offset;
|
||||
|
@ -5264,10 +5287,10 @@ iv_elimination_compare_lt (struct ivopts_data *data,
|
|||
|
||||
/* Handle b < a + 1. */
|
||||
if (TREE_CODE (op1) == PLUS_EXPR && integer_onep (TREE_OPERAND (op1, 1)))
|
||||
{
|
||||
a = TREE_OPERAND (op1, 0);
|
||||
b = TREE_OPERAND (mbz, 0);
|
||||
}
|
||||
{
|
||||
a = TREE_OPERAND (op1, 0);
|
||||
b = TREE_OPERAND (mbz, 0);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
@ -5353,15 +5376,15 @@ may_eliminate_iv (struct ivopts_data *data,
|
|||
{
|
||||
/* See cand_value_at. */
|
||||
if (stmt_after_increment (loop, cand, use->stmt))
|
||||
{
|
||||
if (!tree_int_cst_lt (desc->niter, period))
|
||||
return false;
|
||||
}
|
||||
{
|
||||
if (!tree_int_cst_lt (desc->niter, period))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tree_int_cst_lt (period, desc->niter))
|
||||
return false;
|
||||
}
|
||||
{
|
||||
if (tree_int_cst_lt (period, desc->niter))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* If not, and if this is the only possible exit of the loop, see whether
|
||||
|
@ -5373,22 +5396,23 @@ may_eliminate_iv (struct ivopts_data *data,
|
|||
|
||||
max_niter = desc->max;
|
||||
if (stmt_after_increment (loop, cand, use->stmt))
|
||||
max_niter += 1;
|
||||
max_niter += 1;
|
||||
period_value = wi::to_widest (period);
|
||||
if (wi::gtu_p (max_niter, period_value))
|
||||
{
|
||||
/* See if we can take advantage of inferred loop bound information. */
|
||||
if (data->loop_single_exit_p)
|
||||
{
|
||||
if (!max_loop_iterations (loop, &max_niter))
|
||||
return false;
|
||||
/* The loop bound is already adjusted by adding 1. */
|
||||
if (wi::gtu_p (max_niter, period_value))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
{
|
||||
/* See if we can take advantage of inferred loop bound
|
||||
information. */
|
||||
if (data->loop_single_exit_p)
|
||||
{
|
||||
if (!max_loop_iterations (loop, &max_niter))
|
||||
return false;
|
||||
/* The loop bound is already adjusted by adding 1. */
|
||||
if (wi::gtu_p (max_niter, period_value))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
cand_value_at (loop, cand, use->stmt, desc->niter, &bnd);
|
||||
|
@ -5444,7 +5468,7 @@ determine_group_iv_cost_cond (struct ivopts_data *data,
|
|||
bitmap depends_on_elim = NULL, depends_on_express = NULL, depends_on;
|
||||
comp_cost elim_cost, express_cost, cost, bound_cost;
|
||||
bool ok;
|
||||
int elim_inv_expr_id = -1, express_inv_expr_id = -1, inv_expr_id;
|
||||
iv_inv_expr_ent *elim_inv_expr = NULL, *express_inv_expr = NULL, *inv_expr;
|
||||
tree *control_var, *bound_cst;
|
||||
enum tree_code comp = ERROR_MARK;
|
||||
struct iv_use *use = group->vuses[0];
|
||||
|
@ -5456,18 +5480,18 @@ determine_group_iv_cost_cond (struct ivopts_data *data,
|
|||
{
|
||||
elim_cost = force_var_cost (data, bound, &depends_on_elim);
|
||||
if (elim_cost.cost == 0)
|
||||
elim_cost.cost = parm_decl_cost (data, bound);
|
||||
elim_cost.cost = parm_decl_cost (data, bound);
|
||||
else if (TREE_CODE (bound) == INTEGER_CST)
|
||||
elim_cost.cost = 0;
|
||||
elim_cost.cost = 0;
|
||||
/* If we replace a loop condition 'i < n' with 'p < base + n',
|
||||
depends_on_elim will have 'base' and 'n' set, which implies
|
||||
that both 'base' and 'n' will be live during the loop. More likely,
|
||||
'base + n' will be loop invariant, resulting in only one live value
|
||||
during the loop. So in that case we clear depends_on_elim and set
|
||||
elim_inv_expr_id instead. */
|
||||
elim_inv_expr_id instead. */
|
||||
if (depends_on_elim && bitmap_count_bits (depends_on_elim) > 1)
|
||||
{
|
||||
elim_inv_expr_id = get_expr_id (data, bound);
|
||||
elim_inv_expr = record_inv_expr (data, bound);
|
||||
bitmap_clear (depends_on_elim);
|
||||
}
|
||||
/* The bound is a loop invariant, so it will be only computed
|
||||
|
@ -5497,7 +5521,7 @@ determine_group_iv_cost_cond (struct ivopts_data *data,
|
|||
|
||||
express_cost = get_computation_cost (data, use, cand, false,
|
||||
&depends_on_express, NULL,
|
||||
&express_inv_expr_id);
|
||||
&express_inv_expr);
|
||||
fd_ivopts_data = data;
|
||||
walk_tree (&cmp_iv->base, find_depends, &depends_on_express, NULL);
|
||||
|
||||
|
@ -5515,7 +5539,7 @@ determine_group_iv_cost_cond (struct ivopts_data *data,
|
|||
cost = elim_cost;
|
||||
depends_on = depends_on_elim;
|
||||
depends_on_elim = NULL;
|
||||
inv_expr_id = elim_inv_expr_id;
|
||||
inv_expr = elim_inv_expr;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -5524,11 +5548,11 @@ determine_group_iv_cost_cond (struct ivopts_data *data,
|
|||
depends_on_express = NULL;
|
||||
bound = NULL_TREE;
|
||||
comp = ERROR_MARK;
|
||||
inv_expr_id = express_inv_expr_id;
|
||||
inv_expr = express_inv_expr;
|
||||
}
|
||||
|
||||
set_group_iv_cost (data, group, cand, cost,
|
||||
depends_on, bound, comp, inv_expr_id);
|
||||
depends_on, bound, comp, inv_expr);
|
||||
|
||||
if (depends_on_elim)
|
||||
BITMAP_FREE (depends_on_elim);
|
||||
|
@ -5718,14 +5742,31 @@ determine_group_iv_costs (struct ivopts_data *data)
|
|||
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
{
|
||||
fprintf (dump_file, "<Group-candidate Costs>:\n");
|
||||
fprintf (dump_file, "\n<Invariant Expressions>:\n");
|
||||
auto_vec <iv_inv_expr_ent *> list (data->inv_expr_tab->elements ());
|
||||
|
||||
for (hash_table<iv_inv_expr_hasher>::iterator it
|
||||
= data->inv_expr_tab->begin (); it != data->inv_expr_tab->end ();
|
||||
++it)
|
||||
list.safe_push (*it);
|
||||
|
||||
list.qsort (sort_iv_inv_expr_ent);
|
||||
|
||||
for (i = 0; i < list.length (); ++i)
|
||||
{
|
||||
fprintf (dump_file, "inv_expr %d: \t", i);
|
||||
print_generic_expr (dump_file, list[i]->expr, TDF_SLIM);
|
||||
fprintf (dump_file, "\n");
|
||||
}
|
||||
|
||||
fprintf (dump_file, "\n<Group-candidate Costs>:\n");
|
||||
|
||||
for (i = 0; i < data->vgroups.length (); i++)
|
||||
{
|
||||
group = data->vgroups[i];
|
||||
|
||||
fprintf (dump_file, "Group %d:\n", i);
|
||||
fprintf (dump_file, " cand\tcost\tcompl.\tdepends on\n");
|
||||
fprintf (dump_file, " cand\tcost\tcompl.\tinv.ex.\tdepends on\n");
|
||||
for (j = 0; j < group->n_map_members; j++)
|
||||
{
|
||||
if (!group->cost_map[j].cand
|
||||
|
@ -5736,12 +5777,14 @@ determine_group_iv_costs (struct ivopts_data *data)
|
|||
group->cost_map[j].cand->id,
|
||||
group->cost_map[j].cost.cost,
|
||||
group->cost_map[j].cost.complexity);
|
||||
if (group->cost_map[j].inv_expr != NULL)
|
||||
fprintf (dump_file, "%d\t",
|
||||
group->cost_map[j].inv_expr->id);
|
||||
else
|
||||
fprintf (dump_file, "\t");
|
||||
if (group->cost_map[j].depends_on)
|
||||
bitmap_print (dump_file,
|
||||
group->cost_map[j].depends_on, "","");
|
||||
if (group->cost_map[j].inv_expr_id != -1)
|
||||
fprintf (dump_file, " inv_expr:%d",
|
||||
group->cost_map[j].inv_expr_id);
|
||||
fprintf (dump_file, "\n");
|
||||
}
|
||||
|
||||
|
@ -5942,7 +5985,8 @@ iv_ca_recount_cost (struct ivopts_data *data, struct iv_ca *ivs)
|
|||
cost.cost += ivs->cand_cost;
|
||||
|
||||
cost.cost += ivopts_global_cost_for_size (data,
|
||||
ivs->n_regs + ivs->num_used_inv_expr);
|
||||
ivs->n_regs
|
||||
+ ivs->used_inv_exprs->elements ());
|
||||
|
||||
ivs->cost = cost;
|
||||
}
|
||||
|
@ -5962,7 +6006,7 @@ iv_ca_set_remove_invariants (struct iv_ca *ivs, bitmap invs)
|
|||
{
|
||||
ivs->n_invariant_uses[iid]--;
|
||||
if (ivs->n_invariant_uses[iid] == 0)
|
||||
ivs->n_regs--;
|
||||
ivs->n_regs--;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6000,11 +6044,12 @@ iv_ca_set_no_cp (struct ivopts_data *data, struct iv_ca *ivs,
|
|||
|
||||
iv_ca_set_remove_invariants (ivs, cp->depends_on);
|
||||
|
||||
if (cp->inv_expr_id != -1)
|
||||
if (cp->inv_expr != NULL)
|
||||
{
|
||||
ivs->used_inv_expr[cp->inv_expr_id]--;
|
||||
if (ivs->used_inv_expr[cp->inv_expr_id] == 0)
|
||||
ivs->num_used_inv_expr--;
|
||||
unsigned *slot = ivs->used_inv_exprs->get (cp->inv_expr);
|
||||
--(*slot);
|
||||
if (*slot == 0)
|
||||
ivs->used_inv_exprs->remove (cp->inv_expr);
|
||||
}
|
||||
iv_ca_recount_cost (data, ivs);
|
||||
}
|
||||
|
@ -6024,7 +6069,7 @@ iv_ca_set_add_invariants (struct iv_ca *ivs, bitmap invs)
|
|||
{
|
||||
ivs->n_invariant_uses[iid]++;
|
||||
if (ivs->n_invariant_uses[iid] == 1)
|
||||
ivs->n_regs++;
|
||||
ivs->n_regs++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6064,12 +6109,11 @@ iv_ca_set_cp (struct ivopts_data *data, struct iv_ca *ivs,
|
|||
ivs->cand_use_cost = add_costs (ivs->cand_use_cost, cp->cost);
|
||||
iv_ca_set_add_invariants (ivs, cp->depends_on);
|
||||
|
||||
if (cp->inv_expr_id != -1)
|
||||
{
|
||||
ivs->used_inv_expr[cp->inv_expr_id]++;
|
||||
if (ivs->used_inv_expr[cp->inv_expr_id] == 1)
|
||||
ivs->num_used_inv_expr++;
|
||||
}
|
||||
if (cp->inv_expr != NULL)
|
||||
{
|
||||
unsigned *slot = &ivs->used_inv_exprs->get_or_insert (cp->inv_expr);
|
||||
++(*slot);
|
||||
}
|
||||
iv_ca_recount_cost (data, ivs);
|
||||
}
|
||||
}
|
||||
|
@ -6278,9 +6322,8 @@ iv_ca_new (struct ivopts_data *data)
|
|||
nw->cand_use_cost = no_cost;
|
||||
nw->cand_cost = 0;
|
||||
nw->n_invariant_uses = XCNEWVEC (unsigned, data->max_inv_id + 1);
|
||||
nw->used_inv_exprs = new hash_map <iv_inv_expr_ent *, unsigned> (13);
|
||||
nw->cost = no_cost;
|
||||
nw->used_inv_expr = XCNEWVEC (unsigned, data->inv_expr_id + 1);
|
||||
nw->num_used_inv_expr = 0;
|
||||
|
||||
return nw;
|
||||
}
|
||||
|
@ -6294,7 +6337,7 @@ iv_ca_free (struct iv_ca **ivs)
|
|||
free ((*ivs)->n_cand_uses);
|
||||
BITMAP_FREE ((*ivs)->cands);
|
||||
free ((*ivs)->n_invariant_uses);
|
||||
free ((*ivs)->used_inv_expr);
|
||||
delete ((*ivs)->used_inv_exprs);
|
||||
free (*ivs);
|
||||
*ivs = NULL;
|
||||
}
|
||||
|
@ -6304,13 +6347,13 @@ iv_ca_free (struct iv_ca **ivs)
|
|||
static void
|
||||
iv_ca_dump (struct ivopts_data *data, FILE *file, struct iv_ca *ivs)
|
||||
{
|
||||
const char *pref = " invariants ";
|
||||
unsigned i;
|
||||
comp_cost cost = iv_ca_cost (ivs);
|
||||
|
||||
fprintf (file, " cost: %d (complexity %d)\n", cost.cost, cost.complexity);
|
||||
fprintf (file, " cand_cost: %d\n cand_group_cost: %d (complexity %d)\n",
|
||||
ivs->cand_cost, ivs->cand_use_cost.cost, ivs->cand_use_cost.complexity);
|
||||
ivs->cand_cost, ivs->cand_use_cost.cost,
|
||||
ivs->cand_use_cost.complexity);
|
||||
bitmap_print (file, ivs->cands, " candidates: ","\n");
|
||||
|
||||
for (i = 0; i < ivs->upto; i++)
|
||||
|
@ -6324,12 +6367,24 @@ iv_ca_dump (struct ivopts_data *data, FILE *file, struct iv_ca *ivs)
|
|||
fprintf (file, " group:%d --> ??\n", group->id);
|
||||
}
|
||||
|
||||
const char *pref = "";
|
||||
fprintf (file, " invariant variables: ");
|
||||
for (i = 1; i <= data->max_inv_id; i++)
|
||||
if (ivs->n_invariant_uses[i])
|
||||
{
|
||||
fprintf (file, "%s%d", pref, i);
|
||||
pref = ", ";
|
||||
}
|
||||
|
||||
pref = "";
|
||||
fprintf (file, "\n invariant expressions: ");
|
||||
for (hash_map<iv_inv_expr_ent *, unsigned>::iterator it
|
||||
= ivs->used_inv_exprs->begin (); it != ivs->used_inv_exprs->end (); ++it)
|
||||
{
|
||||
fprintf (file, "%s%d", pref, (*it).first->id);
|
||||
pref = ", ";
|
||||
}
|
||||
|
||||
fprintf (file, "\n\n");
|
||||
}
|
||||
|
||||
|
@ -6366,7 +6421,7 @@ iv_ca_extend (struct ivopts_data *data, struct iv_ca *ivs,
|
|||
continue;
|
||||
|
||||
if (!min_ncand && !cheaper_cost_pair (new_cp, old_cp))
|
||||
continue;
|
||||
continue;
|
||||
|
||||
*delta = iv_ca_delta_add (group, old_cp, new_cp, *delta);
|
||||
}
|
||||
|
@ -6670,7 +6725,7 @@ try_add_cand_for (struct ivopts_data *data, struct iv_ca *ivs,
|
|||
continue;
|
||||
|
||||
if (iv_ca_cand_used_p (ivs, cand))
|
||||
continue;
|
||||
continue;
|
||||
|
||||
cp = get_group_iv_cost (data, group, cand);
|
||||
if (!cp)
|
||||
|
@ -6678,7 +6733,7 @@ try_add_cand_for (struct ivopts_data *data, struct iv_ca *ivs,
|
|||
|
||||
iv_ca_set_cp (data, ivs, group, cp);
|
||||
act_cost = iv_ca_extend (data, ivs, cand, &act_delta, NULL,
|
||||
true);
|
||||
true);
|
||||
iv_ca_set_no_cp (data, ivs, group);
|
||||
act_delta = iv_ca_delta_add (group, NULL, cp, act_delta);
|
||||
|
||||
|
@ -6991,12 +7046,16 @@ create_new_ivs (struct ivopts_data *data, struct iv_ca *set)
|
|||
if (data->loop_loc != UNKNOWN_LOCATION)
|
||||
fprintf (dump_file, " at %s:%d", LOCATION_FILE (data->loop_loc),
|
||||
LOCATION_LINE (data->loop_loc));
|
||||
fprintf (dump_file, ", %lu avg niters",
|
||||
avg_loop_niter (data->current_loop));
|
||||
fprintf (dump_file, ", %lu expressions",
|
||||
set->used_inv_exprs->elements ());
|
||||
fprintf (dump_file, ", %lu IVs:\n", bitmap_count_bits (set->cands));
|
||||
EXECUTE_IF_SET_IN_BITMAP (set->cands, 0, i, bi)
|
||||
{
|
||||
cand = data->vcands[i];
|
||||
dump_cand (dump_file, cand);
|
||||
}
|
||||
{
|
||||
cand = data->vcands[i];
|
||||
dump_cand (dump_file, cand);
|
||||
}
|
||||
fprintf (dump_file, "\n");
|
||||
}
|
||||
}
|
||||
|
@ -7251,10 +7310,10 @@ rewrite_use_compare (struct ivopts_data *data,
|
|||
gimple_seq stmts;
|
||||
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
{
|
||||
fprintf (dump_file, "Replacing exit test: ");
|
||||
print_gimple_stmt (dump_file, use->stmt, 0, TDF_SLIM);
|
||||
}
|
||||
{
|
||||
fprintf (dump_file, "Replacing exit test: ");
|
||||
print_gimple_stmt (dump_file, use->stmt, 0, TDF_SLIM);
|
||||
}
|
||||
compare = cp->comp;
|
||||
bound = unshare_expr (fold_convert (var_type, bound));
|
||||
op = force_gimple_operand (bound, &stmts, true, NULL_TREE);
|
||||
|
@ -7542,7 +7601,7 @@ free_loop_data (struct ivopts_data *data)
|
|||
decl_rtl_to_reset.truncate (0);
|
||||
|
||||
data->inv_expr_tab->empty ();
|
||||
data->inv_expr_id = 0;
|
||||
data->max_inv_expr_id = 0;
|
||||
|
||||
data->iv_common_cand_tab->empty ();
|
||||
data->iv_common_cands.truncate (0);
|
||||
|
|
Loading…
Add table
Reference in a new issue