* [1/7] Use innermost_loop_behavior for outer loop vectorisation
@ 2017-07-03 7:31 Richard Sandiford
2017-07-03 9:40 ` Richard Biener
0 siblings, 1 reply; 2+ messages in thread
From: Richard Sandiford @ 2017-07-03 7:31 UTC (permalink / raw)
To: gcc-patches
This patch replaces the individual stmt_vinfo dr_* fields with
an innermost_loop_behavior, so that the changes in later patches
get picked up automatically. It also adds a helper function for
getting the behavior of a data reference wrt the vectorised loop.
Tested on aarch64-linux-gnu and x86_64-linux-gnu. OK to install?
Richard
2017-07-03 Richard Sandiford <richard.sandiford@linaro.org>
gcc/
* tree-vectorizer.h (_stmt_vec_info): Replace individual dr_*
fields with dr_wrt_vec_loop.
(STMT_VINFO_DR_BASE_ADDRESS, STMT_VINFO_DR_INIT, STMT_VINFO_DR_OFFSET)
(STMT_VINFO_DR_STEP, STMT_VINFO_DR_ALIGNED_TO): Update accordingly.
(STMT_VINFO_DR_WRT_VEC_LOOP): New macro.
(vect_dr_behavior): New function.
(vect_create_addr_base_for_vector_ref): Remove loop parameter.
* tree-vect-data-refs.c (vect_compute_data_ref_alignment): Use
vect_dr_behavior. Use a step_preserves_misalignment_p boolean to
track whether the step preserves the misalignment.
(vect_create_addr_base_for_vector_ref): Remove loop parameter.
Use vect_dr_behavior.
(vect_setup_realignment): Update call accordingly.
(vect_create_data_ref_ptr): Likewise. Use vect_dr_behavior.
* tree-vect-loop-manip.c (vect_gen_prolog_loop_niters): Update
call to vect_create_addr_base_for_vector_ref.
(vect_create_cond_for_align_checks): Likewise.
* tree-vect-patterns.c (vect_recog_bool_pattern): Copy
STMT_VINFO_DR_WRT_VEC_LOOP as a block.
(vect_recog_mask_conversion_pattern): Likewise.
* tree-vect-stmts.c (compare_step_with_zero): Use vect_dr_behavior.
(new_stmt_vec_info): Remove redundant zeroing.
Index: gcc/tree-vectorizer.h
===================================================================
--- gcc/tree-vectorizer.h 2017-07-03 07:53:58.155555242 +0100
+++ gcc/tree-vectorizer.h 2017-07-03 07:57:56.883079731 +0100
@@ -554,11 +554,7 @@ typedef struct _stmt_vec_info {
/* Information about the data-ref relative to this loop
nest (the loop that is being considered for vectorization). */
- tree dr_base_address;
- tree dr_init;
- tree dr_offset;
- tree dr_step;
- tree dr_aligned_to;
+ innermost_loop_behavior dr_wrt_vec_loop;
/* For loop PHI nodes, the base and evolution part of it. This makes sure
this information is still available in vect_update_ivs_after_vectorizer
@@ -706,11 +702,12 @@ #define STMT_VINFO_SIMD_LANE_ACCESS_P(S)
#define STMT_VINFO_VEC_REDUCTION_TYPE(S) (S)->v_reduc_type
#define STMT_VINFO_VEC_CONST_COND_REDUC_CODE(S) (S)->const_cond_reduc_code
-#define STMT_VINFO_DR_BASE_ADDRESS(S) (S)->dr_base_address
-#define STMT_VINFO_DR_INIT(S) (S)->dr_init
-#define STMT_VINFO_DR_OFFSET(S) (S)->dr_offset
-#define STMT_VINFO_DR_STEP(S) (S)->dr_step
-#define STMT_VINFO_DR_ALIGNED_TO(S) (S)->dr_aligned_to
+#define STMT_VINFO_DR_WRT_VEC_LOOP(S) (S)->dr_wrt_vec_loop
+#define STMT_VINFO_DR_BASE_ADDRESS(S) (S)->dr_wrt_vec_loop.base_address
+#define STMT_VINFO_DR_INIT(S) (S)->dr_wrt_vec_loop.init
+#define STMT_VINFO_DR_OFFSET(S) (S)->dr_wrt_vec_loop.offset
+#define STMT_VINFO_DR_STEP(S) (S)->dr_wrt_vec_loop.step
+#define STMT_VINFO_DR_ALIGNED_TO(S) (S)->dr_wrt_vec_loop.aligned_to
#define STMT_VINFO_IN_PATTERN_P(S) (S)->in_pattern_p
#define STMT_VINFO_RELATED_STMT(S) (S)->related_stmt
@@ -1012,6 +1009,22 @@ known_alignment_for_access_p (struct dat
return (DR_MISALIGNMENT (data_ref_info) != DR_MISALIGNMENT_UNKNOWN);
}
+/* Return the behavior of DR with respect to the vectorization context
+ (which for outer loop vectorization might not be the behavior recorded
+ in DR itself). */
+
+static inline innermost_loop_behavior *
+vect_dr_behavior (data_reference *dr)
+{
+ gimple *stmt = DR_STMT (dr);
+ stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
+ loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
+ if (loop_vinfo == NULL
+ || !nested_in_vect_loop_p (LOOP_VINFO_LOOP (loop_vinfo), stmt))
+ return &DR_INNERMOST (dr);
+ else
+ return &STMT_VINFO_DR_WRT_VEC_LOOP (stmt_info);
+}
/* Return true if the vect cost model is unlimited. */
static inline bool
@@ -1138,8 +1151,7 @@ extern tree vect_get_new_vect_var (tree,
extern tree vect_get_new_ssa_name (tree, enum vect_var_kind,
const char * = NULL);
extern tree vect_create_addr_base_for_vector_ref (gimple *, gimple_seq *,
- tree, struct loop *,
- tree = NULL_TREE);
+ tree, tree = NULL_TREE);
/* In tree-vect-loop.c. */
/* FORNOW: Used in tree-parloops.c. */
Index: gcc/tree-vect-data-refs.c
===================================================================
--- gcc/tree-vect-data-refs.c 2017-07-03 07:53:58.155555242 +0100
+++ gcc/tree-vect-data-refs.c 2017-07-03 07:57:47.758408141 +0100
@@ -666,11 +666,8 @@ vect_compute_data_ref_alignment (struct
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
struct loop *loop = NULL;
tree ref = DR_REF (dr);
- tree vectype;
- tree base, base_addr;
- tree misalign = NULL_TREE;
- tree aligned_to;
- tree step;
+ tree vectype = STMT_VINFO_VECTYPE (stmt_info);
+ tree base;
unsigned HOST_WIDE_INT alignment;
if (dump_enabled_p ())
@@ -683,11 +680,15 @@ vect_compute_data_ref_alignment (struct
/* Initialize misalignment to unknown. */
SET_DR_MISALIGNMENT (dr, DR_MISALIGNMENT_UNKNOWN);
- if (tree_fits_shwi_p (DR_STEP (dr)))
- misalign = DR_INIT (dr);
- aligned_to = DR_ALIGNED_TO (dr);
- base_addr = DR_BASE_ADDRESS (dr);
- vectype = STMT_VINFO_VECTYPE (stmt_info);
+ innermost_loop_behavior *drb = vect_dr_behavior (dr);
+ bool step_preserves_misalignment_p;
+
+ /* No step for BB vectorization. */
+ if (!loop)
+ {
+ gcc_assert (integer_zerop (drb->step));
+ step_preserves_misalignment_p = true;
+ }
/* In case the dataref is in an inner-loop of the loop that is being
vectorized (LOOP), we use the base and misalignment information
@@ -695,26 +696,21 @@ vect_compute_data_ref_alignment (struct
stays the same throughout the execution of the inner-loop, which is why
we have to check that the stride of the dataref in the inner-loop evenly
divides by the vector size. */
- if (loop && nested_in_vect_loop_p (loop, stmt))
+ else if (nested_in_vect_loop_p (loop, stmt))
{
tree step = DR_STEP (dr);
+ step_preserves_misalignment_p
+ = (tree_fits_shwi_p (step)
+ && tree_to_shwi (step) % GET_MODE_SIZE (TYPE_MODE (vectype)) == 0);
- if (tree_fits_shwi_p (step)
- && tree_to_shwi (step) % GET_MODE_SIZE (TYPE_MODE (vectype)) == 0)
- {
- if (dump_enabled_p ())
- dump_printf_loc (MSG_NOTE, vect_location,
- "inner step divides the vector-size.\n");
- misalign = STMT_VINFO_DR_INIT (stmt_info);
- aligned_to = STMT_VINFO_DR_ALIGNED_TO (stmt_info);
- base_addr = STMT_VINFO_DR_BASE_ADDRESS (stmt_info);
- }
- else
+ if (dump_enabled_p ())
{
- if (dump_enabled_p ())
+ if (step_preserves_misalignment_p)
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "inner step divides the vector-size.\n");
+ else
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "inner step doesn't divide the vector-size.\n");
- misalign = NULL_TREE;
+ "inner step doesn't divide the vector-size.\n");
}
}
@@ -725,18 +721,17 @@ vect_compute_data_ref_alignment (struct
else
{
tree step = DR_STEP (dr);
- unsigned vf = loop ? LOOP_VINFO_VECT_FACTOR (loop_vinfo) : 1;
+ unsigned vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
+ step_preserves_misalignment_p
+ = (tree_fits_shwi_p (step)
+ && ((tree_to_shwi (step) * vf)
+ % GET_MODE_SIZE (TYPE_MODE (vectype)) == 0));
- if (tree_fits_shwi_p (step)
- && ((tree_to_shwi (step) * vf)
- % GET_MODE_SIZE (TYPE_MODE (vectype)) != 0))
- {
- if (dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "step doesn't divide the vector-size.\n");
- misalign = NULL_TREE;
- }
+ if (!step_preserves_misalignment_p && dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "step doesn't divide the vector-size.\n");
}
+ tree base_addr = drb->base_address;
/* To look at alignment of the base we have to preserve an inner MEM_REF
as that carries alignment information of the actual access. */
@@ -777,8 +772,8 @@ vect_compute_data_ref_alignment (struct
alignment = TYPE_ALIGN_UNIT (vectype);
- if ((compare_tree_int (aligned_to, alignment) < 0)
- || !misalign)
+ if ((compare_tree_int (drb->aligned_to, alignment) < 0)
+ || !step_preserves_misalignment_p)
{
if (dump_enabled_p ())
{
@@ -835,19 +830,16 @@ vect_compute_data_ref_alignment (struct
DR_VECT_AUX (dr)->base_element_aligned = true;
}
- if (loop && nested_in_vect_loop_p (loop, stmt))
- step = STMT_VINFO_DR_STEP (stmt_info);
- else
- step = DR_STEP (dr);
/* If this is a backward running DR then first access in the larger
vectype actually is N-1 elements before the address in the DR.
Adjust misalign accordingly. */
- if (tree_int_cst_sgn (step) < 0)
+ tree misalign = drb->init;
+ if (tree_int_cst_sgn (drb->step) < 0)
{
tree offset = ssize_int (TYPE_VECTOR_SUBPARTS (vectype) - 1);
/* DR_STEP(dr) is the same as -TYPE_SIZE of the scalar type,
otherwise we wouldn't be here. */
- offset = fold_build2 (MULT_EXPR, ssizetype, offset, step);
+ offset = fold_build2 (MULT_EXPR, ssizetype, offset, drb->step);
/* PLUS because STEP was negative. */
misalign = size_binop (PLUS_EXPR, misalign, offset);
}
@@ -3973,38 +3965,22 @@ vect_duplicate_ssa_name_ptr_info (tree n
vect_create_addr_base_for_vector_ref (gimple *stmt,
gimple_seq *new_stmt_list,
tree offset,
- struct loop *loop,
tree byte_offset)
{
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);
+ innermost_loop_behavior *drb = vect_dr_behavior (dr);
- if (loop_vinfo && loop && loop != (gimple_bb (stmt))->loop_father)
- {
- struct loop *outer_loop = LOOP_VINFO_LOOP (loop_vinfo);
-
- gcc_assert (nested_in_vect_loop_p (outer_loop, stmt));
-
- data_ref_base = unshare_expr (STMT_VINFO_DR_BASE_ADDRESS (stmt_info));
- 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));
- }
+ tree data_ref_base = unshare_expr (drb->base_address);
+ tree base_offset = unshare_expr (drb->offset);
+ tree init = unshare_expr (drb->init);
if (loop_vinfo)
base_name = get_name (data_ref_base);
@@ -4169,11 +4145,7 @@ vect_create_data_ref_ptr (gimple *stmt,
/* Check the step (evolution) of the load in LOOP, and record
whether it's invariant. */
- if (nested_in_vect_loop)
- step = STMT_VINFO_DR_STEP (stmt_info);
- else
- step = DR_STEP (STMT_VINFO_DATA_REF (stmt_info));
-
+ step = vect_dr_behavior (dr)->step;
if (integer_zerop (step))
*inv_p = true;
else
@@ -4271,7 +4243,7 @@ vect_create_data_ref_ptr (gimple *stmt,
/* Create: (&(base[init_val+offset]+byte_offset) in the loop preheader. */
new_temp = vect_create_addr_base_for_vector_ref (stmt, &new_stmt_list,
- offset, loop, byte_offset);
+ offset, byte_offset);
if (new_stmt_list)
{
if (pe)
@@ -4985,7 +4957,7 @@ vect_setup_realignment (gimple *stmt, gi
{
/* Generate the INIT_ADDR computation outside LOOP. */
init_addr = vect_create_addr_base_for_vector_ref (stmt, &stmts,
- NULL_TREE, loop);
+ NULL_TREE);
if (loop)
{
pe = loop_preheader_edge (loop);
Index: gcc/tree-vect-loop-manip.c
===================================================================
--- gcc/tree-vect-loop-manip.c 2017-07-03 07:53:58.155555242 +0100
+++ gcc/tree-vect-loop-manip.c 2017-07-03 07:57:47.758408141 +0100
@@ -949,7 +949,6 @@ vect_gen_prolog_loop_niters (loop_vec_in
basic_block bb, int *bound)
{
struct data_reference *dr = LOOP_VINFO_UNALIGNED_DR (loop_vinfo);
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
tree var;
tree niters_type = TREE_TYPE (LOOP_VINFO_NITERS (loop_vinfo));
gimple_seq stmts = NULL, new_stmts = NULL;
@@ -977,7 +976,7 @@ vect_gen_prolog_loop_niters (loop_vec_in
tree offset = negative
? size_int (-TYPE_VECTOR_SUBPARTS (vectype) + 1) : size_zero_node;
tree start_addr = vect_create_addr_base_for_vector_ref (dr_stmt,
- &stmts, offset, loop);
+ &stmts, offset);
tree type = unsigned_type_for (TREE_TYPE (start_addr));
tree vectype_align_minus_1 = build_int_cst (type, vectype_align - 1);
HOST_WIDE_INT elem_size =
@@ -1975,7 +1974,6 @@ vect_create_cond_for_align_checks (loop_
tree *cond_expr,
gimple_seq *cond_expr_stmt_list)
{
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
vec<gimple *> may_misalign_stmts
= LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo);
gimple *ref_stmt;
@@ -2016,7 +2014,7 @@ vect_create_cond_for_align_checks (loop_
/* create: addr_tmp = (int)(address_of_first_vector) */
addr_base =
vect_create_addr_base_for_vector_ref (ref_stmt, &new_stmt_list,
- offset, loop);
+ offset);
if (new_stmt_list != NULL)
gimple_seq_add_seq (cond_expr_stmt_list, new_stmt_list);
Index: gcc/tree-vect-patterns.c
===================================================================
--- gcc/tree-vect-patterns.c 2017-07-03 07:53:58.155555242 +0100
+++ gcc/tree-vect-patterns.c 2017-07-03 07:57:47.759408106 +0100
@@ -3789,14 +3789,8 @@ vect_recog_bool_pattern (vec<gimple *> *
set_vinfo_for_stmt (pattern_stmt, pattern_stmt_info);
STMT_VINFO_DATA_REF (pattern_stmt_info)
= STMT_VINFO_DATA_REF (stmt_vinfo);
- STMT_VINFO_DR_BASE_ADDRESS (pattern_stmt_info)
- = STMT_VINFO_DR_BASE_ADDRESS (stmt_vinfo);
- STMT_VINFO_DR_INIT (pattern_stmt_info) = STMT_VINFO_DR_INIT (stmt_vinfo);
- STMT_VINFO_DR_OFFSET (pattern_stmt_info)
- = STMT_VINFO_DR_OFFSET (stmt_vinfo);
- STMT_VINFO_DR_STEP (pattern_stmt_info) = STMT_VINFO_DR_STEP (stmt_vinfo);
- STMT_VINFO_DR_ALIGNED_TO (pattern_stmt_info)
- = STMT_VINFO_DR_ALIGNED_TO (stmt_vinfo);
+ STMT_VINFO_DR_WRT_VEC_LOOP (pattern_stmt_info)
+ = STMT_VINFO_DR_WRT_VEC_LOOP (stmt_vinfo);
DR_STMT (STMT_VINFO_DATA_REF (stmt_vinfo)) = pattern_stmt;
*type_out = vectype;
*type_in = vectype;
@@ -3930,14 +3924,8 @@ vect_recog_mask_conversion_pattern (vec<
set_vinfo_for_stmt (pattern_stmt, pattern_stmt_info);
STMT_VINFO_DATA_REF (pattern_stmt_info)
= STMT_VINFO_DATA_REF (stmt_vinfo);
- STMT_VINFO_DR_BASE_ADDRESS (pattern_stmt_info)
- = STMT_VINFO_DR_BASE_ADDRESS (stmt_vinfo);
- STMT_VINFO_DR_INIT (pattern_stmt_info) = STMT_VINFO_DR_INIT (stmt_vinfo);
- STMT_VINFO_DR_OFFSET (pattern_stmt_info)
- = STMT_VINFO_DR_OFFSET (stmt_vinfo);
- STMT_VINFO_DR_STEP (pattern_stmt_info) = STMT_VINFO_DR_STEP (stmt_vinfo);
- STMT_VINFO_DR_ALIGNED_TO (pattern_stmt_info)
- = STMT_VINFO_DR_ALIGNED_TO (stmt_vinfo);
+ STMT_VINFO_DR_WRT_VEC_LOOP (pattern_stmt_info)
+ = STMT_VINFO_DR_WRT_VEC_LOOP (stmt_vinfo);
DR_STMT (STMT_VINFO_DATA_REF (stmt_vinfo)) = pattern_stmt;
*type_out = vectype1;
Index: gcc/tree-vect-stmts.c
===================================================================
--- gcc/tree-vect-stmts.c 2017-07-03 07:53:58.155555242 +0100
+++ gcc/tree-vect-stmts.c 2017-07-03 07:57:47.759408106 +0100
@@ -1698,13 +1698,9 @@ static tree permute_vec_elements (tree,
compare_step_with_zero (gimple *stmt)
{
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
- loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
- tree step;
- if (loop_vinfo && nested_in_vect_loop_p (LOOP_VINFO_LOOP (loop_vinfo), stmt))
- step = STMT_VINFO_DR_STEP (stmt_info);
- else
- step = DR_STEP (STMT_VINFO_DATA_REF (stmt_info));
- return tree_int_cst_compare (step, size_zero_node);
+ data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
+ return tree_int_cst_compare (vect_dr_behavior (dr)->step,
+ size_zero_node);
}
/* If the target supports a permute mask that reverses the elements in
@@ -8851,12 +8847,6 @@ new_stmt_vec_info (gimple *stmt, vec_inf
STMT_VINFO_VEC_REDUCTION_TYPE (res) = TREE_CODE_REDUCTION;
STMT_VINFO_VEC_CONST_COND_REDUC_CODE (res) = ERROR_MARK;
- STMT_VINFO_DR_BASE_ADDRESS (res) = NULL;
- STMT_VINFO_DR_OFFSET (res) = NULL;
- STMT_VINFO_DR_INIT (res) = NULL;
- STMT_VINFO_DR_STEP (res) = NULL;
- STMT_VINFO_DR_ALIGNED_TO (res) = NULL;
-
if (gimple_code (stmt) == GIMPLE_PHI
&& is_loop_header_bb_p (gimple_bb (stmt)))
STMT_VINFO_DEF_TYPE (res) = vect_unknown_def_type;
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [1/7] Use innermost_loop_behavior for outer loop vectorisation
2017-07-03 7:31 [1/7] Use innermost_loop_behavior for outer loop vectorisation Richard Sandiford
@ 2017-07-03 9:40 ` Richard Biener
0 siblings, 0 replies; 2+ messages in thread
From: Richard Biener @ 2017-07-03 9:40 UTC (permalink / raw)
To: GCC Patches, Richard Sandiford
On Mon, Jul 3, 2017 at 9:28 AM, Richard Sandiford
<richard.sandiford@linaro.org> wrote:
> This patch replaces the individual stmt_vinfo dr_* fields with
> an innermost_loop_behavior, so that the changes in later patches
> get picked up automatically. It also adds a helper function for
> getting the behavior of a data reference wrt the vectorised loop.
>
> Tested on aarch64-linux-gnu and x86_64-linux-gnu. OK to install?
Ok.
Thanks,
Richard.
> Richard
>
>
> 2017-07-03 Richard Sandiford <richard.sandiford@linaro.org>
>
> gcc/
> * tree-vectorizer.h (_stmt_vec_info): Replace individual dr_*
> fields with dr_wrt_vec_loop.
> (STMT_VINFO_DR_BASE_ADDRESS, STMT_VINFO_DR_INIT, STMT_VINFO_DR_OFFSET)
> (STMT_VINFO_DR_STEP, STMT_VINFO_DR_ALIGNED_TO): Update accordingly.
> (STMT_VINFO_DR_WRT_VEC_LOOP): New macro.
> (vect_dr_behavior): New function.
> (vect_create_addr_base_for_vector_ref): Remove loop parameter.
> * tree-vect-data-refs.c (vect_compute_data_ref_alignment): Use
> vect_dr_behavior. Use a step_preserves_misalignment_p boolean to
> track whether the step preserves the misalignment.
> (vect_create_addr_base_for_vector_ref): Remove loop parameter.
> Use vect_dr_behavior.
> (vect_setup_realignment): Update call accordingly.
> (vect_create_data_ref_ptr): Likewise. Use vect_dr_behavior.
> * tree-vect-loop-manip.c (vect_gen_prolog_loop_niters): Update
> call to vect_create_addr_base_for_vector_ref.
> (vect_create_cond_for_align_checks): Likewise.
> * tree-vect-patterns.c (vect_recog_bool_pattern): Copy
> STMT_VINFO_DR_WRT_VEC_LOOP as a block.
> (vect_recog_mask_conversion_pattern): Likewise.
> * tree-vect-stmts.c (compare_step_with_zero): Use vect_dr_behavior.
> (new_stmt_vec_info): Remove redundant zeroing.
>
> Index: gcc/tree-vectorizer.h
> ===================================================================
> --- gcc/tree-vectorizer.h 2017-07-03 07:53:58.155555242 +0100
> +++ gcc/tree-vectorizer.h 2017-07-03 07:57:56.883079731 +0100
> @@ -554,11 +554,7 @@ typedef struct _stmt_vec_info {
>
> /* Information about the data-ref relative to this loop
> nest (the loop that is being considered for vectorization). */
> - tree dr_base_address;
> - tree dr_init;
> - tree dr_offset;
> - tree dr_step;
> - tree dr_aligned_to;
> + innermost_loop_behavior dr_wrt_vec_loop;
>
> /* For loop PHI nodes, the base and evolution part of it. This makes sure
> this information is still available in vect_update_ivs_after_vectorizer
> @@ -706,11 +702,12 @@ #define STMT_VINFO_SIMD_LANE_ACCESS_P(S)
> #define STMT_VINFO_VEC_REDUCTION_TYPE(S) (S)->v_reduc_type
> #define STMT_VINFO_VEC_CONST_COND_REDUC_CODE(S) (S)->const_cond_reduc_code
>
> -#define STMT_VINFO_DR_BASE_ADDRESS(S) (S)->dr_base_address
> -#define STMT_VINFO_DR_INIT(S) (S)->dr_init
> -#define STMT_VINFO_DR_OFFSET(S) (S)->dr_offset
> -#define STMT_VINFO_DR_STEP(S) (S)->dr_step
> -#define STMT_VINFO_DR_ALIGNED_TO(S) (S)->dr_aligned_to
> +#define STMT_VINFO_DR_WRT_VEC_LOOP(S) (S)->dr_wrt_vec_loop
> +#define STMT_VINFO_DR_BASE_ADDRESS(S) (S)->dr_wrt_vec_loop.base_address
> +#define STMT_VINFO_DR_INIT(S) (S)->dr_wrt_vec_loop.init
> +#define STMT_VINFO_DR_OFFSET(S) (S)->dr_wrt_vec_loop.offset
> +#define STMT_VINFO_DR_STEP(S) (S)->dr_wrt_vec_loop.step
> +#define STMT_VINFO_DR_ALIGNED_TO(S) (S)->dr_wrt_vec_loop.aligned_to
>
> #define STMT_VINFO_IN_PATTERN_P(S) (S)->in_pattern_p
> #define STMT_VINFO_RELATED_STMT(S) (S)->related_stmt
> @@ -1012,6 +1009,22 @@ known_alignment_for_access_p (struct dat
> return (DR_MISALIGNMENT (data_ref_info) != DR_MISALIGNMENT_UNKNOWN);
> }
>
> +/* Return the behavior of DR with respect to the vectorization context
> + (which for outer loop vectorization might not be the behavior recorded
> + in DR itself). */
> +
> +static inline innermost_loop_behavior *
> +vect_dr_behavior (data_reference *dr)
> +{
> + gimple *stmt = DR_STMT (dr);
> + stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
> + loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
> + if (loop_vinfo == NULL
> + || !nested_in_vect_loop_p (LOOP_VINFO_LOOP (loop_vinfo), stmt))
> + return &DR_INNERMOST (dr);
> + else
> + return &STMT_VINFO_DR_WRT_VEC_LOOP (stmt_info);
> +}
>
> /* Return true if the vect cost model is unlimited. */
> static inline bool
> @@ -1138,8 +1151,7 @@ extern tree vect_get_new_vect_var (tree,
> extern tree vect_get_new_ssa_name (tree, enum vect_var_kind,
> const char * = NULL);
> extern tree vect_create_addr_base_for_vector_ref (gimple *, gimple_seq *,
> - tree, struct loop *,
> - tree = NULL_TREE);
> + tree, tree = NULL_TREE);
>
> /* In tree-vect-loop.c. */
> /* FORNOW: Used in tree-parloops.c. */
> Index: gcc/tree-vect-data-refs.c
> ===================================================================
> --- gcc/tree-vect-data-refs.c 2017-07-03 07:53:58.155555242 +0100
> +++ gcc/tree-vect-data-refs.c 2017-07-03 07:57:47.758408141 +0100
> @@ -666,11 +666,8 @@ vect_compute_data_ref_alignment (struct
> loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
> struct loop *loop = NULL;
> tree ref = DR_REF (dr);
> - tree vectype;
> - tree base, base_addr;
> - tree misalign = NULL_TREE;
> - tree aligned_to;
> - tree step;
> + tree vectype = STMT_VINFO_VECTYPE (stmt_info);
> + tree base;
> unsigned HOST_WIDE_INT alignment;
>
> if (dump_enabled_p ())
> @@ -683,11 +680,15 @@ vect_compute_data_ref_alignment (struct
> /* Initialize misalignment to unknown. */
> SET_DR_MISALIGNMENT (dr, DR_MISALIGNMENT_UNKNOWN);
>
> - if (tree_fits_shwi_p (DR_STEP (dr)))
> - misalign = DR_INIT (dr);
> - aligned_to = DR_ALIGNED_TO (dr);
> - base_addr = DR_BASE_ADDRESS (dr);
> - vectype = STMT_VINFO_VECTYPE (stmt_info);
> + innermost_loop_behavior *drb = vect_dr_behavior (dr);
> + bool step_preserves_misalignment_p;
> +
> + /* No step for BB vectorization. */
> + if (!loop)
> + {
> + gcc_assert (integer_zerop (drb->step));
> + step_preserves_misalignment_p = true;
> + }
>
> /* In case the dataref is in an inner-loop of the loop that is being
> vectorized (LOOP), we use the base and misalignment information
> @@ -695,26 +696,21 @@ vect_compute_data_ref_alignment (struct
> stays the same throughout the execution of the inner-loop, which is why
> we have to check that the stride of the dataref in the inner-loop evenly
> divides by the vector size. */
> - if (loop && nested_in_vect_loop_p (loop, stmt))
> + else if (nested_in_vect_loop_p (loop, stmt))
> {
> tree step = DR_STEP (dr);
> + step_preserves_misalignment_p
> + = (tree_fits_shwi_p (step)
> + && tree_to_shwi (step) % GET_MODE_SIZE (TYPE_MODE (vectype)) == 0);
>
> - if (tree_fits_shwi_p (step)
> - && tree_to_shwi (step) % GET_MODE_SIZE (TYPE_MODE (vectype)) == 0)
> - {
> - if (dump_enabled_p ())
> - dump_printf_loc (MSG_NOTE, vect_location,
> - "inner step divides the vector-size.\n");
> - misalign = STMT_VINFO_DR_INIT (stmt_info);
> - aligned_to = STMT_VINFO_DR_ALIGNED_TO (stmt_info);
> - base_addr = STMT_VINFO_DR_BASE_ADDRESS (stmt_info);
> - }
> - else
> + if (dump_enabled_p ())
> {
> - if (dump_enabled_p ())
> + if (step_preserves_misalignment_p)
> + dump_printf_loc (MSG_NOTE, vect_location,
> + "inner step divides the vector-size.\n");
> + else
> dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
> - "inner step doesn't divide the vector-size.\n");
> - misalign = NULL_TREE;
> + "inner step doesn't divide the vector-size.\n");
> }
> }
>
> @@ -725,18 +721,17 @@ vect_compute_data_ref_alignment (struct
> else
> {
> tree step = DR_STEP (dr);
> - unsigned vf = loop ? LOOP_VINFO_VECT_FACTOR (loop_vinfo) : 1;
> + unsigned vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
> + step_preserves_misalignment_p
> + = (tree_fits_shwi_p (step)
> + && ((tree_to_shwi (step) * vf)
> + % GET_MODE_SIZE (TYPE_MODE (vectype)) == 0));
>
> - if (tree_fits_shwi_p (step)
> - && ((tree_to_shwi (step) * vf)
> - % GET_MODE_SIZE (TYPE_MODE (vectype)) != 0))
> - {
> - if (dump_enabled_p ())
> - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
> - "step doesn't divide the vector-size.\n");
> - misalign = NULL_TREE;
> - }
> + if (!step_preserves_misalignment_p && dump_enabled_p ())
> + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
> + "step doesn't divide the vector-size.\n");
> }
> + tree base_addr = drb->base_address;
>
> /* To look at alignment of the base we have to preserve an inner MEM_REF
> as that carries alignment information of the actual access. */
> @@ -777,8 +772,8 @@ vect_compute_data_ref_alignment (struct
>
> alignment = TYPE_ALIGN_UNIT (vectype);
>
> - if ((compare_tree_int (aligned_to, alignment) < 0)
> - || !misalign)
> + if ((compare_tree_int (drb->aligned_to, alignment) < 0)
> + || !step_preserves_misalignment_p)
> {
> if (dump_enabled_p ())
> {
> @@ -835,19 +830,16 @@ vect_compute_data_ref_alignment (struct
> DR_VECT_AUX (dr)->base_element_aligned = true;
> }
>
> - if (loop && nested_in_vect_loop_p (loop, stmt))
> - step = STMT_VINFO_DR_STEP (stmt_info);
> - else
> - step = DR_STEP (dr);
> /* If this is a backward running DR then first access in the larger
> vectype actually is N-1 elements before the address in the DR.
> Adjust misalign accordingly. */
> - if (tree_int_cst_sgn (step) < 0)
> + tree misalign = drb->init;
> + if (tree_int_cst_sgn (drb->step) < 0)
> {
> tree offset = ssize_int (TYPE_VECTOR_SUBPARTS (vectype) - 1);
> /* DR_STEP(dr) is the same as -TYPE_SIZE of the scalar type,
> otherwise we wouldn't be here. */
> - offset = fold_build2 (MULT_EXPR, ssizetype, offset, step);
> + offset = fold_build2 (MULT_EXPR, ssizetype, offset, drb->step);
> /* PLUS because STEP was negative. */
> misalign = size_binop (PLUS_EXPR, misalign, offset);
> }
> @@ -3973,38 +3965,22 @@ vect_duplicate_ssa_name_ptr_info (tree n
> vect_create_addr_base_for_vector_ref (gimple *stmt,
> gimple_seq *new_stmt_list,
> tree offset,
> - struct loop *loop,
> tree byte_offset)
> {
> 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);
> + innermost_loop_behavior *drb = vect_dr_behavior (dr);
>
> - if (loop_vinfo && loop && loop != (gimple_bb (stmt))->loop_father)
> - {
> - struct loop *outer_loop = LOOP_VINFO_LOOP (loop_vinfo);
> -
> - gcc_assert (nested_in_vect_loop_p (outer_loop, stmt));
> -
> - data_ref_base = unshare_expr (STMT_VINFO_DR_BASE_ADDRESS (stmt_info));
> - 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));
> - }
> + tree data_ref_base = unshare_expr (drb->base_address);
> + tree base_offset = unshare_expr (drb->offset);
> + tree init = unshare_expr (drb->init);
>
> if (loop_vinfo)
> base_name = get_name (data_ref_base);
> @@ -4169,11 +4145,7 @@ vect_create_data_ref_ptr (gimple *stmt,
>
> /* Check the step (evolution) of the load in LOOP, and record
> whether it's invariant. */
> - if (nested_in_vect_loop)
> - step = STMT_VINFO_DR_STEP (stmt_info);
> - else
> - step = DR_STEP (STMT_VINFO_DATA_REF (stmt_info));
> -
> + step = vect_dr_behavior (dr)->step;
> if (integer_zerop (step))
> *inv_p = true;
> else
> @@ -4271,7 +4243,7 @@ vect_create_data_ref_ptr (gimple *stmt,
> /* Create: (&(base[init_val+offset]+byte_offset) in the loop preheader. */
>
> new_temp = vect_create_addr_base_for_vector_ref (stmt, &new_stmt_list,
> - offset, loop, byte_offset);
> + offset, byte_offset);
> if (new_stmt_list)
> {
> if (pe)
> @@ -4985,7 +4957,7 @@ vect_setup_realignment (gimple *stmt, gi
> {
> /* Generate the INIT_ADDR computation outside LOOP. */
> init_addr = vect_create_addr_base_for_vector_ref (stmt, &stmts,
> - NULL_TREE, loop);
> + NULL_TREE);
> if (loop)
> {
> pe = loop_preheader_edge (loop);
> Index: gcc/tree-vect-loop-manip.c
> ===================================================================
> --- gcc/tree-vect-loop-manip.c 2017-07-03 07:53:58.155555242 +0100
> +++ gcc/tree-vect-loop-manip.c 2017-07-03 07:57:47.758408141 +0100
> @@ -949,7 +949,6 @@ vect_gen_prolog_loop_niters (loop_vec_in
> basic_block bb, int *bound)
> {
> struct data_reference *dr = LOOP_VINFO_UNALIGNED_DR (loop_vinfo);
> - struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
> tree var;
> tree niters_type = TREE_TYPE (LOOP_VINFO_NITERS (loop_vinfo));
> gimple_seq stmts = NULL, new_stmts = NULL;
> @@ -977,7 +976,7 @@ vect_gen_prolog_loop_niters (loop_vec_in
> tree offset = negative
> ? size_int (-TYPE_VECTOR_SUBPARTS (vectype) + 1) : size_zero_node;
> tree start_addr = vect_create_addr_base_for_vector_ref (dr_stmt,
> - &stmts, offset, loop);
> + &stmts, offset);
> tree type = unsigned_type_for (TREE_TYPE (start_addr));
> tree vectype_align_minus_1 = build_int_cst (type, vectype_align - 1);
> HOST_WIDE_INT elem_size =
> @@ -1975,7 +1974,6 @@ vect_create_cond_for_align_checks (loop_
> tree *cond_expr,
> gimple_seq *cond_expr_stmt_list)
> {
> - struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
> vec<gimple *> may_misalign_stmts
> = LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo);
> gimple *ref_stmt;
> @@ -2016,7 +2014,7 @@ vect_create_cond_for_align_checks (loop_
> /* create: addr_tmp = (int)(address_of_first_vector) */
> addr_base =
> vect_create_addr_base_for_vector_ref (ref_stmt, &new_stmt_list,
> - offset, loop);
> + offset);
> if (new_stmt_list != NULL)
> gimple_seq_add_seq (cond_expr_stmt_list, new_stmt_list);
>
> Index: gcc/tree-vect-patterns.c
> ===================================================================
> --- gcc/tree-vect-patterns.c 2017-07-03 07:53:58.155555242 +0100
> +++ gcc/tree-vect-patterns.c 2017-07-03 07:57:47.759408106 +0100
> @@ -3789,14 +3789,8 @@ vect_recog_bool_pattern (vec<gimple *> *
> set_vinfo_for_stmt (pattern_stmt, pattern_stmt_info);
> STMT_VINFO_DATA_REF (pattern_stmt_info)
> = STMT_VINFO_DATA_REF (stmt_vinfo);
> - STMT_VINFO_DR_BASE_ADDRESS (pattern_stmt_info)
> - = STMT_VINFO_DR_BASE_ADDRESS (stmt_vinfo);
> - STMT_VINFO_DR_INIT (pattern_stmt_info) = STMT_VINFO_DR_INIT (stmt_vinfo);
> - STMT_VINFO_DR_OFFSET (pattern_stmt_info)
> - = STMT_VINFO_DR_OFFSET (stmt_vinfo);
> - STMT_VINFO_DR_STEP (pattern_stmt_info) = STMT_VINFO_DR_STEP (stmt_vinfo);
> - STMT_VINFO_DR_ALIGNED_TO (pattern_stmt_info)
> - = STMT_VINFO_DR_ALIGNED_TO (stmt_vinfo);
> + STMT_VINFO_DR_WRT_VEC_LOOP (pattern_stmt_info)
> + = STMT_VINFO_DR_WRT_VEC_LOOP (stmt_vinfo);
> DR_STMT (STMT_VINFO_DATA_REF (stmt_vinfo)) = pattern_stmt;
> *type_out = vectype;
> *type_in = vectype;
> @@ -3930,14 +3924,8 @@ vect_recog_mask_conversion_pattern (vec<
> set_vinfo_for_stmt (pattern_stmt, pattern_stmt_info);
> STMT_VINFO_DATA_REF (pattern_stmt_info)
> = STMT_VINFO_DATA_REF (stmt_vinfo);
> - STMT_VINFO_DR_BASE_ADDRESS (pattern_stmt_info)
> - = STMT_VINFO_DR_BASE_ADDRESS (stmt_vinfo);
> - STMT_VINFO_DR_INIT (pattern_stmt_info) = STMT_VINFO_DR_INIT (stmt_vinfo);
> - STMT_VINFO_DR_OFFSET (pattern_stmt_info)
> - = STMT_VINFO_DR_OFFSET (stmt_vinfo);
> - STMT_VINFO_DR_STEP (pattern_stmt_info) = STMT_VINFO_DR_STEP (stmt_vinfo);
> - STMT_VINFO_DR_ALIGNED_TO (pattern_stmt_info)
> - = STMT_VINFO_DR_ALIGNED_TO (stmt_vinfo);
> + STMT_VINFO_DR_WRT_VEC_LOOP (pattern_stmt_info)
> + = STMT_VINFO_DR_WRT_VEC_LOOP (stmt_vinfo);
> DR_STMT (STMT_VINFO_DATA_REF (stmt_vinfo)) = pattern_stmt;
>
> *type_out = vectype1;
> Index: gcc/tree-vect-stmts.c
> ===================================================================
> --- gcc/tree-vect-stmts.c 2017-07-03 07:53:58.155555242 +0100
> +++ gcc/tree-vect-stmts.c 2017-07-03 07:57:47.759408106 +0100
> @@ -1698,13 +1698,9 @@ static tree permute_vec_elements (tree,
> compare_step_with_zero (gimple *stmt)
> {
> stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
> - loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
> - tree step;
> - if (loop_vinfo && nested_in_vect_loop_p (LOOP_VINFO_LOOP (loop_vinfo), stmt))
> - step = STMT_VINFO_DR_STEP (stmt_info);
> - else
> - step = DR_STEP (STMT_VINFO_DATA_REF (stmt_info));
> - return tree_int_cst_compare (step, size_zero_node);
> + data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
> + return tree_int_cst_compare (vect_dr_behavior (dr)->step,
> + size_zero_node);
> }
>
> /* If the target supports a permute mask that reverses the elements in
> @@ -8851,12 +8847,6 @@ new_stmt_vec_info (gimple *stmt, vec_inf
> STMT_VINFO_VEC_REDUCTION_TYPE (res) = TREE_CODE_REDUCTION;
> STMT_VINFO_VEC_CONST_COND_REDUC_CODE (res) = ERROR_MARK;
>
> - STMT_VINFO_DR_BASE_ADDRESS (res) = NULL;
> - STMT_VINFO_DR_OFFSET (res) = NULL;
> - STMT_VINFO_DR_INIT (res) = NULL;
> - STMT_VINFO_DR_STEP (res) = NULL;
> - STMT_VINFO_DR_ALIGNED_TO (res) = NULL;
> -
> if (gimple_code (stmt) == GIMPLE_PHI
> && is_loop_header_bb_p (gimple_bb (stmt)))
> STMT_VINFO_DEF_TYPE (res) = vect_unknown_def_type;
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2017-07-03 9:40 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-07-03 7:31 [1/7] Use innermost_loop_behavior for outer loop vectorisation Richard Sandiford
2017-07-03 9:40 ` Richard Biener
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).