Commit 5fa23466 by Richard Biener Committed by Richard Biener

tree-data-ref.c (dr_step_indicator): Handle NULL DR_STEP.

2018-06-21  Richard Biener  <rguenther@suse.de>

	* tree-data-ref.c (dr_step_indicator): Handle NULL DR_STEP.
	* tree-vect-data-refs.c (vect_analyze_possibly_independent_ddr):
	Avoid calling vect_mark_for_runtime_alias_test with gathers or scatters.
	(vect_analyze_data_ref_dependence): Re-order checks to deal with
	NULL DR_STEP.
	(vect_record_base_alignments): Do not record base alignment
	for gathers or scatters.
	(vect_compute_data_ref_alignment): Drop return value that is always
	true.  Bail out early for gathers or scatters.
	(vect_enhance_data_refs_alignment): Bail out early for gathers
	or scatters.
	(vect_find_same_alignment_drs): Likewise.
	(vect_analyze_data_refs_alignment): Remove dead code.
	(vect_slp_analyze_and_verify_node_alignment): Likewise.
	(vect_analyze_data_refs): For possible gathers or scatters do
	not create an alternate DR, just check their possible validity
	and mark them.  Adjust DECL_NONALIASED handling to not rely
	on DR_BASE_ADDRESS.
	* tree-vect-loop-manip.c (vect_update_inits_of_drs): Do not
	update inits of gathers or scatters.
	* tree-vect-patterns.c (vect_recog_mask_conversion_pattern):
	Also copy gather/scatter flag to pattern vinfo.

