This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Vectorizer TLC
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 18 Mar 2013 12:40:13 +0100 (CET)
- Subject: [PATCH] Vectorizer TLC
The following is a collection of TLC sitting in my local tree,
mostly resulting in less obscure IL after vectorization.
Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.
Richard.
2013-03-18 Richard Biener <rguenther@suse.de>
* tree-vect-loop-manip.c (vect_create_cond_for_alias_checks):
Remove cond_expr_stmt_list argument and do not gimplify the
built expression.
(vect_loop_versioning): Adjust.
* tree-vect-data-refs.c (vect_create_addr_base_for_vector_ref):
Cleanup to use less temporaries.
(vect_create_data_ref_ptr): Cleanup.
Index: gcc/tree-vect-loop-manip.c
===================================================================
*** gcc/tree-vect-loop-manip.c.orig 2013-02-20 11:05:04.000000000 +0100
--- gcc/tree-vect-loop-manip.c 2013-03-18 11:38:46.633554021 +0100
*************** vect_vfa_segment_size (struct data_refer
*** 2271,2290 ****
Output:
COND_EXPR - conditional expression.
- COND_EXPR_STMT_LIST - statements needed to construct the conditional
- expression.
-
The returned value is the conditional expression to be used in the if
statement that controls which version of the loop gets executed at runtime.
*/
static void
! vect_create_cond_for_alias_checks (loop_vec_info loop_vinfo,
! tree * cond_expr,
! gimple_seq * cond_expr_stmt_list)
{
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
vec<ddr_p> may_alias_ddrs =
LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo);
int vect_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
--- 2271,2284 ----
Output:
COND_EXPR - conditional expression.
The returned value is the conditional expression to be used in the if
statement that controls which version of the loop gets executed at runtime.
*/
static void
! vect_create_cond_for_alias_checks (loop_vec_info loop_vinfo, tree * cond_expr)
{
vec<ddr_p> may_alias_ddrs =
LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo);
int vect_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
*************** vect_create_cond_for_alias_checks (loop_
*** 2333,2344 ****
dr_b = STMT_VINFO_DATA_REF (vinfo_for_stmt (stmt_b));
}
! addr_base_a =
! vect_create_addr_base_for_vector_ref (stmt_a, cond_expr_stmt_list,
! NULL_TREE, loop);
! addr_base_b =
! vect_create_addr_base_for_vector_ref (stmt_b, cond_expr_stmt_list,
! NULL_TREE, loop);
if (!operand_equal_p (DR_STEP (dr_a), DR_STEP (dr_b), 0))
length_factor = scalar_loop_iters;
--- 2327,2340 ----
dr_b = STMT_VINFO_DATA_REF (vinfo_for_stmt (stmt_b));
}
! addr_base_a
! = fold_build_pointer_plus (DR_BASE_ADDRESS (dr_a),
! size_binop (PLUS_EXPR, DR_OFFSET (dr_a),
! DR_INIT (dr_a)));
! addr_base_b
! = fold_build_pointer_plus (DR_BASE_ADDRESS (dr_b),
! size_binop (PLUS_EXPR, DR_OFFSET (dr_b),
! DR_INIT (dr_b)));
if (!operand_equal_p (DR_STEP (dr_a), DR_STEP (dr_b), 0))
length_factor = scalar_loop_iters;
*************** vect_loop_versioning (loop_vec_info loop
*** 2435,2442 ****
&cond_expr_stmt_list);
if (LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo))
! vect_create_cond_for_alias_checks (loop_vinfo, &cond_expr,
! &cond_expr_stmt_list);
cond_expr = force_gimple_operand_1 (cond_expr, &gimplify_stmt_list,
is_gimple_condexpr, NULL_TREE);
--- 2431,2437 ----
&cond_expr_stmt_list);
if (LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo))
! vect_create_cond_for_alias_checks (loop_vinfo, &cond_expr);
cond_expr = force_gimple_operand_1 (cond_expr, &gimplify_stmt_list,
is_gimple_condexpr, NULL_TREE);
Index: gcc/tree-vect-data-refs.c
===================================================================
*** gcc/tree-vect-data-refs.c.orig 2013-03-05 16:50:25.000000000 +0100
--- gcc/tree-vect-data-refs.c 2013-03-18 11:37:47.391898625 +0100
*************** vect_create_addr_base_for_vector_ref (gi
*** 3556,3574 ****
{
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
! tree data_ref_base = unshare_expr (DR_BASE_ADDRESS (dr));
const char *base_name;
! tree data_ref_base_var;
! tree vec_stmt;
! tree addr_base, addr_expr;
tree dest;
gimple_seq seq = NULL;
! tree base_offset = unshare_expr (DR_OFFSET (dr));
! tree init = unshare_expr (DR_INIT (dr));
tree vect_ptr_type;
tree step = TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dr)));
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
- tree base;
if (loop_vinfo && loop && loop != (gimple_bb (stmt))->loop_father)
{
--- 3556,3571 ----
{
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
! tree data_ref_base;
const char *base_name;
! tree addr_base;
tree dest;
gimple_seq seq = NULL;
! tree base_offset;
! tree init;
tree vect_ptr_type;
tree step = TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dr)));
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
if (loop_vinfo && loop && loop != (gimple_bb (stmt))->loop_father)
{
*************** vect_create_addr_base_for_vector_ref (gi
*** 3580,3585 ****
--- 3577,3588 ----
base_offset = unshare_expr (STMT_VINFO_DR_OFFSET (stmt_info));
init = unshare_expr (STMT_VINFO_DR_INIT (stmt_info));
}
+ else
+ {
+ data_ref_base = unshare_expr (DR_BASE_ADDRESS (dr));
+ base_offset = unshare_expr (DR_OFFSET (dr));
+ init = unshare_expr (DR_INIT (dr));
+ }
if (loop_vinfo)
base_name = get_name (data_ref_base);
*************** vect_create_addr_base_for_vector_ref (gi
*** 3590,3618 ****
base_name = get_name (DR_REF (dr));
}
- data_ref_base_var = create_tmp_var (TREE_TYPE (data_ref_base), "batmp");
- data_ref_base = force_gimple_operand (data_ref_base, &seq, true,
- data_ref_base_var);
- gimple_seq_add_seq (new_stmt_list, seq);
-
/* Create base_offset */
base_offset = size_binop (PLUS_EXPR,
fold_convert (sizetype, base_offset),
fold_convert (sizetype, init));
- dest = create_tmp_var (sizetype, "base_off");
- base_offset = force_gimple_operand (base_offset, &seq, true, dest);
- gimple_seq_add_seq (new_stmt_list, seq);
if (offset)
{
- tree tmp = create_tmp_var (sizetype, "offset");
-
offset = fold_build2 (MULT_EXPR, sizetype,
fold_convert (sizetype, offset), step);
base_offset = fold_build2 (PLUS_EXPR, sizetype,
base_offset, offset);
- base_offset = force_gimple_operand (base_offset, &seq, false, tmp);
- gimple_seq_add_seq (new_stmt_list, seq);
}
/* base + base_offset */
--- 3593,3609 ----
*************** vect_create_addr_base_for_vector_ref (gi
*** 3626,3659 ****
}
vect_ptr_type = build_pointer_type (STMT_VINFO_VECTYPE (stmt_info));
! base = get_base_address (DR_REF (dr));
! if (base
! && TREE_CODE (base) == MEM_REF)
! vect_ptr_type
! = build_qualified_type (vect_ptr_type,
! TYPE_QUALS (TREE_TYPE (TREE_OPERAND (base, 0))));
!
! vec_stmt = fold_convert (vect_ptr_type, addr_base);
! addr_expr = vect_get_new_vect_var (vect_ptr_type, vect_pointer_var,
! base_name);
! vec_stmt = force_gimple_operand (vec_stmt, &seq, false, addr_expr);
gimple_seq_add_seq (new_stmt_list, seq);
if (DR_PTR_INFO (dr)
! && TREE_CODE (vec_stmt) == SSA_NAME)
{
! duplicate_ssa_name_ptr_info (vec_stmt, DR_PTR_INFO (dr));
if (offset)
! mark_ptr_info_alignment_unknown (SSA_NAME_PTR_INFO (vec_stmt));
}
if (dump_enabled_p ())
{
dump_printf_loc (MSG_NOTE, vect_location, "created ");
! dump_generic_expr (MSG_NOTE, TDF_SLIM, vec_stmt);
}
! return vec_stmt;
}
--- 3617,3642 ----
}
vect_ptr_type = build_pointer_type (STMT_VINFO_VECTYPE (stmt_info));
! addr_base = fold_convert (vect_ptr_type, addr_base);
! dest = vect_get_new_vect_var (vect_ptr_type, vect_pointer_var, base_name);
! addr_base = force_gimple_operand (addr_base, &seq, false, dest);
gimple_seq_add_seq (new_stmt_list, seq);
if (DR_PTR_INFO (dr)
! && TREE_CODE (addr_base) == SSA_NAME)
{
! duplicate_ssa_name_ptr_info (addr_base, DR_PTR_INFO (dr));
if (offset)
! mark_ptr_info_alignment_unknown (SSA_NAME_PTR_INFO (addr_base));
}
if (dump_enabled_p ())
{
dump_printf_loc (MSG_NOTE, vect_location, "created ");
! dump_generic_expr (MSG_NOTE, TDF_SLIM, addr_base);
}
! return addr_base;
}
*************** vect_create_data_ref_ptr (gimple stmt, t
*** 3733,3739 ****
gimple incr;
tree step;
bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
- tree base;
gcc_assert (TREE_CODE (aggr_type) == ARRAY_TYPE
|| TREE_CODE (aggr_type) == VECTOR_TYPE);
--- 3716,3721 ----
*************** vect_create_data_ref_ptr (gimple stmt, t
*** 3785,3837 ****
dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_BASE_OBJECT (dr));
}
! /* (1) Create the new aggregate-pointer variable. */
! aggr_ptr_type = build_pointer_type (aggr_type);
! base = get_base_address (DR_REF (dr));
! if (base
! && TREE_CODE (base) == MEM_REF)
! aggr_ptr_type
! = build_qualified_type (aggr_ptr_type,
! TYPE_QUALS (TREE_TYPE (TREE_OPERAND (base, 0))));
! aggr_ptr = vect_get_new_vect_var (aggr_ptr_type, vect_pointer_var, base_name);
!
! /* Vector and array types inherit the alias set of their component
type by default so we need to use a ref-all pointer if the data
reference does not conflict with the created aggregated data
reference because it is not addressable. */
! if (!alias_sets_conflict_p (get_deref_alias_set (aggr_ptr),
get_alias_set (DR_REF (dr))))
! {
! aggr_ptr_type
! = build_pointer_type_for_mode (aggr_type,
! TYPE_MODE (aggr_ptr_type), true);
! aggr_ptr = vect_get_new_vect_var (aggr_ptr_type, vect_pointer_var,
! base_name);
! }
!
/* Likewise for any of the data references in the stmt group. */
else if (STMT_VINFO_GROUP_SIZE (stmt_info) > 1)
{
gimple orig_stmt = STMT_VINFO_GROUP_FIRST_ELEMENT (stmt_info);
do
{
! tree lhs = gimple_assign_lhs (orig_stmt);
! if (!alias_sets_conflict_p (get_deref_alias_set (aggr_ptr),
! get_alias_set (lhs)))
{
! aggr_ptr_type
! = build_pointer_type_for_mode (aggr_type,
! TYPE_MODE (aggr_ptr_type), true);
! aggr_ptr
! = vect_get_new_vect_var (aggr_ptr_type, vect_pointer_var,
! base_name);
break;
}
!
! orig_stmt = STMT_VINFO_GROUP_NEXT_ELEMENT (vinfo_for_stmt (orig_stmt));
}
while (orig_stmt);
}
/* Note: If the dataref is in an inner-loop nested in LOOP, and we are
vectorizing LOOP (i.e., outer-loop vectorization), we need to create two
--- 3767,3803 ----
dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_BASE_OBJECT (dr));
}
! /* (1) Create the new aggregate-pointer variable.
! Vector and array types inherit the alias set of their component
type by default so we need to use a ref-all pointer if the data
reference does not conflict with the created aggregated data
reference because it is not addressable. */
! bool need_ref_all = false;
! if (!alias_sets_conflict_p (get_alias_set (aggr_type),
get_alias_set (DR_REF (dr))))
! need_ref_all = true;
/* Likewise for any of the data references in the stmt group. */
else if (STMT_VINFO_GROUP_SIZE (stmt_info) > 1)
{
gimple orig_stmt = STMT_VINFO_GROUP_FIRST_ELEMENT (stmt_info);
do
{
! stmt_vec_info sinfo = vinfo_for_stmt (orig_stmt);
! struct data_reference *sdr = STMT_VINFO_DATA_REF (sinfo);
! if (!alias_sets_conflict_p (get_alias_set (aggr_type),
! get_alias_set (DR_REF (sdr))))
{
! need_ref_all = true;
break;
}
! orig_stmt = STMT_VINFO_GROUP_NEXT_ELEMENT (sinfo);
}
while (orig_stmt);
}
+ aggr_ptr_type = build_pointer_type_for_mode (aggr_type, ptr_mode,
+ need_ref_all);
+ aggr_ptr = vect_get_new_vect_var (aggr_ptr_type, vect_pointer_var, base_name);
+
/* Note: If the dataref is in an inner-loop nested in LOOP, and we are
vectorizing LOOP (i.e., outer-loop vectorization), we need to create two