diff options
author | victork <victork@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-08-16 14:20:39 +0000 |
---|---|---|
committer | victork <victork@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-08-16 14:20:39 +0000 |
commit | 45b13dc38650fb0f8deecf944c6837637927102e (patch) | |
tree | 03bccd8be0266f061712ef717618bb096e583eab /gcc/tree-vect-analyze.c | |
parent | 20f192724d96d2ca6fb12212edaf04de013b2678 (diff) | |
download | gcc-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.c | 105 |
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; |