#include "expr.h"
#include "recog.h"
#include "optabs.h"
+#include "diagnostic-core.h"
#include "toplev.h"
#include "tree-vectorizer.h"
#include "langhooks.h"
{
case dr_aligned:
{
- inside_cost += ncopies * vect_get_stmt_cost (vector_load);
+ *inside_cost += ncopies * vect_get_stmt_cost (vector_load);
if (vect_print_dump_info (REPORT_COST))
fprintf (vect_dump, "vect_model_load_cost: aligned.");
builtin_decl =
targetm.vectorize.builtin_conversion (code,
vectype_out, vectype_in);
- for (i = 0; VEC_iterate (tree, vec_oprnds0, i, vop0); i++)
+ FOR_EACH_VEC_ELT (tree, vec_oprnds0, i, vop0)
{
/* Arguments are ready. create the new vector stmt. */
new_stmt = gimple_build_call (builtin_decl, 1, vop0);
vect_get_vec_defs_for_stmt_copy (dt, &vec_oprnds, NULL);
/* Arguments are ready. create the new vector stmt. */
- for (i = 0; VEC_iterate (tree, vec_oprnds, i, vop); i++)
+ FOR_EACH_VEC_ELT (tree, vec_oprnds, i, vop)
{
if (CONVERT_EXPR_CODE_P (code))
vop = build1 (VIEW_CONVERT_EXPR, vectype, vop);
vect_get_vec_defs_for_stmt_copy (dt, &vec_oprnds0, &vec_oprnds1);
/* Arguments are ready. Create the new vector stmt. */
- for (i = 0; VEC_iterate (tree, vec_oprnds0, i, vop0); i++)
+ FOR_EACH_VEC_ELT (tree, vec_oprnds0, i, vop0)
{
vop1 = ((op_type == binary_op)
? VEC_index (tree, vec_oprnds1, i) : NULL);
vec_dest = VEC_pop (tree, vec_dsts);
vec_tmp = VEC_alloc (tree, heap, VEC_length (tree, *vec_oprnds0) * 2);
- for (i = 0; VEC_iterate (tree, *vec_oprnds0, i, vop0); i++)
+ FOR_EACH_VEC_ELT (tree, *vec_oprnds0, i, vop0)
{
if (op_type == binary_op)
vop1 = VEC_index (tree, *vec_oprnds1, i);
next_stmt = first_stmt;
for (i = 0; i < vec_num; i++)
{
+ struct ptr_info_def *pi;
+
if (i > 0)
/* Bump the vector pointer. */
dataref_ptr = bump_vector_ptr (dataref_ptr, ptr_incr, gsi, stmt,
vect_permute_store_chain(). */
vec_oprnd = VEC_index (tree, result_chain, i);
+ data_ref = build2 (MEM_REF, TREE_TYPE (vec_oprnd), dataref_ptr,
+ build_int_cst (reference_alias_ptr_type
+ (DR_REF (first_dr)), 0));
+ pi = get_ptr_info (dataref_ptr);
+ pi->align = TYPE_ALIGN_UNIT (vectype);
if (aligned_access_p (first_dr))
- data_ref = build_simple_mem_ref (dataref_ptr);
- else
- {
- int mis = DR_MISALIGNMENT (first_dr);
- tree tmis = (mis == -1 ? size_zero_node : size_int (mis));
- tmis = size_binop (MULT_EXPR, tmis, size_int (BITS_PER_UNIT));
- data_ref = build2 (MISALIGNED_INDIRECT_REF, vectype, dataref_ptr, tmis);
- }
-
- /* If accesses through a pointer to vectype do not alias the original
- memory reference we have a problem. This should never happen. */
- gcc_assert (alias_sets_conflict_p (get_alias_set (data_ref),
- get_alias_set (gimple_assign_lhs (stmt))));
+ pi->misalign = 0;
+ else if (DR_MISALIGNMENT (first_dr) == -1)
+ {
+ TREE_TYPE (data_ref)
+ = build_aligned_type (TREE_TYPE (data_ref),
+ TYPE_ALIGN (TREE_TYPE (vectype)));
+ pi->align = TYPE_ALIGN_UNIT (TREE_TYPE (vectype));
+ pi->misalign = 0;
+ }
+ else
+ {
+ TREE_TYPE (data_ref)
+ = build_aligned_type (TREE_TYPE (data_ref),
+ TYPE_ALIGN (TREE_TYPE (vectype)));
+ pi->misalign = DR_MISALIGNMENT (first_dr);
+ }
/* Arguments are ready. Create the new vector stmt. */
new_stmt = gimple_build_assign (data_ref, vec_oprnd);
switch (alignment_support_scheme)
{
case dr_aligned:
- gcc_assert (aligned_access_p (first_dr));
- data_ref = build_simple_mem_ref (dataref_ptr);
- break;
case dr_unaligned_supported:
{
- int mis = DR_MISALIGNMENT (first_dr);
- tree tmis = (mis == -1 ? size_zero_node : size_int (mis));
-
- tmis = size_binop (MULT_EXPR, tmis, size_int(BITS_PER_UNIT));
- data_ref =
- build2 (MISALIGNED_INDIRECT_REF, vectype, dataref_ptr, tmis);
+ struct ptr_info_def *pi;
+ data_ref
+ = build2 (MEM_REF, vectype, dataref_ptr,
+ build_int_cst (reference_alias_ptr_type
+ (DR_REF (first_dr)), 0));
+ pi = get_ptr_info (dataref_ptr);
+ pi->align = TYPE_ALIGN_UNIT (vectype);
+ if (alignment_support_scheme == dr_aligned)
+ {
+ gcc_assert (aligned_access_p (first_dr));
+ pi->misalign = 0;
+ }
+ else if (DR_MISALIGNMENT (first_dr) == -1)
+ {
+ TREE_TYPE (data_ref)
+ = build_aligned_type (TREE_TYPE (data_ref),
+ TYPE_ALIGN (TREE_TYPE (vectype)));
+ pi->align = TYPE_ALIGN_UNIT (TREE_TYPE (vectype));
+ pi->misalign = 0;
+ }
+ else
+ {
+ TREE_TYPE (data_ref)
+ = build_aligned_type (TREE_TYPE (data_ref),
+ TYPE_ALIGN (TREE_TYPE (vectype)));
+ pi->misalign = DR_MISALIGNMENT (first_dr);
+ }
break;
}
case dr_explicit_realign:
dr_explicit_realign,
dataref_ptr, NULL);
- data_ref = build1 (ALIGN_INDIRECT_REF, vectype, dataref_ptr);
+ new_stmt = gimple_build_assign_with_ops
+ (BIT_AND_EXPR, NULL_TREE, dataref_ptr,
+ build_int_cst
+ (TREE_TYPE (dataref_ptr),
+ -(HOST_WIDE_INT)TYPE_ALIGN_UNIT (vectype)));
+ ptr = make_ssa_name (SSA_NAME_VAR (dataref_ptr), new_stmt);
+ gimple_assign_set_lhs (new_stmt, ptr);
+ vect_finish_stmt_generation (stmt, new_stmt, gsi);
+ data_ref
+ = build2 (MEM_REF, vectype, ptr,
+ build_int_cst (reference_alias_ptr_type
+ (DR_REF (first_dr)), 0));
vec_dest = vect_create_destination_var (scalar_dest, vectype);
new_stmt = gimple_build_assign (vec_dest, data_ref);
new_temp = make_ssa_name (vec_dest, new_stmt);
bump = size_binop (MULT_EXPR, vs_minus_1,
TYPE_SIZE_UNIT (scalar_type));
ptr = bump_vector_ptr (dataref_ptr, NULL, gsi, stmt, bump);
- data_ref = build1 (ALIGN_INDIRECT_REF, vectype, ptr);
+ new_stmt = gimple_build_assign_with_ops
+ (BIT_AND_EXPR, NULL_TREE, ptr,
+ build_int_cst
+ (TREE_TYPE (ptr),
+ -(HOST_WIDE_INT)TYPE_ALIGN_UNIT (vectype)));
+ ptr = make_ssa_name (SSA_NAME_VAR (dataref_ptr), new_stmt);
+ gimple_assign_set_lhs (new_stmt, ptr);
+ vect_finish_stmt_generation (stmt, new_stmt, gsi);
+ data_ref
+ = build2 (MEM_REF, vectype, ptr,
+ build_int_cst (reference_alias_ptr_type
+ (DR_REF (first_dr)), 0));
break;
}
case dr_explicit_realign_optimized:
- data_ref = build1 (ALIGN_INDIRECT_REF, vectype, dataref_ptr);
+ new_stmt = gimple_build_assign_with_ops
+ (BIT_AND_EXPR, NULL_TREE, dataref_ptr,
+ build_int_cst
+ (TREE_TYPE (dataref_ptr),
+ -(HOST_WIDE_INT)TYPE_ALIGN_UNIT (vectype)));
+ new_temp = make_ssa_name (SSA_NAME_VAR (dataref_ptr), new_stmt);
+ gimple_assign_set_lhs (new_stmt, new_temp);
+ vect_finish_stmt_generation (stmt, new_stmt, gsi);
+ data_ref
+ = build2 (MEM_REF, vectype, new_temp,
+ build_int_cst (reference_alias_ptr_type
+ (DR_REF (first_dr)), 0));
break;
default:
gcc_unreachable ();
}
- /* If accesses through a pointer to vectype do not alias the original
- memory reference we have a problem. This should never happen. */
- gcc_assert (alias_sets_conflict_p (get_alias_set (data_ref),
- get_alias_set (gimple_assign_rhs1 (stmt))));
vec_dest = vect_create_destination_var (scalar_dest, vectype);
new_stmt = gimple_build_assign (vec_dest, data_ref);
new_temp = make_ssa_name (vec_dest, new_stmt);
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
enum machine_mode vec_mode;
tree def;
- enum vect_def_type dt;
+ enum vect_def_type dt, dts[4];
int nunits = TYPE_VECTOR_SUBPARTS (vectype);
int ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
enum tree_code code;
+ stmt_vec_info prev_stmt_info = NULL;
+ int j;
/* FORNOW: unsupported in basic block SLP. */
gcc_assert (loop_vinfo);
gcc_assert (ncopies >= 1);
- if (ncopies > 1)
+ if (reduc_index && ncopies > 1)
return false; /* FORNOW */
if (!STMT_VINFO_RELEVANT_P (stmt_info))
vec_dest = vect_create_destination_var (scalar_dest, vectype);
/* Handle cond expr. */
- vec_cond_lhs =
- vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 0), stmt, NULL);
- vec_cond_rhs =
- vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 1), stmt, NULL);
- if (reduc_index == 1)
- vec_then_clause = reduc_def;
- else
- vec_then_clause = vect_get_vec_def_for_operand (then_clause, stmt, NULL);
- if (reduc_index == 2)
- vec_else_clause = reduc_def;
- else
- vec_else_clause = vect_get_vec_def_for_operand (else_clause, stmt, NULL);
-
- /* Arguments are ready. Create the new vector stmt. */
- vec_compare = build2 (TREE_CODE (cond_expr), vectype,
- vec_cond_lhs, vec_cond_rhs);
- vec_cond_expr = build3 (VEC_COND_EXPR, vectype,
- vec_compare, vec_then_clause, vec_else_clause);
-
- *vec_stmt = gimple_build_assign (vec_dest, vec_cond_expr);
- new_temp = make_ssa_name (vec_dest, *vec_stmt);
- gimple_assign_set_lhs (*vec_stmt, new_temp);
- vect_finish_stmt_generation (stmt, *vec_stmt, gsi);
+ for (j = 0; j < ncopies; j++)
+ {
+ gimple new_stmt;
+ if (j == 0)
+ {
+ gimple gtemp;
+ vec_cond_lhs =
+ vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 0),
+ stmt, NULL);
+ vect_is_simple_use (TREE_OPERAND (cond_expr, 0), loop_vinfo,
+ NULL, >emp, &def, &dts[0]);
+ vec_cond_rhs =
+ vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 1),
+ stmt, NULL);
+ vect_is_simple_use (TREE_OPERAND (cond_expr, 1), loop_vinfo,
+ NULL, >emp, &def, &dts[1]);
+ if (reduc_index == 1)
+ vec_then_clause = reduc_def;
+ else
+ {
+ vec_then_clause = vect_get_vec_def_for_operand (then_clause,
+ stmt, NULL);
+ vect_is_simple_use (then_clause, loop_vinfo,
+ NULL, >emp, &def, &dts[2]);
+ }
+ if (reduc_index == 2)
+ vec_else_clause = reduc_def;
+ else
+ {
+ vec_else_clause = vect_get_vec_def_for_operand (else_clause,
+ stmt, NULL);
+ vect_is_simple_use (else_clause, loop_vinfo,
+ NULL, >emp, &def, &dts[3]);
+ }
+ }
+ else
+ {
+ vec_cond_lhs = vect_get_vec_def_for_stmt_copy (dts[0], vec_cond_lhs);
+ vec_cond_rhs = vect_get_vec_def_for_stmt_copy (dts[1], vec_cond_rhs);
+ vec_then_clause = vect_get_vec_def_for_stmt_copy (dts[2],
+ vec_then_clause);
+ vec_else_clause = vect_get_vec_def_for_stmt_copy (dts[3],
+ vec_else_clause);
+ }
+
+ /* Arguments are ready. Create the new vector stmt. */
+ vec_compare = build2 (TREE_CODE (cond_expr), vectype,
+ vec_cond_lhs, vec_cond_rhs);
+ vec_cond_expr = build3 (VEC_COND_EXPR, vectype,
+ vec_compare, vec_then_clause, vec_else_clause);
+
+ new_stmt = gimple_build_assign (vec_dest, vec_cond_expr);
+ new_temp = make_ssa_name (vec_dest, new_stmt);
+ gimple_assign_set_lhs (new_stmt, new_temp);
+ vect_finish_stmt_generation (stmt, new_stmt, gsi);
+ if (j == 0)
+ STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
+ else
+ STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
+
+ prev_stmt_info = vinfo_for_stmt (new_stmt);
+ }
return true;
}