/* Data References Analysis and Manipulation Utilities for Vectorization.
- Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc.
Contributed by Dorit Naishlos <dorit@il.ibm.com>
and Ira Rosen <irar@il.ibm.com>
int misal = DR_MISALIGNMENT (dr);
tree vectype = STMT_VINFO_VECTYPE (stmt_info);
misal += negative ? -npeel * dr_size : npeel * dr_size;
- misal &= GET_MODE_SIZE (TYPE_MODE (vectype)) - 1;
+ misal &= (TYPE_ALIGN (vectype) / BITS_PER_UNIT) - 1;
SET_DR_MISALIGNMENT (dr, misal);
return;
}
if (ba)
is_packed = contains_packed_reference (ba);
+ if (compare_tree_int (TYPE_SIZE (type), TYPE_ALIGN (type)) > 0)
+ is_packed = true;
+
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "Unknown misalignment, is_packed = %d",is_packed);
if (targetm.vectorize.vector_alignment_reachable (type, is_packed))
stmt = DR_STMT (dr);
stmt_info = vinfo_for_stmt (stmt);
+ if (!STMT_VINFO_RELEVANT (stmt_info))
+ continue;
+
/* For interleaving, only the alignment of the first access
matters. */
if (STMT_VINFO_STRIDED_ACCESS (stmt_info)
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
HOST_WIDE_INT dr_step = TREE_INT_CST_LOW (step);
- HOST_WIDE_INT stride;
+ HOST_WIDE_INT stride, last_accessed_element = 1;
bool slp_impossible = false;
+ struct loop *loop = NULL;
+
+ if (loop_vinfo)
+ loop = LOOP_VINFO_LOOP (loop_vinfo);
/* For interleaving, STRIDE is STEP counted in elements, i.e., the size of the
interleaving group (including gaps). */
fprintf (vect_dump, " step ");
print_generic_expr (vect_dump, step, TDF_SLIM);
}
+
+ if (loop_vinfo)
+ {
+ if (vect_print_dump_info (REPORT_DETAILS))
+ fprintf (vect_dump, "Data access with gaps requires scalar "
+ "epilogue loop");
+ if (loop->inner)
+ {
+ if (vect_print_dump_info (REPORT_DETAILS))
+ fprintf (vect_dump, "Peeling for outer loop is not"
+ " supported");
+ return false;
+ }
+
+ LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo) = true;
+ }
+
return true;
}
next = DR_GROUP_NEXT_DR (vinfo_for_stmt (next));
continue;
}
+
prev = next;
/* Check that all the accesses have the same STEP. */
gaps += diff - 1;
}
+ last_accessed_element += diff;
+
/* Store the gap from the previous member of the group. If there is no
gap in the access, DR_GROUP_GAP is always 1. */
DR_GROUP_GAP (vinfo_for_stmt (next)) = diff;
VEC_safe_push (gimple, heap, BB_VINFO_STRIDED_STORES (bb_vinfo),
stmt);
}
+
+ /* There is a gap in the end of the group. */
+ if (stride - last_accessed_element > 0 && loop_vinfo)
+ {
+ if (vect_print_dump_info (REPORT_DETAILS))
+ fprintf (vect_dump, "Data access with gaps requires scalar "
+ "epilogue loop");
+ if (loop->inner)
+ {
+ if (vect_print_dump_info (REPORT_DETAILS))
+ fprintf (vect_dump, "Peeling for outer loop is not supported");
+ return false;
+ }
+
+ LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo) = true;
+ }
}
return true;
{
loop = LOOP_VINFO_LOOP (loop_vinfo);
res = compute_data_dependences_for_loop
- (loop, true, &LOOP_VINFO_DATAREFS (loop_vinfo),
+ (loop, true,
+ &LOOP_VINFO_LOOP_NEST (loop_vinfo),
+ &LOOP_VINFO_DATAREFS (loop_vinfo),
&LOOP_VINFO_DDRS (loop_vinfo));
if (!res)
print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
}
- if (bb_vinfo)
- {
- /* Mark the statement as not vectorizable. */
- STMT_VINFO_VECTORIZABLE (stmt_info) = false;
- continue;
- }
- else
- return false;
+ return false;
}
if (TREE_CODE (DR_BASE_ADDRESS (dr)) == INTEGER_CST)
if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
fprintf (vect_dump, "not vectorized: base addr of dr is a "
"constant");
- if (bb_vinfo)
+ return false;
+ }
+
+ if (TREE_THIS_VOLATILE (DR_REF (dr)))
+ {
+ if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
{
- /* Mark the statement as not vectorizable. */
- STMT_VINFO_VECTORIZABLE (stmt_info) = false;
- continue;
+ fprintf (vect_dump, "not vectorized: volatile type ");
+ print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
}
- else
- return false;
+ return false;
}
base = unshare_expr (DR_BASE_ADDRESS (dr));
offset = unshare_expr (DR_OFFSET (dr));
init = unshare_expr (DR_INIT (dr));
- if (stmt_could_throw_p (stmt))
+ if (stmt_can_throw_internal (stmt))
{
if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
{
return false;
}
+ if (is_gimple_call (stmt))
+ {
+ if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
+ {
+ fprintf (vect_dump, "not vectorized: dr in a call ");
+ print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ }
+ return false;
+ }
+
/* Update DR field in stmt_vec_info struct. */
/* If the dataref is in an inner-loop of the loop that is considered for
if (DR_PTR_INFO (dr)
&& TREE_CODE (vec_stmt) == SSA_NAME)
- duplicate_ssa_name_ptr_info (vec_stmt, DR_PTR_INFO (dr));
+ {
+ duplicate_ssa_name_ptr_info (vec_stmt, DR_PTR_INFO (dr));
+ if (offset)
+ {
+ SSA_NAME_PTR_INFO (vec_stmt)->align = 1;
+ SSA_NAME_PTR_INFO (vec_stmt)->misalign = 0;
+ }
+ }
if (vect_print_dump_info (REPORT_DETAILS))
{
/* Copy the points-to information if it exists. */
if (DR_PTR_INFO (dr))
- duplicate_ssa_name_ptr_info (new_dataref_ptr, DR_PTR_INFO (dr));
+ {
+ duplicate_ssa_name_ptr_info (new_dataref_ptr, DR_PTR_INFO (dr));
+ SSA_NAME_PTR_INFO (new_dataref_ptr)->align = 1;
+ SSA_NAME_PTR_INFO (new_dataref_ptr)->misalign = 0;
+ }
if (!ptr_incr)
return new_dataref_ptr;