re PR tree-optimization/50912 (gimple assertion failure at gimple.h:1940 with -msse2)

PR tree-optimization/50912
	* tree-vectorizer.h (slp_void_p): New.
	(struct _slp_tree): Replace left and right with children.  Update
	documentation.
	(struct _slp_oprnd_info): New.
	(vect_get_vec_defs): Declare.
	(vect_get_slp_defs): Update arguments.
	* tree-vect-loop.c (vect_create_epilog_for_reduction): Call
	vect_get_vec_defs instead of vect_get_slp_defs.
	(vectorizable_reduction): Likewise.
	* tree-vect-stmts.c (vect_get_vec_defs): Remove static, add argument.
	Update call to vect_get_slp_defs.
	(vectorizable_conversion): Update call to vect_get_vec_defs.
	(vectorizable_assignment, vectorizable_shift,
	vectorizable_operation): Likewise.
	(vectorizable_type_demotion): Call vect_get_vec_defs instead of
	vect_get_slp_defs.
	(vectorizable_type_promotion, vectorizable_store): Likewise.
	(vect_analyze_stmt): Fix typo.
	* tree-vect-slp.c (vect_free_slp_tree): Update SLP tree traversal.
	(vect_print_slp_tree, vect_mark_slp_stmts,
	vect_mark_slp_stmts_relevant, vect_slp_rearrange_stmts,
	vect_detect_hybrid_slp_stmts, vect_slp_analyze_node_operations,
	vect_schedule_slp_instance): Likewise.
	(vect_create_new_slp_node): New.
	(vect_create_oprnd_info, vect_free_oprnd_info): Likewise.
	(vect_get_and_check_slp_defs): Pass information about defs using
	oprnds_info, allow any number of operands.
	(vect_build_slp_tree): Likewise.  Update calls to
	vect_get_and_check_slp_defs.  Fix comments.
	(vect_analyze_slp_instance): Move node creation to
	vect_create_new_slp_node.
	(vect_get_slp_defs): Allow any number of operands.

From-SVN: r180819
This commit is contained in:
Ira Rosen 2011-11-03 08:44:35 +00:00 committed by Ira Rosen
parent d2a7d041b6
commit d092494cf3
10 changed files with 541 additions and 382 deletions

View file

@ -1,3 +1,39 @@
2011-11-03 Ira Rosen <ira.rosen@linaro.org>
PR tree-optimization/50912
* tree-vectorizer.h (slp_void_p): New.
(struct _slp_tree): Replace left and right with children. Update
documentation.
(struct _slp_oprnd_info): New.
(vect_get_vec_defs): Declare.
(vect_get_slp_defs): Update arguments.
* tree-vect-loop.c (vect_create_epilog_for_reduction): Call
vect_get_vec_defs instead of vect_get_slp_defs.
(vectorizable_reduction): Likewise.
* tree-vect-stmts.c (vect_get_vec_defs): Remove static, add argument.
Update call to vect_get_slp_defs.
(vectorizable_conversion): Update call to vect_get_vec_defs.
(vectorizable_assignment, vectorizable_shift,
vectorizable_operation): Likewise.
(vectorizable_type_demotion): Call vect_get_vec_defs instead of
vect_get_slp_defs.
(vectorizable_type_promotion, vectorizable_store): Likewise.
(vect_analyze_stmt): Fix typo.
* tree-vect-slp.c (vect_free_slp_tree): Update SLP tree traversal.
(vect_print_slp_tree, vect_mark_slp_stmts,
vect_mark_slp_stmts_relevant, vect_slp_rearrange_stmts,
vect_detect_hybrid_slp_stmts, vect_slp_analyze_node_operations,
vect_schedule_slp_instance): Likewise.
(vect_create_new_slp_node): New.
(vect_create_oprnd_info, vect_free_oprnd_info): Likewise.
(vect_get_and_check_slp_defs): Pass information about defs using
oprnds_info, allow any number of operands.
(vect_build_slp_tree): Likewise. Update calls to
vect_get_and_check_slp_defs. Fix comments.
(vect_analyze_slp_instance): Move node creation to
vect_create_new_slp_node.
(vect_get_slp_defs): Allow any number of operands.
2011-11-02 Peter Bergner <bergner@vnet.ibm.com>
Iain Sandoe <iains@gcc.gnu.org>

