aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vect-loop.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-vect-loop.c')
-rw-r--r--gcc/tree-vect-loop.c147
1 files changed, 50 insertions, 97 deletions
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index 8740a7573ac..8b2a61e733b 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -1098,112 +1098,77 @@ bb_in_loop_p (const_basic_block bb, const void *data)
}
-/* Function new_loop_vec_info.
-
- Create and initialize a new loop_vec_info struct for LOOP, as well as
- stmt_vec_info structs for all the stmts in LOOP. */
-
-static loop_vec_info
-new_loop_vec_info (struct loop *loop)
+/* Create and initialize a new loop_vec_info struct for LOOP_IN, as well as
+ stmt_vec_info structs for all the stmts in LOOP_IN. */
+
+_loop_vec_info::_loop_vec_info (struct loop *loop_in)
+ : vec_info (vec_info::loop, init_cost (loop_in)),
+ loop (loop_in),
+ bbs (XCNEWVEC (basic_block, loop->num_nodes)),
+ num_itersm1 (NULL_TREE),
+ num_iters (NULL_TREE),
+ num_iters_unchanged (NULL_TREE),
+ num_iters_assumptions (NULL_TREE),
+ th (0),
+ vectorization_factor (0),
+ unaligned_dr (NULL),
+ peeling_for_alignment (0),
+ ptr_mask (0),
+ slp_unrolling_factor (1),
+ single_scalar_iteration_cost (0),
+ vectorizable (false),
+ peeling_for_gaps (false),
+ peeling_for_niter (false),
+ operands_swapped (false),
+ no_data_dependencies (false),
+ has_mask_store (false),
+ scalar_loop (NULL),
+ orig_loop_info (NULL)
{
- loop_vec_info res;
- basic_block *bbs;
- gimple_stmt_iterator si;
- unsigned int i, nbbs;
-
- res = (loop_vec_info) xcalloc (1, sizeof (struct _loop_vec_info));
- res->kind = vec_info::loop;
- LOOP_VINFO_LOOP (res) = loop;
-
- bbs = get_loop_body (loop);
-
/* Create/Update stmt_info for all stmts in the loop. */
- for (i = 0; i < loop->num_nodes; i++)
+ basic_block *body = get_loop_body (loop);
+ for (unsigned int i = 0; i < loop->num_nodes; i++)
{
- basic_block bb = bbs[i];
+ basic_block bb = body[i];
+ gimple_stmt_iterator si;
for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
{
gimple *phi = gsi_stmt (si);
gimple_set_uid (phi, 0);
- set_vinfo_for_stmt (phi, new_stmt_vec_info (phi, res));
+ set_vinfo_for_stmt (phi, new_stmt_vec_info (phi, this));
}
for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
{
gimple *stmt = gsi_stmt (si);
gimple_set_uid (stmt, 0);
- set_vinfo_for_stmt (stmt, new_stmt_vec_info (stmt, res));
+ set_vinfo_for_stmt (stmt, new_stmt_vec_info (stmt, this));
}
}
+ free (body);
/* CHECKME: We want to visit all BBs before their successors (except for
latch blocks, for which this assertion wouldn't hold). In the simple
case of the loop forms we allow, a dfs order of the BBs would the same
as reversed postorder traversal, so we are safe. */
- free (bbs);
- bbs = XCNEWVEC (basic_block, loop->num_nodes);
- nbbs = dfs_enumerate_from (loop->header, 0, bb_in_loop_p,
- bbs, loop->num_nodes, loop);
- gcc_assert (nbbs == loop->num_nodes);
-
- LOOP_VINFO_BBS (res) = bbs;
- LOOP_VINFO_NITERSM1 (res) = NULL;
- LOOP_VINFO_NITERS (res) = NULL;
- LOOP_VINFO_NITERS_UNCHANGED (res) = NULL;
- LOOP_VINFO_NITERS_ASSUMPTIONS (res) = NULL;
- LOOP_VINFO_COST_MODEL_THRESHOLD (res) = 0;
- LOOP_VINFO_VECTORIZABLE_P (res) = 0;
- LOOP_VINFO_PEELING_FOR_ALIGNMENT (res) = 0;
- LOOP_VINFO_VECT_FACTOR (res) = 0;
- LOOP_VINFO_LOOP_NEST (res) = vNULL;
- LOOP_VINFO_DATAREFS (res) = vNULL;
- LOOP_VINFO_DDRS (res) = vNULL;
- LOOP_VINFO_UNALIGNED_DR (res) = NULL;
- LOOP_VINFO_MAY_MISALIGN_STMTS (res) = vNULL;
- LOOP_VINFO_MAY_ALIAS_DDRS (res) = vNULL;
- LOOP_VINFO_GROUPED_STORES (res) = vNULL;
- LOOP_VINFO_REDUCTIONS (res) = vNULL;
- LOOP_VINFO_REDUCTION_CHAINS (res) = vNULL;
- LOOP_VINFO_SLP_INSTANCES (res) = vNULL;
- LOOP_VINFO_SLP_UNROLLING_FACTOR (res) = 1;
- LOOP_VINFO_TARGET_COST_DATA (res) = init_cost (loop);
- LOOP_VINFO_PEELING_FOR_GAPS (res) = false;
- LOOP_VINFO_PEELING_FOR_NITER (res) = false;
- LOOP_VINFO_OPERANDS_SWAPPED (res) = false;
- LOOP_VINFO_ORIG_LOOP_INFO (res) = NULL;
-
- return res;
+ unsigned int nbbs = dfs_enumerate_from (loop->header, 0, bb_in_loop_p,
+ bbs, loop->num_nodes, loop);
+ gcc_assert (nbbs == loop->num_nodes);
}
-/* Function destroy_loop_vec_info.
-
- Free LOOP_VINFO struct, as well as all the stmt_vec_info structs of all the
- stmts in the loop. */
+/* Free all memory used by the _loop_vec_info, as well as all the
+ stmt_vec_info structs of all the stmts in the loop. */
-void
-destroy_loop_vec_info (loop_vec_info loop_vinfo, bool clean_stmts)
+_loop_vec_info::~_loop_vec_info ()
{
- struct loop *loop;
- basic_block *bbs;
int nbbs;
gimple_stmt_iterator si;
int j;
- vec<slp_instance> slp_instances;
- slp_instance instance;
- bool swapped;
-
- if (!loop_vinfo)
- return;
-
- loop = LOOP_VINFO_LOOP (loop_vinfo);
-
- bbs = LOOP_VINFO_BBS (loop_vinfo);
- nbbs = clean_stmts ? loop->num_nodes : 0;
- swapped = LOOP_VINFO_OPERANDS_SWAPPED (loop_vinfo);
+ nbbs = loop->num_nodes;
for (j = 0; j < nbbs; j++)
{
basic_block bb = bbs[j];
@@ -1216,7 +1181,7 @@ destroy_loop_vec_info (loop_vec_info loop_vinfo, bool clean_stmts)
/* We may have broken canonical form by moving a constant
into RHS1 of a commutative op. Fix such occurrences. */
- if (swapped && is_gimple_assign (stmt))
+ if (operands_swapped && is_gimple_assign (stmt))
{
enum tree_code code = gimple_assign_rhs_code (stmt);
@@ -1256,26 +1221,8 @@ destroy_loop_vec_info (loop_vec_info loop_vinfo, bool clean_stmts)
}
}
- free (LOOP_VINFO_BBS (loop_vinfo));
- vect_destroy_datarefs (loop_vinfo);
- free_dependence_relations (LOOP_VINFO_DDRS (loop_vinfo));
- LOOP_VINFO_LOOP_NEST (loop_vinfo).release ();
- LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo).release ();
- LOOP_VINFO_COMP_ALIAS_DDRS (loop_vinfo).release ();
- LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo).release ();
- slp_instances = LOOP_VINFO_SLP_INSTANCES (loop_vinfo);
- FOR_EACH_VEC_ELT (slp_instances, j, instance)
- vect_free_slp_instance (instance);
-
- LOOP_VINFO_SLP_INSTANCES (loop_vinfo).release ();
- LOOP_VINFO_GROUPED_STORES (loop_vinfo).release ();
- LOOP_VINFO_REDUCTIONS (loop_vinfo).release ();
- LOOP_VINFO_REDUCTION_CHAINS (loop_vinfo).release ();
-
- destroy_cost_data (LOOP_VINFO_TARGET_COST_DATA (loop_vinfo));
- loop_vinfo->scalar_cost_vec.release ();
+ free (bbs);
- free (loop_vinfo);
loop->aux = NULL;
}
@@ -1562,7 +1509,7 @@ vect_analyze_loop_form (struct loop *loop)
&number_of_iterations, &inner_loop_cond))
return NULL;
- loop_vec_info loop_vinfo = new_loop_vec_info (loop);
+ loop_vec_info loop_vinfo = new _loop_vec_info (loop);
LOOP_VINFO_NITERSM1 (loop_vinfo) = number_of_iterationsm1;
LOOP_VINFO_NITERS (loop_vinfo) = number_of_iterations;
LOOP_VINFO_NITERS_UNCHANGED (loop_vinfo) = number_of_iterations;
@@ -2343,6 +2290,7 @@ again:
}
/* Free optimized alias test DDRS. */
LOOP_VINFO_COMP_ALIAS_DDRS (loop_vinfo).release ();
+ LOOP_VINFO_CHECK_UNEQUAL_ADDRS (loop_vinfo).release ();
/* Reset target cost data. */
destroy_cost_data (LOOP_VINFO_TARGET_COST_DATA (loop_vinfo));
LOOP_VINFO_TARGET_COST_DATA (loop_vinfo)
@@ -2409,7 +2357,7 @@ vect_analyze_loop (struct loop *loop, loop_vec_info orig_loop_vinfo)
return loop_vinfo;
}
- destroy_loop_vec_info (loop_vinfo, true);
+ delete loop_vinfo;
vector_sizes &= ~current_vector_size;
if (fatal
@@ -3434,6 +3382,11 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo,
unsigned len = LOOP_VINFO_COMP_ALIAS_DDRS (loop_vinfo).length ();
(void) add_stmt_cost (target_cost_data, len, vector_stmt, NULL, 0,
vect_prologue);
+ len = LOOP_VINFO_CHECK_UNEQUAL_ADDRS (loop_vinfo).length ();
+ if (len)
+ /* Count LEN - 1 ANDs and LEN comparisons. */
+ (void) add_stmt_cost (target_cost_data, len * 2 - 1, scalar_stmt,
+ NULL, 0, vect_prologue);
dump_printf (MSG_NOTE,
"cost model: Adding cost of checks for loop "
"versioning aliasing.\n");