[11/46] Pass back a stmt_vec_info from vect_is_simple_use

This patch makes vect_is_simple_use pass back a stmt_vec_info to
those callers that want it.  Most users only need the stmt_vec_info
but some need the gimple stmt too.

It's probably high time we added a class to represent "simple operands"
instead, but I have a separate series that tries to clean up how
operands are handled (with a view to allowing mixed vector sizes).

2018-07-31  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
	* tree-vectorizer.h (vect_is_simple_use): Add an optional
	stmt_vec_info * parameter before the optional gimple **.
	* tree-vect-stmts.c (vect_is_simple_use): Likewise.
	(process_use, vect_get_vec_def_for_operand_1): Update callers.
	(vect_get_vec_def_for_operand, vectorizable_shift): Likewise.
	* tree-vect-loop.c (vectorizable_reduction): Likewise.
	(vectorizable_live_operation): Likewise.
	* tree-vect-patterns.c (type_conversion_p): Likewise.
	(vect_look_through_possible_promotion): Likewise.
	(vect_recog_rotate_pattern): Likewise.
	* tree-vect-slp.c (vect_get_and_check_slp_defs): Likewise.

From-SVN: r263126
This commit is contained in:
Richard Sandiford 2018-07-31 14:22:01 +00:00 committed by Richard Sandiford
parent dbe1b84664
commit fef96d8e2a
6 changed files with 90 additions and 75 deletions

View File

@ -1,3 +1,17 @@
2018-07-31 Richard Sandiford <richard.sandiford@arm.com>
* tree-vectorizer.h (vect_is_simple_use): Add an optional
stmt_vec_info * parameter before the optional gimple **.
* tree-vect-stmts.c (vect_is_simple_use): Likewise.
(process_use, vect_get_vec_def_for_operand_1): Update callers.
(vect_get_vec_def_for_operand, vectorizable_shift): Likewise.
* tree-vect-loop.c (vectorizable_reduction): Likewise.
(vectorizable_live_operation): Likewise.
* tree-vect-patterns.c (type_conversion_p): Likewise.
(vect_look_through_possible_promotion): Likewise.
(vect_recog_rotate_pattern): Likewise.
* tree-vect-slp.c (vect_get_and_check_slp_defs): Likewise.
2018-07-31 Richard Sandiford <richard.sandiford@arm.com>
* tree-vectorizer.h (stmt_vec_info): Temporarily change from

View File