View file

@ -1,3 +1,9 @@
2011-11-03 Ira Rosen <ira.rosen@linaro.org>
PR tree-optimization/50912
* gnat.dg/loop_optimization10.ad[sb]: New test.
* gnat.dg/loop_optimization10_pkg.ads: New helper.
2011-11-02 Jason Merrill <jason@redhat.com>
PR c++/50930

View file

@ -0,0 +1,18 @@
-- { dg-do compile }
-- { dg-options "-O3" }
-- { dg-options "-O3 -msse2" { target i?86-*-* x86_64-*-* } }
package body Loop_Optimization10 is
function F (Low, High : in Array_Real_Type) return Array_Limit_Type is
Result : Array_Limit_Type;
begin
for I in Result'Range
loop
Result (I) := F (Low (I), High (I));
end loop;
return Result;
end;
end Loop_Optimization10;

View file

@ -0,0 +1,11 @@
with Loop_Optimization10_Pkg; use Loop_Optimization10_Pkg;
package Loop_Optimization10 is
type Dual_Axis_Type is (One, Two);
type Array_Real_Type is array (Dual_Axis_Type) of Float;
type Array_Limit_Type is array (Dual_Axis_Type) of Limit_Type;
function F (Low, High : in Array_Real_Type) return Array_Limit_Type;
end Loop_Optimization10;

View file

@ -0,0 +1,12 @@
package Loop_Optimization10_Pkg is
pragma Pure (Loop_Optimization10_Pkg);
type Limit_Type is record
Low : Float;
High : Float;
end record;
function F (Low, High : in Float) return Limit_Type;
end Loop_Optimization10_Pkg;

View file

@ -2524,7 +2524,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
VEC (data_reference_p, heap) *datarefs;
struct data_reference *dr;
tree scalar_type;
bool res, stop_bb_analysis = false;
bool res;
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "=== vect_analyze_data_refs ===\n");
@ -2586,12 +2586,6 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
stmt = DR_STMT (dr);
stmt_info = vinfo_for_stmt (stmt);
if (stop_bb_analysis)
{
STMT_VINFO_VECTORIZABLE (stmt_info) = false;
continue;
}
/* Check that analysis of the data-ref succeeded. */
if (!DR_BASE_ADDRESS (dr) || !DR_OFFSET (dr) || !DR_INIT (dr)
|| !DR_STEP (dr))
@ -2602,13 +2596,6 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
}
if (bb_vinfo)
{
STMT_VINFO_VECTORIZABLE (stmt_info) = false;
stop_bb_analysis = true;
continue;
}
return false;
}
@ -2617,15 +2604,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
fprintf (vect_dump, "not vectorized: base addr of dr is a "
"constant");
if (bb_vinfo)
{
STMT_VINFO_VECTORIZABLE (stmt_info) = false;
stop_bb_analysis = true;
continue;
}
return false;
return false;
}
if (TREE_THIS_VOLATILE (DR_REF (dr)))
@ -2635,14 +2614,6 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
fprintf (vect_dump, "not vectorized: volatile type ");
print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
}
if (bb_vinfo)
{
STMT_VINFO_VECTORIZABLE (stmt_info) = false;
stop_bb_analysis = true;
continue;
}
return false;
}
@ -2658,14 +2629,6 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
"exception ");
print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
}
if (bb_vinfo)
{
STMT_VINFO_VECTORIZABLE (stmt_info) = false;
stop_bb_analysis = true;
continue;
}
return false;
}
@ -2783,14 +2746,6 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
"not vectorized: more than one data ref in stmt: ");
print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
}
if (bb_vinfo)
{
STMT_VINFO_VECTORIZABLE (stmt_info) = false;
stop_bb_analysis = true;
continue;
}
return false;
}
@ -2815,7 +2770,6 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
{
/* Mark the statement as not vectorizable. */
STMT_VINFO_VECTORIZABLE (stmt_info) = false;
stop_bb_analysis = true;
continue;
}
else

