[08/46] Add vec_info::lookup_def

This patch adds a vec_info helper for checking whether an operand is an
SSA_NAME that is defined in the vectorisable region.

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

gcc/
	* tree-vectorizer.h (vec_info::lookup_def): Declare.
	* tree-vectorizer.c (vec_info::lookup_def): New function.
	* tree-vect-patterns.c (vect_get_internal_def): Use it.
	(vect_widened_op_tree): Likewise.
	* tree-vect-stmts.c (vect_is_simple_use): Likewise.
	* tree-vect-loop.c (vect_analyze_loop_operations): Likewise.
	(vectorizable_reduction): Likewise.
	(vect_valid_reduction_input_p): Take a stmt_vec_info instead
	of a gimple *.
	(vect_is_slp_reduction): Update calls accordingly.  Use
	vec_info::lookup_def.
	(vect_is_simple_reduction): Likewise
	* tree-vect-slp.c (vect_detect_hybrid_slp_1): Use vec_info::lookup_def.

From-SVN: r263123
This commit is contained in:
Richard Sandiford 2018-07-31 14:21:45 +00:00 committed by Richard Sandiford
parent 6585ff8f3a
commit c98d05955b
7 changed files with 81 additions and 82 deletions

View File

@ -1,3 +1,19 @@
2018-07-31 Richard Sandiford <richard.sandiford@arm.com>
* tree-vectorizer.h (vec_info::lookup_def): Declare.
* tree-vectorizer.c (vec_info::lookup_def): New function.
* tree-vect-patterns.c (vect_get_internal_def): Use it.
(vect_widened_op_tree): Likewise.
* tree-vect-stmts.c (vect_is_simple_use): Likewise.
* tree-vect-loop.c (vect_analyze_loop_operations): Likewise.
(vectorizable_reduction): Likewise.
(vect_valid_reduction_input_p): Take a stmt_vec_info instead
of a gimple *.
(vect_is_slp_reduction): Update calls accordingly. Use
vec_info::lookup_def.
(vect_is_simple_reduction): Likewise
* tree-vect-slp.c (vect_detect_hybrid_slp_1): Use vec_info::lookup_def.
2018-07-31 Richard Sandiford <richard.sandiford@arm.com> 2018-07-31 Richard Sandiford <richard.sandiford@arm.com>
* tree-vectorizer.h (vec_info::lookup_stmt): Declare. * tree-vectorizer.h (vec_info::lookup_stmt): Declare.

View File

