Commit 7078979b by Bin Cheng Committed by Bin Cheng

tree-vectorizer.h (vect_build_loop_niters): New parameter.

	* tree-vectorizer.h (vect_build_loop_niters): New parameter.
	* tree-vect-loop-manip.c (vect_build_loop_niters): New parameter.
	Set true to new parameter if new ssa variable is defined.
	(vect_gen_vector_loop_niters): Refactor.  Set range information
	for the new vector loop bound variable.
	(vect_do_peeling): Ditto.

From-SVN: r248958
parent ba00284c
2017-06-07 Bin Cheng <bin.cheng@arm.com> 2017-06-07 Bin Cheng <bin.cheng@arm.com>
* tree-vectorizer.h (vect_build_loop_niters): New parameter.
* tree-vect-loop-manip.c (vect_build_loop_niters): New parameter.
Set true to new parameter if new ssa variable is defined.
(vect_gen_vector_loop_niters): Refactor. Set range information
for the new vector loop bound variable.
(vect_do_peeling): Ditto.
2017-06-07 Bin Cheng <bin.cheng@arm.com>
* tree-affine.c (ssa.h): Include header file. * tree-affine.c (ssa.h): Include header file.
(tree_to_aff_combination): Handle (T1)(X - CST) when inner type (tree_to_aff_combination): Handle (T1)(X - CST) when inner type
has wrapping overflow behavior. has wrapping overflow behavior.
......
...@@ -1095,10 +1095,11 @@ vect_update_inits_of_drs (loop_vec_info loop_vinfo, tree niters) ...@@ -1095,10 +1095,11 @@ vect_update_inits_of_drs (loop_vec_info loop_vinfo, tree niters)
/* This function builds ni_name = number of iterations. Statements /* This function builds ni_name = number of iterations. Statements
are emitted on the loop preheader edge. */ are emitted on the loop preheader edge. If NEW_VAR_P is not NULL, set
it to TRUE if new ssa_var is generated. */
tree tree
vect_build_loop_niters (loop_vec_info loop_vinfo) vect_build_loop_niters (loop_vec_info loop_vinfo, bool *new_var_p)
{ {
tree ni = unshare_expr (LOOP_VINFO_NITERS (loop_vinfo)); tree ni = unshare_expr (LOOP_VINFO_NITERS (loop_vinfo));
if (TREE_CODE (ni) == INTEGER_CST) if (TREE_CODE (ni) == INTEGER_CST)
...@@ -1112,7 +1113,11 @@ vect_build_loop_niters (loop_vec_info loop_vinfo) ...@@ -1112,7 +1113,11 @@ vect_build_loop_niters (loop_vec_info loop_vinfo)
var = create_tmp_var (TREE_TYPE (ni), "niters"); var = create_tmp_var (TREE_TYPE (ni), "niters");
ni_name = force_gimple_operand (ni, &stmts, false, var); ni_name = force_gimple_operand (ni, &stmts, false, var);
if (stmts) if (stmts)
gsi_insert_seq_on_edge_immediate (pe, stmts); {
gsi_insert_seq_on_edge_immediate (pe, stmts);
if (new_var_p != NULL)
*new_var_p = true;
}
return ni_name; return ni_name;
} }
...@@ -1177,22 +1182,21 @@ vect_gen_vector_loop_niters (loop_vec_info loop_vinfo, tree niters, ...@@ -1177,22 +1182,21 @@ vect_gen_vector_loop_niters (loop_vec_info loop_vinfo, tree niters,
tree *niters_vector_ptr, bool niters_no_overflow) tree *niters_vector_ptr, bool niters_no_overflow)
{ {
tree ni_minus_gap, var; tree ni_minus_gap, var;
tree niters_vector; tree niters_vector, type = TREE_TYPE (niters);
int vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo); int vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
edge pe = loop_preheader_edge (LOOP_VINFO_LOOP (loop_vinfo)); edge pe = loop_preheader_edge (LOOP_VINFO_LOOP (loop_vinfo));
tree log_vf = build_int_cst (TREE_TYPE (niters), exact_log2 (vf)); tree log_vf = build_int_cst (type, exact_log2 (vf));
/* If epilogue loop is required because of data accesses with gaps, we /* If epilogue loop is required because of data accesses with gaps, we
subtract one iteration from the total number of iterations here for subtract one iteration from the total number of iterations here for
correct calculation of RATIO. */ correct calculation of RATIO. */
if (LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo)) if (LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo))
{ {
ni_minus_gap = fold_build2 (MINUS_EXPR, TREE_TYPE (niters), ni_minus_gap = fold_build2 (MINUS_EXPR, type, niters,
niters, build_one_cst (type));
build_one_cst (TREE_TYPE (niters)));
if (!is_gimple_val (ni_minus_gap)) if (!is_gimple_val (ni_minus_gap))
{ {
var = create_tmp_var (TREE_TYPE (niters), "ni_gap"); var = create_tmp_var (type, "ni_gap");
gimple *stmts = NULL; gimple *stmts = NULL;
ni_minus_gap = force_gimple_operand (ni_minus_gap, &stmts, ni_minus_gap = force_gimple_operand (ni_minus_gap, &stmts,
true, var); true, var);
...@@ -1208,25 +1212,28 @@ vect_gen_vector_loop_niters (loop_vec_info loop_vinfo, tree niters, ...@@ -1208,25 +1212,28 @@ vect_gen_vector_loop_niters (loop_vec_info loop_vinfo, tree niters,
(niters - vf) >> log2(vf) + 1 by using the fact that we know ratio (niters - vf) >> log2(vf) + 1 by using the fact that we know ratio
will be at least one. */ will be at least one. */
if (niters_no_overflow) if (niters_no_overflow)
niters_vector = fold_build2 (RSHIFT_EXPR, TREE_TYPE (niters), niters_vector = fold_build2 (RSHIFT_EXPR, type, ni_minus_gap, log_vf);
ni_minus_gap, log_vf);
else else
niters_vector niters_vector
= fold_build2 (PLUS_EXPR, TREE_TYPE (niters), = fold_build2 (PLUS_EXPR, type,
fold_build2 (RSHIFT_EXPR, TREE_TYPE (niters), fold_build2 (RSHIFT_EXPR, type,
fold_build2 (MINUS_EXPR, TREE_TYPE (niters), fold_build2 (MINUS_EXPR, type, ni_minus_gap,
ni_minus_gap, build_int_cst (type, vf)),
build_int_cst
(TREE_TYPE (niters), vf)),
log_vf), log_vf),
build_int_cst (TREE_TYPE (niters), 1)); build_int_cst (type, 1));
if (!is_gimple_val (niters_vector)) if (!is_gimple_val (niters_vector))
{ {
var = create_tmp_var (TREE_TYPE (niters), "bnd"); var = create_tmp_var (type, "bnd");
gimple *stmts = NULL; gimple_seq stmts = NULL;
niters_vector = force_gimple_operand (niters_vector, &stmts, true, var); niters_vector = force_gimple_operand (niters_vector, &stmts, true, var);
gsi_insert_seq_on_edge_immediate (pe, stmts); gsi_insert_seq_on_edge_immediate (pe, stmts);
/* Peeling algorithm guarantees that vector loop bound is at least ONE,
we set range information to make niters analyzer's life easier. */
if (stmts != NULL)
set_range_info (niters_vector, VR_RANGE, build_int_cst (type, 1),
fold_build2 (RSHIFT_EXPR, type,
TYPE_MAX_VALUE (type), log_vf));
} }
*niters_vector_ptr = niters_vector; *niters_vector_ptr = niters_vector;
...@@ -1771,7 +1778,13 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, tree nitersm1, ...@@ -1771,7 +1778,13 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, tree nitersm1,
LOOP_VINFO_NITERSM1 (loop_vinfo) LOOP_VINFO_NITERSM1 (loop_vinfo)
= fold_build2 (MINUS_EXPR, type, = fold_build2 (MINUS_EXPR, type,
LOOP_VINFO_NITERSM1 (loop_vinfo), niters_prolog); LOOP_VINFO_NITERSM1 (loop_vinfo), niters_prolog);
niters = vect_build_loop_niters (loop_vinfo); bool new_var_p = false;
niters = vect_build_loop_niters (loop_vinfo, &new_var_p);
/* It's guaranteed that vector loop bound before vectorization is at
least VF, so set range information for newly generated var. */
if (new_var_p)
set_range_info (niters, VR_RANGE,
build_int_cst (type, vf), TYPE_MAX_VALUE (type));
/* Prolog iterates at most bound_prolog times, latch iterates at /* Prolog iterates at most bound_prolog times, latch iterates at
most bound_prolog - 1 times. */ most bound_prolog - 1 times. */
......
...@@ -1150,7 +1150,7 @@ extern gimple *vect_force_simple_reduction (loop_vec_info, gimple *, ...@@ -1150,7 +1150,7 @@ extern gimple *vect_force_simple_reduction (loop_vec_info, gimple *,
bool *, bool); bool *, bool);
/* Drive for loop analysis stage. */ /* Drive for loop analysis stage. */
extern loop_vec_info vect_analyze_loop (struct loop *, loop_vec_info); extern loop_vec_info vect_analyze_loop (struct loop *, loop_vec_info);
extern tree vect_build_loop_niters (loop_vec_info); extern tree vect_build_loop_niters (loop_vec_info, bool * = NULL);
extern void vect_gen_vector_loop_niters (loop_vec_info, tree, tree *, bool); extern void vect_gen_vector_loop_niters (loop_vec_info, tree, tree *, bool);
/* Drive for loop transformation stage. */ /* Drive for loop transformation stage. */
extern struct loop *vect_transform_loop (loop_vec_info); extern struct loop *vect_transform_loop (loop_vec_info);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment