tree-vect-data-refs.c (vect_find_stmt_data_reference): Modify DR for SIMD lane accesses here and mark DR with (void *)-1 aux.
2018-06-25 Richard Biener <rguenther@suse.de> * tree-vect-data-refs.c (vect_find_stmt_data_reference): Modify DR for SIMD lane accesses here and mark DR with (void *)-1 aux. (vect_analyze_data_refs): Remove similar code from here and simplify accordingly. From-SVN: r262008
This commit is contained in:
parent
8c9632905d
commit
f2227a6696
@ -1,3 +1,10 @@
|
||||
2018-06-25 Richard Biener <rguenther@suse.de>
|
||||
|
||||
* tree-vect-data-refs.c (vect_find_stmt_data_reference): Modify
|
||||
DR for SIMD lane accesses here and mark DR with (void *)-1 aux.
|
||||
(vect_analyze_data_refs): Remove similar code from here and
|
||||
simplify accordingly.
|
||||
|
||||
2018-06-25 Richard Biener <rguenther@suse.de>
|
||||
|
||||
* tree-vect-data-refs.c (vect_check_gather_scatter): Fail
|
||||
|
@ -4032,6 +4032,70 @@ vect_find_stmt_data_reference (loop_p loop, gimple *stmt,
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check whether this may be a SIMD lane access and adjust the
|
||||
DR to make it easier for us to handle it. */
|
||||
if (loop
|
||||
&& loop->simduid
|
||||
&& (!DR_BASE_ADDRESS (dr)
|
||||
|| !DR_OFFSET (dr)
|
||||
|| !DR_INIT (dr)
|
||||
|| !DR_STEP (dr)))
|
||||
{
|
||||
struct data_reference *newdr
|
||||
= create_data_ref (NULL, loop_containing_stmt (stmt), DR_REF (dr), stmt,
|
||||
DR_IS_READ (dr), DR_IS_CONDITIONAL_IN_STMT (dr));
|
||||
if (DR_BASE_ADDRESS (newdr)
|
||||
&& DR_OFFSET (newdr)
|
||||
&& DR_INIT (newdr)
|
||||
&& DR_STEP (newdr)
|
||||
&& integer_zerop (DR_STEP (newdr)))
|
||||
{
|
||||
tree off = DR_OFFSET (newdr);
|
||||
STRIP_NOPS (off);
|
||||
if (TREE_CODE (DR_INIT (newdr)) == INTEGER_CST
|
||||
&& TREE_CODE (off) == MULT_EXPR
|
||||
&& tree_fits_uhwi_p (TREE_OPERAND (off, 1)))
|
||||
{
|
||||
tree step = TREE_OPERAND (off, 1);
|
||||
off = TREE_OPERAND (off, 0);
|
||||
STRIP_NOPS (off);
|
||||
if (CONVERT_EXPR_P (off)
|
||||
&& (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (off, 0)))
|
||||
< TYPE_PRECISION (TREE_TYPE (off))))
|
||||
off = TREE_OPERAND (off, 0);
|
||||
if (TREE_CODE (off) == SSA_NAME)
|
||||
{
|
||||
gimple *def = SSA_NAME_DEF_STMT (off);
|
||||
tree reft = TREE_TYPE (DR_REF (newdr));
|
||||
if (is_gimple_call (def)
|
||||
&& gimple_call_internal_p (def)
|
||||
&& (gimple_call_internal_fn (def) == IFN_GOMP_SIMD_LANE))
|
||||
{
|
||||
tree arg = gimple_call_arg (def, 0);
|
||||
gcc_assert (TREE_CODE (arg) == SSA_NAME);
|
||||
arg = SSA_NAME_VAR (arg);
|
||||
if (arg == loop->simduid
|
||||
/* For now. */
|
||||
&& tree_int_cst_equal (TYPE_SIZE_UNIT (reft), step))
|
||||
{
|
||||
DR_OFFSET (newdr) = ssize_int (0);
|
||||
DR_STEP (newdr) = step;
|
||||
DR_OFFSET_ALIGNMENT (newdr) = BIGGEST_ALIGNMENT;
|
||||
DR_STEP_ALIGNMENT (newdr)
|
||||
= highest_pow2_factor (step);
|
||||
/* Mark as simd-lane access. */
|
||||
newdr->aux = (void *)-1;
|
||||
free_data_ref (dr);
|
||||
datarefs->safe_push (newdr);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free_data_ref (newdr);
|
||||
}
|
||||
|
||||
datarefs->safe_push (dr);
|
||||
return true;
|
||||
}
|
||||
@ -4073,7 +4137,6 @@ vect_analyze_data_refs (vec_info *vinfo, poly_uint64 *min_vf)
|
||||
gimple *stmt;
|
||||
stmt_vec_info stmt_info;
|
||||
enum { SG_NONE, GATHER, SCATTER } gatherscatter = SG_NONE;
|
||||
bool simd_lane_access = false;
|
||||
poly_uint64 vf;
|
||||
|
||||
gcc_assert (DR_REF (dr));
|
||||
@ -4094,76 +4157,13 @@ vect_analyze_data_refs (vec_info *vinfo, poly_uint64 *min_vf)
|
||||
&& !TREE_THIS_VOLATILE (DR_REF (dr))
|
||||
&& (targetm.vectorize.builtin_scatter != NULL
|
||||
|| supports_vec_scatter_store_p ());
|
||||
bool maybe_simd_lane_access
|
||||
= is_a <loop_vec_info> (vinfo) && loop->simduid;
|
||||
|
||||
/* 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. */
|
||||
/* If target supports vector gather loads or scatter stores,
|
||||
see if they can't be used. */
|
||||
if (is_a <loop_vec_info> (vinfo)
|
||||
&& !nested_in_vect_loop_p (loop, stmt))
|
||||
{
|
||||
if (maybe_simd_lane_access)
|
||||
{
|
||||
struct data_reference *newdr
|
||||
= create_data_ref (NULL, loop_containing_stmt (stmt),
|
||||
DR_REF (dr), stmt, !maybe_scatter,
|
||||
DR_IS_CONDITIONAL_IN_STMT (dr));
|
||||
gcc_assert (newdr != NULL && DR_REF (newdr));
|
||||
if (DR_BASE_ADDRESS (newdr)
|
||||
&& DR_OFFSET (newdr)
|
||||
&& DR_INIT (newdr)
|
||||
&& DR_STEP (newdr)
|
||||
&& integer_zerop (DR_STEP (newdr)))
|
||||
{
|
||||
tree off = DR_OFFSET (newdr);
|
||||
STRIP_NOPS (off);
|
||||
if (TREE_CODE (DR_INIT (newdr)) == INTEGER_CST
|
||||
&& TREE_CODE (off) == MULT_EXPR
|
||||
&& tree_fits_uhwi_p (TREE_OPERAND (off, 1)))
|
||||
{
|
||||
tree step = TREE_OPERAND (off, 1);
|
||||
off = TREE_OPERAND (off, 0);
|
||||
STRIP_NOPS (off);
|
||||
if (CONVERT_EXPR_P (off)
|
||||
&& TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (off,
|
||||
0)))
|
||||
< TYPE_PRECISION (TREE_TYPE (off)))
|
||||
off = TREE_OPERAND (off, 0);
|
||||
if (TREE_CODE (off) == SSA_NAME)
|
||||
{
|
||||
gimple *def = SSA_NAME_DEF_STMT (off);
|
||||
tree reft = TREE_TYPE (DR_REF (newdr));
|
||||
if (is_gimple_call (def)
|
||||
&& gimple_call_internal_p (def)
|
||||
&& (gimple_call_internal_fn (def)
|
||||
== IFN_GOMP_SIMD_LANE))
|
||||
{
|
||||
tree arg = gimple_call_arg (def, 0);
|
||||
gcc_assert (TREE_CODE (arg) == SSA_NAME);
|
||||
arg = SSA_NAME_VAR (arg);
|
||||
if (arg == loop->simduid
|
||||
/* For now. */
|
||||
&& tree_int_cst_equal
|
||||
(TYPE_SIZE_UNIT (reft),
|
||||
step))
|
||||
{
|
||||
DR_OFFSET (newdr) = ssize_int (0);
|
||||
DR_STEP (newdr) = step;
|
||||
DR_OFFSET_ALIGNMENT (newdr)
|
||||
= BIGGEST_ALIGNMENT;
|
||||
DR_STEP_ALIGNMENT (newdr)
|
||||
= highest_pow2_factor (step);
|
||||
dr = newdr;
|
||||
simd_lane_access = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!simd_lane_access)
|
||||
free_data_ref (newdr);
|
||||
}
|
||||
if (!simd_lane_access && (maybe_gather || maybe_scatter))
|
||||
if (maybe_gather || maybe_scatter)
|
||||
{
|
||||
if (maybe_gather)
|
||||
gatherscatter = GATHER;
|
||||
@ -4172,7 +4172,7 @@ vect_analyze_data_refs (vec_info *vinfo, poly_uint64 *min_vf)
|
||||
}
|
||||
}
|
||||
|
||||
if (gatherscatter == SG_NONE && !simd_lane_access)
|
||||
if (gatherscatter == SG_NONE)
|
||||
{
|
||||
if (dump_enabled_p ())
|
||||
{
|
||||
@ -4192,6 +4192,23 @@ vect_analyze_data_refs (vec_info *vinfo, poly_uint64 *min_vf)
|
||||
}
|
||||
}
|
||||
|
||||
/* See if this was detected as SIMD lane access. */
|
||||
if (dr->aux == (void *)-1)
|
||||
{
|
||||
if (nested_in_vect_loop_p (loop, stmt))
|
||||
{
|
||||
if (dump_enabled_p ())
|
||||
{
|
||||
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
|
||||
"not vectorized: data ref analysis "
|
||||
"failed ");
|
||||
dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
STMT_VINFO_SIMD_LANE_ACCESS_P (stmt_info) = true;
|
||||
}
|
||||
|
||||
tree base = get_base_address (DR_REF (dr));
|
||||
if (base && VAR_P (base) && DECL_NONALIASED (base))
|
||||
{
|
||||
@ -4294,12 +4311,6 @@ vect_analyze_data_refs (vec_info *vinfo, poly_uint64 *min_vf)
|
||||
|
||||
gcc_assert (!STMT_VINFO_DATA_REF (stmt_info));
|
||||
STMT_VINFO_DATA_REF (stmt_info) = dr;
|
||||
if (simd_lane_access)
|
||||
{
|
||||
STMT_VINFO_SIMD_LANE_ACCESS_P (stmt_info) = true;
|
||||
free_data_ref (datarefs[i]);
|
||||
datarefs[i] = dr;
|
||||
}
|
||||
|
||||
/* Set vectype for STMT. */
|
||||
scalar_type = TREE_TYPE (DR_REF (dr));
|
||||
@ -4325,12 +4336,6 @@ vect_analyze_data_refs (vec_info *vinfo, poly_uint64 *min_vf)
|
||||
STMT_VINFO_VECTORIZABLE (stmt_info) = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (simd_lane_access)
|
||||
{
|
||||
STMT_VINFO_DATA_REF (stmt_info) = NULL;
|
||||
free_data_ref (dr);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
|
Loading…
Reference in New Issue
Block a user