summaryrefslogtreecommitdiff
path: root/gcc/tree-vect-analyze.c
diff options
context:
space:
mode:
authorvictork <victork@138bc75d-0d04-0410-961f-82ee72b054a4>2007-08-16 14:20:39 +0000
committervictork <victork@138bc75d-0d04-0410-961f-82ee72b054a4>2007-08-16 14:20:39 +0000
commit45b13dc38650fb0f8deecf944c6837637927102e (patch)
tree03bccd8be0266f061712ef717618bb096e583eab /gcc/tree-vect-analyze.c
parent20f192724d96d2ca6fb12212edaf04de013b2678 (diff)
downloadgcc-45b13dc38650fb0f8deecf944c6837637927102e.tar.gz
gcc/ChangeLog
* tree-vectorizer.c (new_loop_vec_info): Initialize new field. (destroy_loop_vec_info): Add call to VEC_free. * tree-vectorizer.h (may_alias_ddrs): Define. (LOOP_VINFO_MAY_ALIAS_DDRS): Define. * tree-vect-analyze.c (vect_analyze_data_ref_dependence): Change reporting to dump. (vect_is_duplicate_ddr): New. (vect_mark_for_runtime_alias_test): New. (vect_analyze_data_ref_dependences) Add call to vect_mark_for_runtime_alias_test. (vect_enhance_data_refs_alignment): Define local variable vect_versioning_for_alias_required, don't perform peeling for alignment if versioning for alias is required. (vect_enhance_data_refs_alignment): Use PARAM_VECT_MAX_VERSION_FOR_ALIGNMENT_CHECKS instead of PARAM_VECT_MAX_VERSION_CHECKS. * tree-vect-transform.c (vect_create_cond_for_alias_checks): New. (vect_transform_loop): Add call to vect_create_cond_for_alias_checks. (vect_vfa_segment_size): New. * params.def (PARAM_VECT_MAX_VERSION_FOR_ALIGNMENT_CHECKS): Rename. (PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS): Define. * gcc/doc/invoke.texi (vect-max-version-for-alignment-checks): Document. (vect-max-version-for-alias-checks): Document. (vect-max-version-checks): Remove. gcc/testsuite/ChangeLog * gcc.dg/vect/vect-vfa-01.c: New. * gcc.dg/vect/vect-vfa-02.c: New. * gcc.dg/vect/vect-vfa-03.c: New. * gcc.dg/vect/vect-vfa-04.c: New. * gcc.dg/vect/vect-102a.c, gcc.dg/vect/vect-51.c, gcc.dg/vect/pr29145.c, gcc.dg/vect/vect-43.c, gcc.dg/vect/vect-61.c, gcc.dg/vect/vect-53.c, gcc.dg/vect/vect-45.c, gcc.dg/vect/vect-101.c, gcc.dg/vect/vect-37.c, gcc.dg/vect/vect-79.c, gcc.dg/vect/vect-102.c, gcc.dg/vect/vect-dv-2.c, gcc.dg/vect/vect-57.c, gcc.dg/vect/vect-49.c, gfortran.dg/vect/pr19049.f90: Rename to start with prefix no-vfa-. * gcc.dg/vect/vect.exp: Disable versioning for alias when test starts with no-vfa-. * gfortran.dg/vect/vect.exp: Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@127559 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-vect-analyze.c')
-rw-r--r--gcc/tree-vect-analyze.c105
1 files changed, 94 insertions, 11 deletions
diff --git a/gcc/tree-vect-analyze.c b/gcc/tree-vect-analyze.c
index 3e2b4c73fd8..cc43ad61aef 100644
--- a/gcc/tree-vect-analyze.c
+++ b/gcc/tree-vect-analyze.c
@@ -1039,10 +1039,10 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
+ if (vect_print_dump_info (REPORT_DR_DETAILS))
{
fprintf (vect_dump,
- "not vectorized: can't determine dependence between ");
+ "versioning for alias required: can't determine dependence between ");
print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
fprintf (vect_dump, " and ");
print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
@@ -1052,9 +1052,9 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
if (DDR_NUM_DIST_VECTS (ddr) == 0)
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
+ if (vect_print_dump_info (REPORT_DR_DETAILS))
{
- fprintf (vect_dump, "not vectorized: bad dist vector for ");
+ fprintf (vect_dump, "versioning for alias required: bad dist vector for ");
print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
fprintf (vect_dump, " and ");
print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
@@ -1108,10 +1108,11 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
continue;
}
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
+ if (vect_print_dump_info (REPORT_DR_DETAILS))
{
fprintf (vect_dump,
- "not vectorized: possible dependence between data-refs ");
+ "versioning for alias required: possible dependence "
+ "between data-refs ");
print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
fprintf (vect_dump, " and ");
print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
@@ -1123,6 +1124,77 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
return false;
}
+/* Return TRUE if DDR_NEW is already found in MAY_ALIAS_DDRS list. */
+
+static bool
+vect_is_duplicate_ddr (VEC (ddr_p, heap) * may_alias_ddrs, ddr_p ddr_new)
+{
+ unsigned i;
+ ddr_p ddr;
+
+ for (i = 0; VEC_iterate (ddr_p, may_alias_ddrs, i, ddr); i++)
+ {
+ tree dref_A_i, dref_B_i, dref_A_j, dref_B_j;
+
+ dref_A_i = DR_REF (DDR_A (ddr));
+ dref_B_i = DR_REF (DDR_B (ddr));
+ dref_A_j = DR_REF (DDR_A (ddr_new));
+ dref_B_j = DR_REF (DDR_B (ddr_new));
+
+ if ((operand_equal_p (dref_A_i, dref_A_j, 0)
+ && operand_equal_p (dref_B_i, dref_B_j, 0))
+ || (operand_equal_p (dref_A_i, dref_B_j, 0)
+ && operand_equal_p (dref_B_i, dref_A_j, 0)))
+ {
+ if (vect_print_dump_info (REPORT_DR_DETAILS))
+ {
+ fprintf (vect_dump, "found same pair of data references ");
+ print_generic_expr (vect_dump, dref_A_i, TDF_SLIM);
+ fprintf (vect_dump, " and ");
+ print_generic_expr (vect_dump, dref_B_i, TDF_SLIM);
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+/* Save DDR in LOOP_VINFO list of ddrs that may alias and need to be
+ tested at run-time. Returns false if number of run-time checks
+ inserted by vectorizer is greater than maximum defined by
+ PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS. */
+static bool
+vect_mark_for_runtime_alias_test (ddr_p ddr, loop_vec_info loop_vinfo)
+{
+ if (vect_print_dump_info (REPORT_DR_DETAILS))
+ {
+ fprintf (vect_dump, "mark for run-time aliasing test between ");
+ print_generic_expr (vect_dump, DR_REF (DDR_A (ddr)), TDF_SLIM);
+ fprintf (vect_dump, " and ");
+ print_generic_expr (vect_dump, DR_REF (DDR_B (ddr)), TDF_SLIM);
+ }
+
+ /* Do not add to the list duplicate ddrs. */
+ if (vect_is_duplicate_ddr (LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo), ddr))
+ return true;
+
+ if (VEC_length (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo))
+ >= (unsigned) PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS))
+ {
+ if (vect_print_dump_info (REPORT_DR_DETAILS))
+ {
+ fprintf (vect_dump,
+ "disable versioning for alias - max number of generated "
+ "checks exceeded.");
+ }
+
+ VEC_truncate (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo), 0);
+
+ return false;
+ }
+ VEC_safe_push (ddr_p, heap, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo), ddr);
+ return true;
+}
/* Function vect_analyze_data_ref_dependences.
@@ -1133,7 +1205,7 @@ static bool
vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo)
{
unsigned int i;
- VEC (ddr_p, heap) *ddrs = LOOP_VINFO_DDRS (loop_vinfo);
+ VEC (ddr_p, heap) * ddrs = LOOP_VINFO_DDRS (loop_vinfo);
struct data_dependence_relation *ddr;
if (vect_print_dump_info (REPORT_DETAILS))
@@ -1141,7 +1213,11 @@ vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo)
for (i = 0; VEC_iterate (ddr_p, ddrs, i, ddr); i++)
if (vect_analyze_data_ref_dependence (ddr, loop_vinfo))
+ {
+ /* Add to list of ddrs that need to be tested at run-time. */
+ if (!vect_mark_for_runtime_alias_test (ddr, loop_vinfo))
return false;
+ }
return true;
}
@@ -1554,6 +1630,7 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
bool stat;
tree stmt;
stmt_vec_info stmt_info;
+ int vect_versioning_for_alias_required;
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "=== vect_enhance_data_refs_alignment ===");
@@ -1619,9 +1696,15 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
}
}
- /* Often peeling for alignment will require peeling for loop-bound, which in
- turn requires that we know how to adjust the loop ivs after the loop. */
- if (!vect_can_advance_ivs_p (loop_vinfo)
+ vect_versioning_for_alias_required =
+ (VEC_length (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo)) > 0);
+
+ /* Temporarily, if versioning for alias is required, we disable peeling
+ until we support peeling and versioning. Often peeling for alignment
+ will require peeling for loop-bound, which in turn requires that we
+ know how to adjust the loop ivs after the loop. */
+ if (vect_versioning_for_alias_required
+ || !vect_can_advance_ivs_p (loop_vinfo)
|| !slpeel_can_duplicate_loop_p (loop, single_exit (loop)))
do_peeling = false;
@@ -1749,7 +1832,7 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
if (known_alignment_for_access_p (dr)
|| VEC_length (tree,
LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo))
- >= (unsigned) PARAM_VALUE (PARAM_VECT_MAX_VERSION_CHECKS))
+ >= (unsigned) PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIGNMENT_CHECKS))
{
do_versioning = false;
break;