@ -1569,26 +1569,19 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo)
if (STMT_VINFO_RELEVANT_P (stmt_info)) if (STMT_VINFO_RELEVANT_P (stmt_info))
{ {
tree phi_op; tree phi_op;
gimple *op_def_stmt;
if (gimple_phi_num_args (phi) != 1) if (gimple_phi_num_args (phi) != 1)
return false; return false;
phi_op = PHI_ARG_DEF (phi, 0); phi_op = PHI_ARG_DEF (phi, 0);
if (TREE_CODE (phi_op) != SSA_NAME) stmt_vec_info op_def_info = loop_vinfo->lookup_def (phi_op);
if (!op_def_info)
return false; return false;
op_def_stmt = SSA_NAME_DEF_STMT (phi_op); if (STMT_VINFO_RELEVANT (op_def_info) != vect_used_in_outer
if (gimple_nop_p (op_def_stmt) && (STMT_VINFO_RELEVANT (op_def_info)
|| !flow_bb_inside_loop_p (loop, gimple_bb (op_def_stmt)) != vect_used_in_outer_by_reduction))
|| !vinfo_for_stmt (op_def_stmt)) return false;
return false;
if (STMT_VINFO_RELEVANT (vinfo_for_stmt (op_def_stmt))
!= vect_used_in_outer
&& STMT_VINFO_RELEVANT (vinfo_for_stmt (op_def_stmt))
!= vect_used_in_outer_by_reduction)
return false;
} }
continue; continue;
@ -2504,20 +2497,19 @@ report_vect_op (dump_flags_t msg_type, gimple *stmt, const char *msg)
dump_gimple_stmt (msg_type, TDF_SLIM, stmt, 0); dump_gimple_stmt (msg_type, TDF_SLIM, stmt, 0);
} }
/* DEF_STMT occurs in a loop that contains a potential reduction operation. /* DEF_STMT_INFO occurs in a loop that contains a potential reduction
Return true if the results of DEF_STMT are something that can be operation. Return true if the results of DEF_STMT_INFO are something
accumulated by such a reduction. */ that can be accumulated by such a reduction. */
static bool static bool
vect_valid_reduction_input_p (gimple *def_stmt) vect_valid_reduction_input_p (stmt_vec_info def_stmt_info)
{ {
stmt_vec_info def_stmt_info = vinfo_for_stmt (def_stmt); return (is_gimple_assign (def_stmt_info->stmt)
return (is_gimple_assign (def_stmt) || is_gimple_call (def_stmt_info->stmt)
|| is_gimple_call (def_stmt)
|| STMT_VINFO_DEF_TYPE (def_stmt_info) == vect_induction_def || STMT_VINFO_DEF_TYPE (def_stmt_info) == vect_induction_def
|| (gimple_code (def_stmt) == GIMPLE_PHI || (gimple_code (def_stmt_info->stmt) == GIMPLE_PHI
&& STMT_VINFO_DEF_TYPE (def_stmt_info) == vect_internal_def && STMT_VINFO_DEF_TYPE (def_stmt_info) == vect_internal_def
&& !is_loop_header_bb_p (gimple_bb (def_stmt)))); && !is_loop_header_bb_p (gimple_bb (def_stmt_info->stmt))));
} }
/* Detect SLP reduction of the form: /* Detect SLP reduction of the form:
@ -2633,18 +2625,14 @@ vect_is_slp_reduction (loop_vec_info loop_info, gimple *phi,
if (gimple_assign_rhs2 (next_stmt) == lhs) if (gimple_assign_rhs2 (next_stmt) == lhs)
{ {
tree op = gimple_assign_rhs1 (next_stmt); tree op = gimple_assign_rhs1 (next_stmt);
gimple *def_stmt = NULL; stmt_vec_info def_stmt_info = loop_info->lookup_def (op);
if (TREE_CODE (op) == SSA_NAME)
def_stmt = SSA_NAME_DEF_STMT (op);
/* Check that the other def is either defined in the loop /* Check that the other def is either defined in the loop
("vect_internal_def"), or it's an induction (defined by a ("vect_internal_def"), or it's an induction (defined by a
loop-header phi-node). */ loop-header phi-node). */
if (def_stmt if (def_stmt_info
&& gimple_bb (def_stmt) && flow_bb_inside_loop_p (loop, gimple_bb (def_stmt_info->stmt))
&& flow_bb_inside_loop_p (loop, gimple_bb (def_stmt)) && vect_valid_reduction_input_p (def_stmt_info))
&& vect_valid_reduction_input_p (def_stmt))
{ {
lhs = gimple_assign_lhs (next_stmt); lhs = gimple_assign_lhs (next_stmt);
next_stmt = REDUC_GROUP_NEXT_ELEMENT (vinfo_for_stmt (next_stmt)); next_stmt = REDUC_GROUP_NEXT_ELEMENT (vinfo_for_stmt (next_stmt));
@ -2656,18 +2644,14 @@ vect_is_slp_reduction (loop_vec_info loop_info, gimple *phi,
else else
{ {
tree op = gimple_assign_rhs2 (next_stmt); tree op = gimple_assign_rhs2 (next_stmt);
gimple *def_stmt = NULL; stmt_vec_info def_stmt_info = loop_info->lookup_def (op);
if (TREE_CODE (op) == SSA_NAME)
def_stmt = SSA_NAME_DEF_STMT (op);
/* Check that the other def is either defined in the loop /* Check that the other def is either defined in the loop
("vect_internal_def"), or it's an induction (defined by a ("vect_internal_def"), or it's an induction (defined by a
loop-header phi-node). */ loop-header phi-node). */
if (def_stmt if (def_stmt_info
&& gimple_bb (def_stmt) && flow_bb_inside_loop_p (loop, gimple_bb (def_stmt_info->stmt))
&& flow_bb_inside_loop_p (loop, gimple_bb (def_stmt)) && vect_valid_reduction_input_p (def_stmt_info))
&& vect_valid_reduction_input_p (def_stmt))
{ {
if (dump_enabled_p ()) if (dump_enabled_p ())
{ {
@ -2896,7 +2880,7 @@ vect_is_simple_reduction (loop_vec_info loop_info, gimple *phi,
{ {
struct loop *loop = (gimple_bb (phi))->loop_father; struct loop *loop = (gimple_bb (phi))->loop_father;
struct loop *vect_loop = LOOP_VINFO_LOOP (loop_info); struct loop *vect_loop = LOOP_VINFO_LOOP (loop_info);
gimple *def_stmt, *def1 = NULL, *def2 = NULL, *phi_use_stmt = NULL; gimple *def_stmt, *phi_use_stmt = NULL;
enum tree_code orig_code, code; enum tree_code orig_code, code;
tree op1, op2, op3 = NULL_TREE, op4 = NULL_TREE; tree op1, op2, op3 = NULL_TREE, op4 = NULL_TREE;
tree type; tree type;
@ -3020,7 +3004,7 @@ vect_is_simple_reduction (loop_vec_info loop_info, gimple *phi,
return NULL; return NULL;
} }
def1 = SSA_NAME_DEF_STMT (op1); gimple *def1 = SSA_NAME_DEF_STMT (op1);
if (gimple_bb (def1) if (gimple_bb (def1)
&& flow_bb_inside_loop_p (loop, gimple_bb (def_stmt)) && flow_bb_inside_loop_p (loop, gimple_bb (def_stmt))
&& loop->inner && loop->inner
@ -3178,14 +3162,9 @@ vect_is_simple_reduction (loop_vec_info loop_info, gimple *phi,
1) integer arithmetic and no trapv 1) integer arithmetic and no trapv
2) floating point arithmetic, and special flags permit this optimization 2) floating point arithmetic, and special flags permit this optimization
3) nested cycle (i.e., outer loop vectorization). */ 3) nested cycle (i.e., outer loop vectorization). */
if (TREE_CODE (op1) == SSA_NAME) stmt_vec_info def1_info = loop_info->lookup_def (op1);
def1 = SSA_NAME_DEF_STMT (op1); stmt_vec_info def2_info = loop_info->lookup_def (op2);
if (code != COND_EXPR && !def1_info && !def2_info)
if (TREE_CODE (op2) == SSA_NAME)
def2 = SSA_NAME_DEF_STMT (op2);
if (code != COND_EXPR
&& ((!def1 || gimple_nop_p (def1)) && (!def2 || gimple_nop_p (def2))))
{ {
if (dump_enabled_p ()) if (dump_enabled_p ())
report_vect_op (MSG_NOTE, def_stmt, "reduction: no defs for operands: "); report_vect_op (MSG_NOTE, def_stmt, "reduction: no defs for operands: ");
@ -3196,22 +3175,22 @@ vect_is_simple_reduction (loop_vec_info loop_info, gimple *phi,
the other def is either defined in the loop ("vect_internal_def"), the other def is either defined in the loop ("vect_internal_def"),
or it's an induction (defined by a loop-header phi-node). */ or it's an induction (defined by a loop-header phi-node). */
if (def2 && def2 == phi if (def2_info
&& def2_info->stmt == phi
&& (code == COND_EXPR && (code == COND_EXPR
|| !def1 || gimple_nop_p (def1) || !def1_info
|| !flow_bb_inside_loop_p (loop, gimple_bb (def1)) || vect_valid_reduction_input_p (def1_info)))
|| vect_valid_reduction_input_p (def1)))
{ {
if (dump_enabled_p ()) if (dump_enabled_p ())
report_vect_op (MSG_NOTE, def_stmt, "detected reduction: "); report_vect_op (MSG_NOTE, def_stmt, "detected reduction: ");
return def_stmt; return def_stmt;
} }
if (def1 && def1 == phi if (def1_info
&& def1_info->stmt == phi
&& (code == COND_EXPR && (code == COND_EXPR
|| !def2 || gimple_nop_p (def2) || !def2_info
|| !flow_bb_inside_loop_p (loop, gimple_bb (def2)) || vect_valid_reduction_input_p (def2_info)))
|| vect_valid_reduction_input_p (def2)))
{ {
if (! nested_in_vect_loop && orig_code != MINUS_EXPR) if (! nested_in_vect_loop && orig_code != MINUS_EXPR)
{ {
@ -6131,9 +6110,8 @@ vectorizable_reduction (gimple *stmt, gimple_stmt_iterator *gsi,
bool nested_cycle = false, found_nested_cycle_def = false; bool nested_cycle = false, found_nested_cycle_def = false;
bool double_reduc = false; bool double_reduc = false;
basic_block def_bb; basic_block def_bb;
struct loop * def_stmt_loop, *outer_loop = NULL; struct loop * def_stmt_loop;
tree def_arg; tree def_arg;
gimple *def_arg_stmt;
auto_vec<tree> vec_oprnds0; auto_vec<tree> vec_oprnds0;
auto_vec<tree> vec_oprnds1; auto_vec<tree> vec_oprnds1;
auto_vec<tree> vec_oprnds2; auto_vec<tree> vec_oprnds2;
@ -6151,7 +6129,6 @@ vectorizable_reduction (gimple *stmt, gimple_stmt_iterator *gsi,
if (nested_in_vect_loop_p (loop, stmt)) if (nested_in_vect_loop_p (loop, stmt))
{ {
outer_loop = loop;
loop = loop->inner; loop = loop->inner;
nested_cycle = true; nested_cycle = true;
} }
@ -6731,13 +6708,10 @@ vectorizable_reduction (gimple *stmt, gimple_stmt_iterator *gsi,
def_stmt_loop = def_bb->loop_father; def_stmt_loop = def_bb->loop_father;
def_arg = PHI_ARG_DEF_FROM_EDGE (reduc_def_stmt, def_arg = PHI_ARG_DEF_FROM_EDGE (reduc_def_stmt,
loop_preheader_edge (def_stmt_loop)); loop_preheader_edge (def_stmt_loop));
if (TREE_CODE (def_arg) == SSA_NAME stmt_vec_info def_arg_stmt_info = loop_vinfo->lookup_def (def_arg);
&& (def_arg_stmt = SSA_NAME_DEF_STMT (def_arg)) if (def_arg_stmt_info
&& gimple_code (def_arg_stmt) == GIMPLE_PHI && (STMT_VINFO_DEF_TYPE (def_arg_stmt_info)
&& flow_bb_inside_loop_p (outer_loop, gimple_bb (def_arg_stmt)) == vect_double_reduction_def))
&& vinfo_for_stmt (def_arg_stmt)
&& STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_arg_stmt))
== vect_double_reduction_def)
double_reduc = true; double_reduc = true;
} }

View File

@ -227,14 +227,11 @@ vect_element_precision (unsigned int precision)
static stmt_vec_info static stmt_vec_info
vect_get_internal_def (vec_info *vinfo, tree op) vect_get_internal_def (vec_info *vinfo, tree op)
{ {
vect_def_type dt; stmt_vec_info def_stmt_info = vinfo->lookup_def (op);
gimple *def_stmt; if (def_stmt_info
if (TREE_CODE (op) != SSA_NAME && STMT_VINFO_DEF_TYPE (def_stmt_info) == vect_internal_def)
|| !vect_is_simple_use (op, vinfo, &dt, &def_stmt) return def_stmt_info;
|| dt != vect_internal_def) return NULL;
return NULL;
return vinfo_for_stmt (def_stmt);
} }
/* Check whether NAME, an ssa-name used in USE_STMT, /* Check whether NAME, an ssa-name used in USE_STMT,
@ -528,6 +525,7 @@ vect_widened_op_tree (stmt_vec_info stmt_info, tree_code code,
vect_unpromoted_value *unprom, tree *common_type) vect_unpromoted_value *unprom, tree *common_type)
{ {
/* Check for an integer operation with the right code. */ /* Check for an integer operation with the right code. */
vec_info *vinfo = stmt_info->vinfo;
gassign *assign = dyn_cast <gassign *> (stmt_info->stmt); gassign *assign = dyn_cast <gassign *> (stmt_info->stmt);
if (!assign) if (!assign)
return 0; return 0;
@ -584,7 +582,7 @@ vect_widened_op_tree (stmt_vec_info stmt_info, tree_code code,
/* Recursively process the definition of the operand. */ /* Recursively process the definition of the operand. */
stmt_vec_info def_stmt_info stmt_vec_info def_stmt_info
= vinfo_for_stmt (SSA_NAME_DEF_STMT (this_unprom->op)); = vinfo->lookup_def (this_unprom->op);
nops = vect_widened_op_tree (def_stmt_info, code, widened_code, nops = vect_widened_op_tree (def_stmt_info, code, widened_code,
shift_p, max_nops, this_unprom, shift_p, max_nops, this_unprom,
common_type); common_type);

View File

@ -2389,11 +2389,8 @@ vect_detect_hybrid_slp_1 (tree *tp, int *, void *data)
if (wi->is_lhs) if (wi->is_lhs)
return NULL_TREE; return NULL_TREE;
stmt_vec_info def_stmt_info; stmt_vec_info def_stmt_info = loop_vinfo->lookup_def (*tp);
if (TREE_CODE (*tp) == SSA_NAME if (def_stmt_info && PURE_SLP_STMT (def_stmt_info))
&& !SSA_NAME_IS_DEFAULT_DEF (*tp)
&& (def_stmt_info = loop_vinfo->lookup_stmt (SSA_NAME_DEF_STMT (*tp)))
&& PURE_SLP_STMT (def_stmt_info))
{ {
if (dump_enabled_p ()) if (dump_enabled_p ())
{ {

View File

@ -10092,11 +10092,11 @@ vect_is_simple_use (tree operand, vec_info *vinfo, enum vect_def_type *dt,
else else
{ {
gimple *def_stmt = SSA_NAME_DEF_STMT (operand); gimple *def_stmt = SSA_NAME_DEF_STMT (operand);
if (! vect_stmt_in_region_p (vinfo, def_stmt)) stmt_vec_info stmt_vinfo = vinfo->lookup_def (operand);
if (!stmt_vinfo)
*dt = vect_external_def; *dt = vect_external_def;
else else
{ {
stmt_vec_info stmt_vinfo = vinfo_for_stmt (def_stmt);
if (STMT_VINFO_IN_PATTERN_P (stmt_vinfo)) if (STMT_VINFO_IN_PATTERN_P (stmt_vinfo))
{ {
def_stmt = STMT_VINFO_RELATED_STMT (stmt_vinfo); def_stmt = STMT_VINFO_RELATED_STMT (stmt_vinfo);

View File

@ -535,6 +535,19 @@ vec_info::lookup_stmt (gimple *stmt)
return NULL; return NULL;
} }
/* If NAME is an SSA_NAME and its definition has an associated stmt_vec_info,
return that stmt_vec_info, otherwise return null. It is safe to call
this on arbitrary operands. */
stmt_vec_info
vec_info::lookup_def (tree name)
{
if (TREE_CODE (name) == SSA_NAME
&& !SSA_NAME_IS_DEFAULT_DEF (name))
return lookup_stmt (SSA_NAME_DEF_STMT (name));
return NULL;
}
/* A helper function to free scev and LOOP niter information, as well as /* A helper function to free scev and LOOP niter information, as well as
clear loop constraint LOOP_C_FINITE. */ clear loop constraint LOOP_C_FINITE. */

View File

@ -219,6 +219,7 @@ struct vec_info {
stmt_vec_info add_stmt (gimple *); stmt_vec_info add_stmt (gimple *);
stmt_vec_info lookup_stmt (gimple *); stmt_vec_info lookup_stmt (gimple *);
stmt_vec_info lookup_def (tree);
/* The type of vectorization. */ /* The type of vectorization. */
vec_kind kind; vec_kind kind;