View file

@ -3537,8 +3537,8 @@ vect_create_epilog_for_reduction (VEC (tree, heap) *vect_defs, gimple stmt,
/* Get the loop-entry arguments. */
if (slp_node)
vect_get_slp_defs (reduction_op, NULL_TREE, slp_node, &vec_initial_defs,
NULL, reduc_index);
vect_get_vec_defs (reduction_op, NULL_TREE, stmt, &vec_initial_defs,
NULL, slp_node, reduc_index);
else
{
vec_initial_defs = VEC_alloc (tree, heap, 1);
@ -4792,8 +4792,8 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi,
}
if (slp_node)
vect_get_slp_defs (op0, op1, slp_node, &vec_oprnds0, &vec_oprnds1,
-1);
vect_get_vec_defs (op0, op1, stmt, &vec_oprnds0, &vec_oprnds1,
slp_node, -1);
else
{
loop_vec_def0 = vect_get_vec_def_for_operand (ops[!reduc_index],

File diff suppressed because it is too large Load diff

View file

@ -1399,16 +1399,35 @@ vect_get_vec_defs_for_stmt_copy (enum vect_def_type *dt,
}
/* Get vectorized definitions for OP0 and OP1, or SLP_NODE if it is not
NULL. */
/* Get vectorized definitions for OP0 and OP1.
REDUC_INDEX is the index of reduction operand in case of reduction,
and -1 otherwise. */
static void
void
vect_get_vec_defs (tree op0, tree op1, gimple stmt,
VEC(tree,heap) **vec_oprnds0, VEC(tree,heap) **vec_oprnds1,
slp_tree slp_node)
VEC (tree, heap) **vec_oprnds0,
VEC (tree, heap) **vec_oprnds1,
slp_tree slp_node, int reduc_index)
{
if (slp_node)
vect_get_slp_defs (op0, op1, slp_node, vec_oprnds0, vec_oprnds1, -1);
{
int nops = (op1 == NULL_TREE) ? 1 : 2;
VEC (tree, heap) *ops = VEC_alloc (tree, heap, nops);
VEC (slp_void_p, heap) *vec_defs = VEC_alloc (slp_void_p, heap, nops);
VEC_quick_push (tree, ops, op0);
if (op1)
VEC_quick_push (tree, ops, op1);
vect_get_slp_defs (ops, slp_node, &vec_defs, reduc_index);
*vec_oprnds0 = (VEC (tree, heap) *) VEC_index (slp_void_p, vec_defs, 0);
if (op1)
*vec_oprnds1 = (VEC (tree, heap) *) VEC_index (slp_void_p, vec_defs, 1);
VEC_free (tree, heap, ops);
VEC_free (slp_void_p, heap, vec_defs);
}
else
{
tree vec_oprnd;
@ -1986,7 +2005,8 @@ vectorizable_conversion (gimple stmt, gimple_stmt_iterator *gsi,
for (j = 0; j < ncopies; j++)
{
if (j == 0)
vect_get_vec_defs (op0, NULL, stmt, &vec_oprnds0, NULL, slp_node);
vect_get_vec_defs (op0, NULL, stmt, &vec_oprnds0, NULL, slp_node,
-1);
else
vect_get_vec_defs_for_stmt_copy (dt, &vec_oprnds0, NULL);
@ -2223,7 +2243,7 @@ vectorizable_assignment (gimple stmt, gimple_stmt_iterator *gsi,
{
/* Handle uses. */
if (j == 0)
vect_get_vec_defs (op, NULL, stmt, &vec_oprnds, NULL, slp_node);
vect_get_vec_defs (op, NULL, stmt, &vec_oprnds, NULL, slp_node, -1);
else
vect_get_vec_defs_for_stmt_copy (dt, &vec_oprnds, NULL);
@ -2617,10 +2637,10 @@ vectorizable_shift (gimple stmt, gimple_stmt_iterator *gsi,
operand 1 should be of a vector type (the usual case). */
if (vec_oprnd1)
vect_get_vec_defs (op0, NULL_TREE, stmt, &vec_oprnds0, NULL,
slp_node);
slp_node, -1);
else
vect_get_vec_defs (op0, op1, stmt, &vec_oprnds0, &vec_oprnds1,
slp_node);
slp_node, -1);
}
else
vect_get_vec_defs_for_stmt_copy (dt, &vec_oprnds0, &vec_oprnds1);
@ -2942,10 +2962,10 @@ vectorizable_operation (gimple stmt, gimple_stmt_iterator *gsi,
{
if (op_type == binary_op || op_type == ternary_op)
vect_get_vec_defs (op0, op1, stmt, &vec_oprnds0, &vec_oprnds1,
slp_node);
slp_node, -1);
else
vect_get_vec_defs (op0, NULL_TREE, stmt, &vec_oprnds0, NULL,
slp_node);
slp_node, -1);
if (op_type == ternary_op)
{
vec_oprnds2 = VEC_alloc (tree, heap, 1);
@ -3268,7 +3288,8 @@ vectorizable_type_demotion (gimple stmt, gimple_stmt_iterator *gsi,
{
/* Handle uses. */
if (slp_node)
vect_get_slp_defs (op0, NULL_TREE, slp_node, &vec_oprnds0, NULL, -1);
vect_get_vec_defs (op0, NULL_TREE, stmt, &vec_oprnds0, NULL,
slp_node, -1);
else
{
VEC_free (tree, heap, vec_oprnds0);
@ -3627,12 +3648,12 @@ vectorizable_type_promotion (gimple stmt, gimple_stmt_iterator *gsi,
for (k = 0; k < slp_node->vec_stmts_size - 1; k++)
VEC_quick_push (tree, vec_oprnds1, vec_oprnd1);
vect_get_slp_defs (op0, NULL_TREE, slp_node, &vec_oprnds0, NULL,
-1);
vect_get_vec_defs (op0, NULL_TREE, stmt, &vec_oprnds0, NULL,
slp_node, -1);
}
else
vect_get_slp_defs (op0, op1, slp_node, &vec_oprnds0,
&vec_oprnds1, -1);
vect_get_vec_defs (op0, op1, stmt, &vec_oprnds0,
&vec_oprnds1, slp_node, -1);
}
else
{
@ -3870,6 +3891,7 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
vec_num = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node);
first_stmt = VEC_index (gimple, SLP_TREE_SCALAR_STMTS (slp_node), 0);
first_dr = STMT_VINFO_DATA_REF (vinfo_for_stmt (first_stmt));
op = gimple_assign_rhs1 (first_stmt);
}
else
/* VEC_NUM is the number of vect stmts to be created for this
@ -3952,8 +3974,8 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
if (slp)
{
/* Get vectorized arguments for SLP_NODE. */
vect_get_slp_defs (NULL_TREE, NULL_TREE, slp_node, &vec_oprnds,
NULL, -1);
vect_get_vec_defs (op, NULL_TREE, stmt, &vec_oprnds,
NULL, slp_node, -1);
vec_oprnd = VEC_index (tree, vec_oprnds, 0);
}
@ -5069,7 +5091,7 @@ vect_analyze_stmt (gimple stmt, bool *need_to_vectorize, slp_tree node)
In basic blocks we only analyze statements that are a part of some SLP
instance, therefore, all the statements are relevant.
Pattern statement need to be analyzed instead of the original statement
Pattern statement needs to be analyzed instead of the original statement
if the original statement is not relevant. Otherwise, we analyze both
statements. */

View file

@ -73,15 +73,15 @@ enum vect_def_type {
/************************************************************************
SLP
************************************************************************/
typedef void *slp_void_p;
DEF_VEC_P (slp_void_p);
DEF_VEC_ALLOC_P (slp_void_p, heap);
/* A computation tree of an SLP instance. Each node corresponds to a group of
/* A computation tree of an SLP instance. Each node corresponds to a group of
stmts to be packed in a SIMD stmt. */
typedef struct _slp_tree {
/* Only binary and unary operations are supported. LEFT child corresponds to
the first operand and RIGHT child to the second if the operation is
binary. */
struct _slp_tree *left;
struct _slp_tree *right;
/* Nodes that contain def-stmts of this node statements operands. */
VEC (slp_void_p, heap) *children;
/* A group of scalar stmts to be vectorized together. */
VEC (gimple, heap) *stmts;
/* Vectorized stmt/s. */
@ -146,14 +146,32 @@ DEF_VEC_ALLOC_P(slp_instance, heap);
#define SLP_INSTANCE_LOADS(S) (S)->loads
#define SLP_INSTANCE_FIRST_LOAD_STMT(S) (S)->first_load
#define SLP_TREE_LEFT(S) (S)->left
#define SLP_TREE_RIGHT(S) (S)->right
#define SLP_TREE_CHILDREN(S) (S)->children
#define SLP_TREE_SCALAR_STMTS(S) (S)->stmts
#define SLP_TREE_VEC_STMTS(S) (S)->vec_stmts
#define SLP_TREE_NUMBER_OF_VEC_STMTS(S) (S)->vec_stmts_size
#define SLP_TREE_OUTSIDE_OF_LOOP_COST(S) (S)->cost.outside_of_loop
#define SLP_TREE_INSIDE_OF_LOOP_COST(S) (S)->cost.inside_of_loop
/* This structure is used in creation of an SLP tree. Each instance
corresponds to the same operand in a group of scalar stmts in an SLP
node. */
typedef struct _slp_oprnd_info
{
/* Def-stmts for the operands. */
VEC (gimple, heap) *def_stmts;
/* Information about the first statement, its vector def-type, type, the
operand itself in case it's constant, and an indication if it's a pattern
stmt. */
enum vect_def_type first_dt;
tree first_def_type;
tree first_const_oprnd;
bool first_pattern;
} *slp_oprnd_info;
DEF_VEC_P(slp_oprnd_info);
DEF_VEC_ALLOC_P(slp_oprnd_info, heap);
typedef struct _vect_peel_info
{
@ -824,6 +842,8 @@ extern void vect_get_load_cost (struct data_reference *, int, bool,
unsigned int *, unsigned int *);
extern void vect_get_store_cost (struct data_reference *, int, unsigned int *);
extern bool vect_supportable_shift (enum tree_code, tree);
extern void vect_get_vec_defs (tree, tree, gimple, VEC (tree, heap) **,
VEC (tree, heap) **, slp_tree, int);
/* In tree-vect-data-refs.c. */
extern bool vect_can_force_dr_alignment_p (const_tree, unsigned int);
@ -891,8 +911,9 @@ extern void vect_update_slp_costs_according_to_vf (loop_vec_info);
extern bool vect_analyze_slp (loop_vec_info, bb_vec_info);
extern bool vect_make_slp_decision (loop_vec_info);
extern void vect_detect_hybrid_slp (loop_vec_info);
extern void vect_get_slp_defs (tree, tree, slp_tree, VEC (tree,heap) **,
VEC (tree,heap) **, int);
extern void vect_get_slp_defs (VEC (tree, heap) *, slp_tree,
VEC (slp_void_p, heap) **, int);
extern LOC find_bb_location (basic_block);
extern bb_vec_info vect_slp_analyze_bb (basic_block);
extern void vect_slp_transform_bb (basic_block);