@ -6090,7 +6090,6 @@ vectorizable_reduction (gimple *stmt, gimple_stmt_iterator *gsi,
int op_type;
optab optab;
tree new_temp = NULL_TREE;
gimple *def_stmt;
enum vect_def_type dt, cond_reduc_dt = vect_unknown_def_type;
gimple *cond_reduc_def_stmt = NULL;
enum tree_code cond_reduc_op_code = ERROR_MARK;
@ -6324,13 +6323,14 @@ vectorizable_reduction (gimple *stmt, gimple_stmt_iterator *gsi,
if (i == 0 && code == COND_EXPR)
continue;
is_simple_use = vect_is_simple_use (ops[i], loop_vinfo,
&dts[i], &tem, &def_stmt);
stmt_vec_info def_stmt_info;
is_simple_use = vect_is_simple_use (ops[i], loop_vinfo, &dts[i], &tem,
&def_stmt_info);
dt = dts[i];
gcc_assert (is_simple_use);
if (dt == vect_reduction_def)
{
reduc_def_stmt = def_stmt;
reduc_def_stmt = def_stmt_info;
reduc_index = i;
continue;
}
@ -6354,7 +6354,7 @@ vectorizable_reduction (gimple *stmt, gimple_stmt_iterator *gsi,
if (dt == vect_nested_cycle)
{
found_nested_cycle_def = true;
reduc_def_stmt = def_stmt;
reduc_def_stmt = def_stmt_info;
reduc_index = i;
}
@ -6367,11 +6367,11 @@ vectorizable_reduction (gimple *stmt, gimple_stmt_iterator *gsi,
cond_reduc_val = ops[i];
}
if (dt == vect_induction_def
&& def_stmt != NULL
&& is_nonwrapping_integer_induction (def_stmt, loop))
&& def_stmt_info
&& is_nonwrapping_integer_induction (def_stmt_info, loop))
{
cond_reduc_dt = dt;
cond_reduc_def_stmt = def_stmt;
cond_reduc_def_stmt = def_stmt_info;
}
}
}
@ -7958,7 +7958,7 @@ vectorizable_live_operation (gimple *stmt,
else
{
enum vect_def_type dt = STMT_VINFO_DEF_TYPE (stmt_info);
vec_lhs = vect_get_vec_def_for_operand_1 (stmt, dt);
vec_lhs = vect_get_vec_def_for_operand_1 (stmt_info, dt);
gcc_checking_assert (ncopies == 1
|| !LOOP_VINFO_FULLY_MASKED_P (loop_vinfo));

View File

@ -250,7 +250,9 @@ type_conversion_p (tree name, gimple *use_stmt, bool check_sign,
enum vect_def_type dt;
stmt_vinfo = vinfo_for_stmt (use_stmt);
if (!vect_is_simple_use (name, stmt_vinfo->vinfo, &dt, def_stmt))
stmt_vec_info def_stmt_info;
if (!vect_is_simple_use (name, stmt_vinfo->vinfo, &dt, &def_stmt_info,
def_stmt))
return false;
if (dt != vect_internal_def
@ -371,9 +373,10 @@ vect_look_through_possible_promotion (vec_info *vinfo, tree op,
while (TREE_CODE (op) == SSA_NAME && INTEGRAL_TYPE_P (op_type))
{
/* See whether OP is simple enough to vectorize. */
stmt_vec_info def_stmt_info;
gimple *def_stmt;
vect_def_type dt;
if (!vect_is_simple_use (op, vinfo, &dt, &def_stmt))
if (!vect_is_simple_use (op, vinfo, &dt, &def_stmt_info, &def_stmt))
break;
/* If OP is the input of a demotion, skip over it to see whether
@ -407,17 +410,15 @@ vect_look_through_possible_promotion (vec_info *vinfo, tree op,
the cast is potentially vectorizable. */
if (!def_stmt)
break;
if (dt == vect_internal_def)
{
caster = vinfo_for_stmt (def_stmt);
caster = def_stmt_info;
/* Ignore pattern statements, since we don't link uses for them. */
if (single_use_p
if (caster
&& single_use_p
&& !STMT_VINFO_RELATED_STMT (caster)
&& !has_single_use (res))
*single_use_p = false;
}
else
caster = NULL;
gassign *assign = dyn_cast <gassign *> (def_stmt);
if (!assign || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))
break;
@ -1988,7 +1989,8 @@ vect_recog_rotate_pattern (stmt_vec_info stmt_vinfo, tree *type_out)
|| !TYPE_UNSIGNED (type))
return NULL;
if (!vect_is_simple_use (oprnd1, vinfo, &dt, &def_stmt))
stmt_vec_info def_stmt_info;
if (!vect_is_simple_use (oprnd1, vinfo, &dt, &def_stmt_info, &def_stmt))
return NULL;
if (dt != vect_internal_def

View File

@ -303,7 +303,6 @@ vect_get_and_check_slp_defs (vec_info *vinfo, unsigned char *swap,
gimple *stmt = stmts[stmt_num];
tree oprnd;
unsigned int i, number_of_oprnds;
gimple *def_stmt;
enum vect_def_type dt = vect_uninitialized_def;
bool pattern = false;
slp_oprnd_info oprnd_info;
@ -357,7 +356,8 @@ again:
oprnd_info = (*oprnds_info)[i];
if (!vect_is_simple_use (oprnd, vinfo, &dt, &def_stmt))
stmt_vec_info def_stmt_info;
if (!vect_is_simple_use (oprnd, vinfo, &dt, &def_stmt_info))
{
if (dump_enabled_p ())
{
@ -370,13 +370,10 @@ again:
return -1;
}
/* Check if DEF_STMT is a part of a pattern in LOOP and get the def stmt
from the pattern. Check that all the stmts of the node are in the
pattern. */
if (def_stmt && gimple_bb (def_stmt)
&& vect_stmt_in_region_p (vinfo, def_stmt)
&& vinfo_for_stmt (def_stmt)
&& is_pattern_stmt_p (vinfo_for_stmt (def_stmt)))
/* Check if DEF_STMT_INFO is a part of a pattern in LOOP and get
the def stmt from the pattern. Check that all the stmts of the
node are in the pattern. */
if (def_stmt_info && is_pattern_stmt_p (def_stmt_info))
{
pattern = true;
if (!first && !oprnd_info->first_pattern
@ -405,7 +402,7 @@ again:
return 1;
}
dt = STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt));
dt = STMT_VINFO_DEF_TYPE (def_stmt_info);
if (dt == vect_unknown_def_type)
{
@ -415,7 +412,7 @@ again:
return -1;
}
switch (gimple_code (def_stmt))
switch (gimple_code (def_stmt_info->stmt))
{
case GIMPLE_PHI:
case GIMPLE_ASSIGN:
@ -499,7 +496,7 @@ again:
case vect_reduction_def:
case vect_induction_def:
case vect_internal_def:
oprnd_info->def_stmts.quick_push (def_stmt);
oprnd_info->def_stmts.quick_push (def_stmt_info);
break;
default:

View File

@ -459,11 +459,9 @@ process_use (gimple *stmt, tree use, loop_vec_info loop_vinfo,
enum vect_relevant relevant, vec<gimple *> *worklist,
bool force)
{
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
stmt_vec_info dstmt_vinfo;
basic_block bb, def_bb;
gimple *def_stmt;
enum vect_def_type dt;
/* case 1: we are only interested in uses that need to be vectorized. Uses
@ -471,7 +469,7 @@ process_use (gimple *stmt, tree use, loop_vec_info loop_vinfo,
if (!force && !exist_non_indexing_operands_for_use_p (use, stmt))
return true;
if (!vect_is_simple_use (use, loop_vinfo, &dt, &def_stmt))
if (!vect_is_simple_use (use, loop_vinfo, &dt, &dstmt_vinfo))
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@ -479,27 +477,20 @@ process_use (gimple *stmt, tree use, loop_vec_info loop_vinfo,
return false;
}
if (!def_stmt || gimple_nop_p (def_stmt))
if (!dstmt_vinfo)
return true;
def_bb = gimple_bb (def_stmt);
if (!flow_bb_inside_loop_p (loop, def_bb))
{
if (dump_enabled_p ())
dump_printf_loc (MSG_NOTE, vect_location, "def_stmt is out of loop.\n");
return true;
}
def_bb = gimple_bb (dstmt_vinfo->stmt);
/* case 2: A reduction phi (STMT) defined by a reduction stmt (DEF_STMT).
DEF_STMT must have already been processed, because this should be the
/* case 2: A reduction phi (STMT) defined by a reduction stmt (DSTMT_VINFO).
DSTMT_VINFO must have already been processed, because this should be the
only way that STMT, which is a reduction-phi, was put in the worklist,
as there should be no other uses for DEF_STMT in the loop. So we just
as there should be no other uses for DSTMT_VINFO in the loop. So we just
check that everything is as expected, and we are done. */
dstmt_vinfo = vinfo_for_stmt (def_stmt);
bb = gimple_bb (stmt);
if (gimple_code (stmt) == GIMPLE_PHI
&& STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_reduction_def
&& gimple_code (def_stmt) != GIMPLE_PHI
&& gimple_code (dstmt_vinfo->stmt) != GIMPLE_PHI
&& STMT_VINFO_DEF_TYPE (dstmt_vinfo) == vect_reduction_def
&& bb->loop_father == def_bb->loop_father)
{
@ -514,7 +505,7 @@ process_use (gimple *stmt, tree use, loop_vec_info loop_vinfo,
/* case 3a: outer-loop stmt defining an inner-loop stmt:
outer-loop-header-bb:
d = def_stmt
d = dstmt_vinfo
inner-loop:
stmt # use (d)
outer-loop-tail-bb:
@ -554,7 +545,7 @@ process_use (gimple *stmt, tree use, loop_vec_info loop_vinfo,
outer-loop-header-bb:
...
inner-loop:
d = def_stmt
d = dstmt_vinfo
outer-loop-tail-bb (or outer-loop-exit-bb in double reduction):
stmt # use (d) */
else if (flow_loop_nested_p (bb->loop_father, def_bb->loop_father))
@ -601,7 +592,7 @@ process_use (gimple *stmt, tree use, loop_vec_info loop_vinfo,
}
vect_mark_relevant (worklist, def_stmt, relevant, false);
vect_mark_relevant (worklist, dstmt_vinfo, relevant, false);
return true;
}
@ -1563,7 +1554,9 @@ vect_get_vec_def_for_operand (tree op, gimple *stmt, tree vectype)
dump_printf (MSG_NOTE, "\n");
}
is_simple_use = vect_is_simple_use (op, loop_vinfo, &dt, &def_stmt);
stmt_vec_info def_stmt_info;
is_simple_use = vect_is_simple_use (op, loop_vinfo, &dt,
&def_stmt_info, &def_stmt);
gcc_assert (is_simple_use);
if (def_stmt && dump_enabled_p ())
{
@ -1588,7 +1581,7 @@ vect_get_vec_def_for_operand (tree op, gimple *stmt, tree vectype)
return vect_init_vector (stmt, op, vector_type, NULL);
}
else
return vect_get_vec_def_for_operand_1 (def_stmt, dt);
return vect_get_vec_def_for_operand_1 (def_stmt_info, dt);
}
@ -5479,7 +5472,9 @@ vectorizable_shift (gimple *stmt, gimple_stmt_iterator *gsi,
return false;
op1 = gimple_assign_rhs2 (stmt);
if (!vect_is_simple_use (op1, vinfo, &dt[1], &op1_vectype))
stmt_vec_info op1_def_stmt_info;
if (!vect_is_simple_use (op1, vinfo, &dt[1], &op1_vectype,
&op1_def_stmt_info))
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@ -5524,13 +5519,9 @@ vectorizable_shift (gimple *stmt, gimple_stmt_iterator *gsi,
/* If the shift amount is computed by a pattern stmt we cannot
use the scalar amount directly thus give up and use a vector
shift. */
if (dt[1] == vect_internal_def)
{
gimple *def = SSA_NAME_DEF_STMT (op1);
if (is_pattern_stmt_p (vinfo_for_stmt (def)))
if (op1_def_stmt_info && is_pattern_stmt_p (op1_def_stmt_info))
scalar_shift_arg = false;
}
}
else
{
if (dump_enabled_p ())
@ -10051,7 +10042,10 @@ get_same_sized_vectype (tree scalar_type, tree vector_type)
VINFO - the vect info of the loop or basic block that is being vectorized.
OPERAND - operand in the loop or bb.
Output:
DEF_STMT_OUT (optional) - the defining stmt in case OPERAND is an SSA_NAME.
DEF_STMT_INFO_OUT (optional) - information about the defining stmt in
case OPERAND is an SSA_NAME that is defined in the vectorizable region
DEF_STMT_OUT (optional) - the defining stmt in case OPERAND is an SSA_NAME;
the definition could be anywhere in the function
DT - the type of definition
Returns whether a stmt with OPERAND can be vectorized.
@ -10064,8 +10058,10 @@ get_same_sized_vectype (tree scalar_type, tree vector_type)
bool
vect_is_simple_use (tree operand, vec_info *vinfo, enum vect_def_type *dt,
gimple **def_stmt_out)
stmt_vec_info *def_stmt_info_out, gimple **def_stmt_out)
{
if (def_stmt_info_out)
*def_stmt_info_out = NULL;
if (def_stmt_out)
*def_stmt_out = NULL;
*dt = vect_unknown_def_type;
@ -10113,6 +10109,8 @@ vect_is_simple_use (tree operand, vec_info *vinfo, enum vect_def_type *dt,
*dt = vect_unknown_def_type;
break;
}
if (def_stmt_info_out)
*def_stmt_info_out = stmt_vinfo;
}
if (def_stmt_out)
*def_stmt_out = def_stmt;
@ -10175,14 +10173,18 @@ vect_is_simple_use (tree operand, vec_info *vinfo, enum vect_def_type *dt,
bool
vect_is_simple_use (tree operand, vec_info *vinfo, enum vect_def_type *dt,
tree *vectype, gimple **def_stmt_out)
tree *vectype, stmt_vec_info *def_stmt_info_out,
gimple **def_stmt_out)
{
stmt_vec_info def_stmt_info;
gimple *def_stmt;
if (!vect_is_simple_use (operand, vinfo, dt, &def_stmt))
if (!vect_is_simple_use (operand, vinfo, dt, &def_stmt_info, &def_stmt))
return false;
if (def_stmt_out)
*def_stmt_out = def_stmt;
if (def_stmt_info_out)
*def_stmt_info_out = def_stmt_info;
/* Now get a vector type if the def is internal, otherwise supply
NULL_TREE and leave it up to the caller to figure out a proper
@ -10193,8 +10195,7 @@ vect_is_simple_use (tree operand, vec_info *vinfo, enum vect_def_type *dt,
|| *dt == vect_double_reduction_def
|| *dt == vect_nested_cycle)
{
stmt_vec_info stmt_info = vinfo_for_stmt (def_stmt);
*vectype = STMT_VINFO_VECTYPE (stmt_info);
*vectype = STMT_VINFO_VECTYPE (def_stmt_info);
gcc_assert (*vectype != NULL_TREE);
if (dump_enabled_p ())
{

View File

@ -1532,9 +1532,10 @@ extern tree get_mask_type_for_scalar_type (tree);
extern tree get_same_sized_vectype (tree, tree);
extern bool vect_get_loop_mask_type (loop_vec_info);
extern bool vect_is_simple_use (tree, vec_info *, enum vect_def_type *,
gimple ** = NULL);
stmt_vec_info * = NULL, gimple ** = NULL);
extern bool vect_is_simple_use (tree, vec_info *, enum vect_def_type *,
tree *, gimple ** = NULL);
tree *, stmt_vec_info * = NULL,
gimple ** = NULL);
extern bool supportable_widening_operation (enum tree_code, gimple *, tree,
tree, enum tree_code *,
enum tree_code *, int *,