From-SVN: r261834
parent 1ac6620a
2018-06-21 Richard Biener <rguenther@suse.de>
* tree-data-ref.c (dr_step_indicator): Handle NULL DR_STEP.
* tree-vect-data-refs.c (vect_analyze_possibly_independent_ddr):
Avoid calling vect_mark_for_runtime_alias_test with gathers or scatters.
(vect_analyze_data_ref_dependence): Re-order checks to deal with
NULL DR_STEP.
(vect_record_base_alignments): Do not record base alignment
for gathers or scatters.
(vect_compute_data_ref_alignment): Drop return value that is always
true. Bail out early for gathers or scatters.
(vect_enhance_data_refs_alignment): Bail out early for gathers
or scatters.
(vect_find_same_alignment_drs): Likewise.
(vect_analyze_data_refs_alignment): Remove dead code.
(vect_slp_analyze_and_verify_node_alignment): Likewise.
(vect_analyze_data_refs): For possible gathers or scatters do
not create an alternate DR, just check their possible validity
and mark them. Adjust DECL_NONALIASED handling to not rely
on DR_BASE_ADDRESS.
* tree-vect-loop-manip.c (vect_update_inits_of_drs): Do not
update inits of gathers or scatters.
* tree-vect-patterns.c (vect_recog_mask_conversion_pattern):
Also copy gather/scatter flag to pattern vinfo.
2018-06-20 Kelvin Nilsen <kelvin@gcc.gnu.org> 2018-06-20 Kelvin Nilsen <kelvin@gcc.gnu.org>
* config/rs6000/rs6000-c.c (altivec_overloaded_builtins): Change * config/rs6000/rs6000-c.c (altivec_overloaded_builtins): Change
......
...@@ -5454,6 +5454,8 @@ static tree ...@@ -5454,6 +5454,8 @@ static tree
dr_step_indicator (struct data_reference *dr, int useful_min) dr_step_indicator (struct data_reference *dr, int useful_min)
{ {
tree step = DR_STEP (dr); tree step = DR_STEP (dr);
if (!step)
return NULL_TREE;
STRIP_NOPS (step); STRIP_NOPS (step);
/* Look for cases where the step is scaled by a positive constant /* Look for cases where the step is scaled by a positive constant
integer, which will often be the access size. If the multiplication integer, which will often be the access size. If the multiplication
......
...@@ -267,7 +267,11 @@ vect_analyze_possibly_independent_ddr (data_dependence_relation *ddr, ...@@ -267,7 +267,11 @@ vect_analyze_possibly_independent_ddr (data_dependence_relation *ddr,
Note that the alias checks will be removed if the VF ends up Note that the alias checks will be removed if the VF ends up
being small enough. */ being small enough. */
return vect_mark_for_runtime_alias_test (ddr, loop_vinfo); return (!STMT_VINFO_GATHER_SCATTER_P
(vinfo_for_stmt (DR_STMT (DDR_A (ddr))))
&& !STMT_VINFO_GATHER_SCATTER_P
(vinfo_for_stmt (DR_STMT (DDR_B (ddr))))
&& vect_mark_for_runtime_alias_test (ddr, loop_vinfo));
} }
} }
return true; return true;
...@@ -479,15 +483,15 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr, ...@@ -479,15 +483,15 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
if (loop->safelen < 2) if (loop->safelen < 2)
{ {
tree indicator = dr_zero_step_indicator (dra); tree indicator = dr_zero_step_indicator (dra);
if (TREE_CODE (indicator) != INTEGER_CST) if (!indicator || integer_zerop (indicator))
vect_check_nonzero_value (loop_vinfo, indicator);
else if (integer_zerop (indicator))
{ {
if (dump_enabled_p ()) if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
"access also has a zero step\n"); "access also has a zero step\n");
return true; return true;
} }
else if (TREE_CODE (indicator) != INTEGER_CST)
vect_check_nonzero_value (loop_vinfo, indicator);
} }
continue; continue;
} }
...@@ -832,21 +836,20 @@ vect_record_base_alignments (vec_info *vinfo) ...@@ -832,21 +836,20 @@ vect_record_base_alignments (vec_info *vinfo)
FOR_EACH_VEC_ELT (vinfo->datarefs, i, dr) FOR_EACH_VEC_ELT (vinfo->datarefs, i, dr)
{ {
gimple *stmt = vect_dr_stmt (dr); gimple *stmt = vect_dr_stmt (dr);
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
if (!DR_IS_CONDITIONAL_IN_STMT (dr) if (!DR_IS_CONDITIONAL_IN_STMT (dr)
&& STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (stmt))) && STMT_VINFO_VECTORIZABLE (stmt_info)
&& !STMT_VINFO_GATHER_SCATTER_P (stmt_info))
{ {
vect_record_base_alignment (vinfo, stmt, &DR_INNERMOST (dr)); vect_record_base_alignment (vinfo, stmt, &DR_INNERMOST (dr));
/* If DR is nested in the loop that is being vectorized, we can also /* If DR is nested in the loop that is being vectorized, we can also
record the alignment of the base wrt the outer loop. */ record the alignment of the base wrt the outer loop. */
if (loop && nested_in_vect_loop_p (loop, stmt)) if (loop && nested_in_vect_loop_p (loop, stmt))
{
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
vect_record_base_alignment vect_record_base_alignment
(vinfo, stmt, &STMT_VINFO_DR_WRT_VEC_LOOP (stmt_info)); (vinfo, stmt, &STMT_VINFO_DR_WRT_VEC_LOOP (stmt_info));
} }
} }
}
} }
/* Return the target alignment for the vectorized form of DR. */ /* Return the target alignment for the vectorized form of DR. */
...@@ -865,14 +868,12 @@ vect_calculate_target_alignment (struct data_reference *dr) ...@@ -865,14 +868,12 @@ vect_calculate_target_alignment (struct data_reference *dr)
Compute the misalignment of the data reference DR. Compute the misalignment of the data reference DR.
Output: Output:
1. If during the misalignment computation it is found that the data reference 1. DR_MISALIGNMENT (DR) is defined.
cannot be vectorized then false is returned.
2. DR_MISALIGNMENT (DR) is defined.
FOR NOW: No analysis is actually performed. Misalignment is calculated FOR NOW: No analysis is actually performed. Misalignment is calculated
only for trivial cases. TODO. */ only for trivial cases. TODO. */
static bool static void
vect_compute_data_ref_alignment (struct data_reference *dr) vect_compute_data_ref_alignment (struct data_reference *dr)
{ {
gimple *stmt = vect_dr_stmt (dr); gimple *stmt = vect_dr_stmt (dr);
...@@ -893,6 +894,9 @@ vect_compute_data_ref_alignment (struct data_reference *dr) ...@@ -893,6 +894,9 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
/* Initialize misalignment to unknown. */ /* Initialize misalignment to unknown. */
SET_DR_MISALIGNMENT (dr, DR_MISALIGNMENT_UNKNOWN); SET_DR_MISALIGNMENT (dr, DR_MISALIGNMENT_UNKNOWN);
if (STMT_VINFO_GATHER_SCATTER_P (stmt_info))
return;
innermost_loop_behavior *drb = vect_dr_behavior (dr); innermost_loop_behavior *drb = vect_dr_behavior (dr);
bool step_preserves_misalignment_p; bool step_preserves_misalignment_p;
...@@ -970,7 +974,7 @@ vect_compute_data_ref_alignment (struct data_reference *dr) ...@@ -970,7 +974,7 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, ref); dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, ref);
dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
} }
return true; return;
} }
if (base_alignment < vector_alignment) if (base_alignment < vector_alignment)
...@@ -988,7 +992,7 @@ vect_compute_data_ref_alignment (struct data_reference *dr) ...@@ -988,7 +992,7 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
dump_generic_expr (MSG_NOTE, TDF_SLIM, ref); dump_generic_expr (MSG_NOTE, TDF_SLIM, ref);
dump_printf (MSG_NOTE, "\n"); dump_printf (MSG_NOTE, "\n");
} }
return true; return;
} }
/* Force the alignment of the decl. /* Force the alignment of the decl.
...@@ -1027,7 +1031,7 @@ vect_compute_data_ref_alignment (struct data_reference *dr) ...@@ -1027,7 +1031,7 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, ref); dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, ref);
dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
} }
return true; return;
} }
SET_DR_MISALIGNMENT (dr, const_misalignment); SET_DR_MISALIGNMENT (dr, const_misalignment);
...@@ -1040,7 +1044,7 @@ vect_compute_data_ref_alignment (struct data_reference *dr) ...@@ -1040,7 +1044,7 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
} }
return true; return;
} }
/* Function vect_update_misalignment_for_peel. /* Function vect_update_misalignment_for_peel.
...@@ -1733,8 +1737,10 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo) ...@@ -1733,8 +1737,10 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
&& DR_GROUP_FIRST_ELEMENT (stmt_info) != stmt) && DR_GROUP_FIRST_ELEMENT (stmt_info) != stmt)
continue; continue;
/* For invariant accesses there is nothing to enhance. */ /* For scatter-gather or invariant accesses there is nothing
if (integer_zerop (DR_STEP (dr))) to enhance. */
if (STMT_VINFO_GATHER_SCATTER_P (stmt_info)
|| integer_zerop (DR_STEP (dr)))
continue; continue;
/* Strided accesses perform only component accesses, alignment is /* Strided accesses perform only component accesses, alignment is
...@@ -2295,6 +2301,10 @@ vect_find_same_alignment_drs (struct data_dependence_relation *ddr) ...@@ -2295,6 +2301,10 @@ vect_find_same_alignment_drs (struct data_dependence_relation *ddr)
if (dra == drb) if (dra == drb)
return; return;
if (STMT_VINFO_GATHER_SCATTER_P (stmtinfo_a)
|| STMT_VINFO_GATHER_SCATTER_P (stmtinfo_b))
return;
if (!operand_equal_p (DR_BASE_ADDRESS (dra), DR_BASE_ADDRESS (drb), 0) if (!operand_equal_p (DR_BASE_ADDRESS (dra), DR_BASE_ADDRESS (drb), 0)
|| !operand_equal_p (DR_OFFSET (dra), DR_OFFSET (drb), 0) || !operand_equal_p (DR_OFFSET (dra), DR_OFFSET (drb), 0)
|| !operand_equal_p (DR_STEP (dra), DR_STEP (drb), 0)) || !operand_equal_p (DR_STEP (dra), DR_STEP (drb), 0))
...@@ -2357,22 +2367,8 @@ vect_analyze_data_refs_alignment (loop_vec_info vinfo) ...@@ -2357,22 +2367,8 @@ vect_analyze_data_refs_alignment (loop_vec_info vinfo)
FOR_EACH_VEC_ELT (datarefs, i, dr) FOR_EACH_VEC_ELT (datarefs, i, dr)
{ {
stmt_vec_info stmt_info = vinfo_for_stmt (vect_dr_stmt (dr)); stmt_vec_info stmt_info = vinfo_for_stmt (vect_dr_stmt (dr));
if (STMT_VINFO_VECTORIZABLE (stmt_info) if (STMT_VINFO_VECTORIZABLE (stmt_info))
&& !vect_compute_data_ref_alignment (dr)) vect_compute_data_ref_alignment (dr);
{
/* Strided accesses perform only component accesses, misalignment
information is irrelevant for them. */
if (STMT_VINFO_STRIDED_P (stmt_info)
&& !STMT_VINFO_GROUPED_ACCESS (stmt_info))
continue;
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
"not vectorized: can't calculate alignment "
"for data ref.\n");
return false;
}
} }
return true; return true;
...@@ -2393,12 +2389,12 @@ vect_slp_analyze_and_verify_node_alignment (slp_tree node) ...@@ -2393,12 +2389,12 @@ vect_slp_analyze_and_verify_node_alignment (slp_tree node)
first_stmt = DR_GROUP_FIRST_ELEMENT (vinfo_for_stmt (first_stmt)); first_stmt = DR_GROUP_FIRST_ELEMENT (vinfo_for_stmt (first_stmt));
data_reference_p dr = STMT_VINFO_DATA_REF (vinfo_for_stmt (first_stmt)); data_reference_p dr = STMT_VINFO_DATA_REF (vinfo_for_stmt (first_stmt));
if (! vect_compute_data_ref_alignment (dr) vect_compute_data_ref_alignment (dr);
/* For creating the data-ref pointer we need alignment of the /* For creating the data-ref pointer we need alignment of the
first element anyway. */ first element anyway. */
|| (dr != first_dr if (dr != first_dr)
&& ! vect_compute_data_ref_alignment (first_dr)) vect_compute_data_ref_alignment (first_dr);
|| ! verify_data_ref_alignment (dr)) if (! verify_data_ref_alignment (dr))
{ {
if (dump_enabled_p ()) if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
...@@ -4102,9 +4098,10 @@ vect_analyze_data_refs (vec_info *vinfo, poly_uint64 *min_vf) ...@@ -4102,9 +4098,10 @@ vect_analyze_data_refs (vec_info *vinfo, poly_uint64 *min_vf)
/* If target supports vector gather loads or scatter stores, or if /* If target supports vector gather loads or scatter stores, or if
this might be a SIMD lane access, see if they can't be used. */ this might be a SIMD lane access, see if they can't be used. */
if (is_a <loop_vec_info> (vinfo) if (is_a <loop_vec_info> (vinfo)
&& (maybe_gather || maybe_scatter || maybe_simd_lane_access)
&& !nested_in_vect_loop_p (loop, stmt)) && !nested_in_vect_loop_p (loop, stmt))
{ {
if (maybe_simd_lane_access)
{
struct data_reference *newdr struct data_reference *newdr
= create_data_ref (NULL, loop_containing_stmt (stmt), = create_data_ref (NULL, loop_containing_stmt (stmt),
DR_REF (dr), stmt, !maybe_scatter, DR_REF (dr), stmt, !maybe_scatter,
...@@ -4116,8 +4113,6 @@ vect_analyze_data_refs (vec_info *vinfo, poly_uint64 *min_vf) ...@@ -4116,8 +4113,6 @@ vect_analyze_data_refs (vec_info *vinfo, poly_uint64 *min_vf)
&& DR_STEP (newdr) && DR_STEP (newdr)
&& integer_zerop (DR_STEP (newdr))) && integer_zerop (DR_STEP (newdr)))
{ {
if (maybe_simd_lane_access)
{
tree off = DR_OFFSET (newdr); tree off = DR_OFFSET (newdr);
STRIP_NOPS (off); STRIP_NOPS (off);
if (TREE_CODE (DR_INIT (newdr)) == INTEGER_CST if (TREE_CODE (DR_INIT (newdr)) == INTEGER_CST
...@@ -4163,18 +4158,17 @@ vect_analyze_data_refs (vec_info *vinfo, poly_uint64 *min_vf) ...@@ -4163,18 +4158,17 @@ vect_analyze_data_refs (vec_info *vinfo, poly_uint64 *min_vf)
} }
} }
} }
if (!simd_lane_access)
free_data_ref (newdr);
}
if (!simd_lane_access && (maybe_gather || maybe_scatter)) if (!simd_lane_access && (maybe_gather || maybe_scatter))
{ {
dr = newdr;
if (maybe_gather) if (maybe_gather)
gatherscatter = GATHER; gatherscatter = GATHER;
else else
gatherscatter = SCATTER; gatherscatter = SCATTER;
} }
} }
if (gatherscatter == SG_NONE && !simd_lane_access)
free_data_ref (newdr);
}
if (gatherscatter == SG_NONE && !simd_lane_access) if (gatherscatter == SG_NONE && !simd_lane_access)
{ {
...@@ -4196,9 +4190,8 @@ vect_analyze_data_refs (vec_info *vinfo, poly_uint64 *min_vf) ...@@ -4196,9 +4190,8 @@ vect_analyze_data_refs (vec_info *vinfo, poly_uint64 *min_vf)
} }
} }
if (TREE_CODE (DR_BASE_ADDRESS (dr)) == ADDR_EXPR tree base = get_base_address (DR_REF (dr));
&& VAR_P (TREE_OPERAND (DR_BASE_ADDRESS (dr), 0)) if (base && VAR_P (base) && DECL_NONALIASED (base))
&& DECL_NONALIASED (TREE_OPERAND (DR_BASE_ADDRESS (dr), 0)))
{ {
if (dump_enabled_p ()) if (dump_enabled_p ())
{ {
...@@ -4218,6 +4211,7 @@ vect_analyze_data_refs (vec_info *vinfo, poly_uint64 *min_vf) ...@@ -4218,6 +4211,7 @@ vect_analyze_data_refs (vec_info *vinfo, poly_uint64 *min_vf)
} }
if (is_a <loop_vec_info> (vinfo) if (is_a <loop_vec_info> (vinfo)
&& DR_STEP (dr)
&& TREE_CODE (DR_STEP (dr)) != INTEGER_CST) && TREE_CODE (DR_STEP (dr)) != INTEGER_CST)
{ {
if (nested_in_vect_loop_p (loop, stmt)) if (nested_in_vect_loop_p (loop, stmt))
...@@ -4330,10 +4324,9 @@ vect_analyze_data_refs (vec_info *vinfo, poly_uint64 *min_vf) ...@@ -4330,10 +4324,9 @@ vect_analyze_data_refs (vec_info *vinfo, poly_uint64 *min_vf)
continue; continue;
} }
if (gatherscatter != SG_NONE || simd_lane_access) if (simd_lane_access)
{ {
STMT_VINFO_DATA_REF (stmt_info) = NULL; STMT_VINFO_DATA_REF (stmt_info) = NULL;
if (gatherscatter != SG_NONE)
free_data_ref (dr); free_data_ref (dr);
} }
return false; return false;
...@@ -4363,8 +4356,6 @@ vect_analyze_data_refs (vec_info *vinfo, poly_uint64 *min_vf) ...@@ -4363,8 +4356,6 @@ vect_analyze_data_refs (vec_info *vinfo, poly_uint64 *min_vf)
&gs_info) &gs_info)
|| !get_vectype_for_scalar_type (TREE_TYPE (gs_info.offset))) || !get_vectype_for_scalar_type (TREE_TYPE (gs_info.offset)))
{ {
STMT_VINFO_DATA_REF (stmt_info) = NULL;
free_data_ref (dr);
if (dump_enabled_p ()) if (dump_enabled_p ())
{ {
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
...@@ -4377,9 +4368,6 @@ vect_analyze_data_refs (vec_info *vinfo, poly_uint64 *min_vf) ...@@ -4377,9 +4368,6 @@ vect_analyze_data_refs (vec_info *vinfo, poly_uint64 *min_vf)
} }
return false; return false;
} }
free_data_ref (datarefs[i]);
datarefs[i] = dr;
STMT_VINFO_GATHER_SCATTER_P (stmt_info) = gatherscatter; STMT_VINFO_GATHER_SCATTER_P (stmt_info) = gatherscatter;
} }
} }
......
...@@ -1752,7 +1752,11 @@ vect_update_inits_of_drs (loop_vec_info loop_vinfo, tree niters, ...@@ -1752,7 +1752,11 @@ vect_update_inits_of_drs (loop_vec_info loop_vinfo, tree niters,
} }
FOR_EACH_VEC_ELT (datarefs, i, dr) FOR_EACH_VEC_ELT (datarefs, i, dr)
{
gimple *stmt = DR_STMT (dr);
if (!STMT_VINFO_GATHER_SCATTER_P (vinfo_for_stmt (stmt)))
vect_update_init_of_dr (dr, niters, code); vect_update_init_of_dr (dr, niters, code);
}
} }
/* For the information recorded in LOOP_VINFO prepare the loop for peeling /* For the information recorded in LOOP_VINFO prepare the loop for peeling
......
...@@ -3848,6 +3848,8 @@ vect_recog_mask_conversion_pattern (vec<gimple *> *stmts, tree *type_out) ...@@ -3848,6 +3848,8 @@ vect_recog_mask_conversion_pattern (vec<gimple *> *stmts, tree *type_out)
= STMT_VINFO_DATA_REF (stmt_vinfo); = STMT_VINFO_DATA_REF (stmt_vinfo);
STMT_VINFO_DR_WRT_VEC_LOOP (pattern_stmt_info) STMT_VINFO_DR_WRT_VEC_LOOP (pattern_stmt_info)
= STMT_VINFO_DR_WRT_VEC_LOOP (stmt_vinfo); = STMT_VINFO_DR_WRT_VEC_LOOP (stmt_vinfo);
STMT_VINFO_GATHER_SCATTER_P (pattern_stmt_info)
= STMT_VINFO_GATHER_SCATTER_P (stmt_vinfo);
*type_out = vectype1; *type_out = vectype1;
stmts->safe_push (last_stmt); stmts->safe_push (last_stmt);
......
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