tree-vect-analyze.c (vect_analyze_data_ref_dependence): DRs whose dependence-distance modulo VF is 0 are recorded in the...

* tree-vect-analyze.c (vect_analyze_data_ref_dependence): DRs whose
        dependence-distance modulo VF is 0 are recorded in the
        SAME_ALIGN_REFs VEC in each DR.
        (vect_enhance_data_refs_alignment): Avoid 80 column overflow. The
        alignment information of DRs that are in the SAME_ALIGN_REFs VEC of the
        DR we want to peel for, is set to 0.
        * tree-vect-transform.c (vect_do_peeling_for_loop_bound): Fix printout.
        * tree-vectorizer.c (destroy_loop_vec_info): Free the SAME_ALIGN_REFs
        VEC.
        * tree-vectorizer.h (dr_p): New type. Defined to use the VEC API.
        (_stmt_vec_info): Added new field same_align_refs.
        (STMT_VINFO_SAME_ALIGN_REFS): New macro.

From-SVN: r100817
This commit is contained in:
Dorit Nuzman 2005-06-10 14:52:01 +00:00 committed by Dorit Nuzman
parent cdd5a1bebe
commit bb74832900
10 changed files with 146 additions and 17 deletions

View File

@ -1,3 +1,18 @@
2005-06-10 Dorit Nuzman <dorit@il.ibm.com>
* tree-vect-analyze.c (vect_analyze_data_ref_dependence): DRs whose
dependence-distance modulo VF is 0 are recorded in the
SAME_ALIGN_REFs VEC in each DR.
(vect_enhance_data_refs_alignment): Avoid 80 column overflow. The
alignment information of DRs that are in the SAME_ALIGN_REFs VEC of the
DR we want to peel for, is set to 0.
* tree-vect-transform.c (vect_do_peeling_for_loop_bound): Fix printout.
* tree-vectorizer.c (destroy_loop_vec_info): Free the SAME_ALIGN_REFs
VEC.
* tree-vectorizer.h (dr_p): New type. Defined to use the VEC API.
(_stmt_vec_info): Added new field same_align_refs.
(STMT_VINFO_SAME_ALIGN_REFS): New macro.
2005-06-10 Nathan Sidwell <nathan@codesourcery.com>
* vec.h (VEC_safe_grow): Append MEM_STAT_INFO.

View File

@ -1,3 +1,14 @@
2005-06-10 Dorit Nuzman <dorit@il.ibm.com>
* gfortran.dg/vect/vect-4.f90: Update comments. Only one unaligned
access will be generated when this loop is vectorized. Test that
accesses with same alignment were detected.
* gcc.dg/vect/vect-dv-2.c: Remove "vect_no_align" from xfail.
Test that accesses with same alignment were detected.
* gcc.dg/vect/vect-ifcvt-1.c: Likewise.
* gcc.dg/vect/vect-91.c: New test. Test that accesses with same
alignment were detected.
2005-06-09 Gabriel Dos Reis <gdr@integrable-solutions.net>
* gcc.dg/Wcxx-compat-1.c: New.

View File

@ -0,0 +1,70 @@
/* { dg-do compile } */
/* { dg-require-effective-target vect_int } */
#include <stdarg.h>
#include "tree-vect.h"
#define N 256
extern int a[N];
/* The alignment of 'pa' is unknown.
Yet we do know that both the read access and write access have
the same alignment. Peeling to align one of the accesses will
align the other.
Not vectorized yet due to problems in dataref analysis that
are fixed in autovect-branch but not yet in mainline. */
int
main1 (int * pa)
{
int i;
for (i = 0; i < N; i++)
{
pa[i] = pa[i] + 1;
}
return 0;
}
/* The alignment of 'a' is unknown.
Yet we do know that both the read access and write access have
the same alignment. Peeling to align one of the accesses will
align the other. */
int
main2 ()
{
int i;
for (i = 0; i < N; i++)
{
a[i] = a[i] + 1;
}
return 0;
}
int
main3 ()
{
int i;
for (i = 0; i < N; i++)
{
a[i] = a[i+20];
}
return 0;
}
/* Currently only the loops in main2 and main3 get vectorized. After the merge
of the datarefs-analysis cleanups from autovect-branch to mainline, the loop
in main1 will also be vectorized. */
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" } } */
/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
/* { dg-final { scan-tree-dump-times "accesses have the same alignment." 2 "vect" } } */
/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" } } */
/* { dg-final { cleanup-tree-dump "vect" } } */

View File

@ -69,5 +69,6 @@ int main ()
/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { xfail vect_no_align } } } */
/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" } } */
/* { dg-final { scan-tree-dump-times "accesses have the same alignment." 2 "vect" } } */
/* { dg-final { cleanup-tree-dump "vect" } } */

View File

@ -70,5 +70,6 @@ int main ()
/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { xfail vect_no_align } } } */
/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" } } */
/* { dg-final { scan-tree-dump-times "accesses have the same alignment." 2 "vect" } } */
/* { dg-final { cleanup-tree-dump "vect" } } */

View File

@ -1,14 +1,18 @@
! { dg-do compile }
! { dg-require-effective-target vect_float }
! Peeling to align the store to Y will also align the load from Y.
! The load from X may still be misaligned.
SUBROUTINE SAXPY(X, Y, A)
DIMENSION X(64), Y(64)
Y = Y + A * X
END
! fail to vectorize until the patch that ignores dependence-distance 0 is
! brought from autovect.
! fail to vectorize due to aliasing problems in dataref analysis that are
! solved in autvect-branch but not yet in mainline.
! { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } }
! { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail *-*-* } } }
! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail *-*-* } } }
! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail *-*-* } } }
! { dg-final { scan-tree-dump-times "accesses have the same alignment." 1 "vect" { xfail *-*-* } } }
! { dg-final { cleanup-tree-dump "vect" } }

View File

@ -853,7 +853,8 @@ vect_analyze_data_ref_dependence (struct data_reference *dra,
int dist = 0;
unsigned int loop_depth = 0;
struct loop *loop_nest = loop;
stmt_vec_info stmtinfo_a = vinfo_for_stmt (DR_STMT (dra));
stmt_vec_info stmtinfo_b = vinfo_for_stmt (DR_STMT (drb));
if (!vect_base_addr_differ_p (dra, drb, &differ_p))
{
@ -924,10 +925,13 @@ vect_analyze_data_ref_dependence (struct data_reference *dra,
dist = DDR_DIST_VECT (ddr)[loop_depth];
/* Same loop iteration. */
if (dist == 0)
if (dist % vectorization_factor == 0)
{
if (vect_print_dump_info (REPORT_DETAILS, LOOP_LOC (loop_vinfo)))
fprintf (vect_dump, "dependence distance 0.");
/* Two references with distance zero have the same alignment. */
VEC_safe_push (dr_p, heap, STMT_VINFO_SAME_ALIGN_REFS (stmtinfo_a), drb);
VEC_safe_push (dr_p, heap, STMT_VINFO_SAME_ALIGN_REFS (stmtinfo_b), dra);
if (vect_print_dump_info (REPORT_ALIGNMENT, LOOP_LOC (loop_vinfo)))
fprintf (vect_dump, "accesses have the same alignment.");
return false;
}
@ -1146,7 +1150,9 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
varray_type loop_read_datarefs = LOOP_VINFO_DATAREF_READS (loop_vinfo);
varray_type loop_write_datarefs = LOOP_VINFO_DATAREF_WRITES (loop_vinfo);
varray_type datarefs;
VEC(dr_p,heap) *same_align_drs;
struct data_reference *dr0 = NULL;
struct data_reference *dr;
unsigned int i, j;
/*
@ -1300,7 +1306,8 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
else if (known_alignment_for_access_p (dr)
&& known_alignment_for_access_p (dr0))
{
int drsize = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (dr))));
int drsize =
GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (dr))));
DR_MISALIGNMENT (dr) += npeel * drsize;
DR_MISALIGNMENT (dr) %= UNITS_PER_SIMD_WORD;
@ -1311,6 +1318,13 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
datarefs = loop_read_datarefs;
}
same_align_drs =
STMT_VINFO_SAME_ALIGN_REFS (vinfo_for_stmt (DR_STMT (dr0)));
for (i = 0; VEC_iterate (dr_p, same_align_drs, i, dr); i++)
{
DR_MISALIGNMENT (dr) = 0;
}
DR_MISALIGNMENT (dr0) = 0;
}
}

View File

@ -962,9 +962,9 @@ vectorizable_store (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
{
SSA_NAME_DEF_STMT (def) = *vec_stmt;
/* If this virtual def has a use outside the loop and a loop peel is performed
then the def may be renamed by the peel. Mark it for renaming so the
later use will also be renamed. */
/* If this virtual def has a use outside the loop and a loop peel is
performed then the def may be renamed by the peel. Mark it for
renaming so the later use will also be renamed. */
mark_sym_for_renaming (SSA_NAME_VAR (def));
}
@ -1776,7 +1776,7 @@ vect_do_peeling_for_loop_bound (loop_vec_info loop_vinfo, tree *ratio,
#endif
if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
fprintf (vect_dump, "=== vect_transtorm_for_unknown_loop_bound ===");
fprintf (vect_dump, "=== vect_do_peeling_for_loop_bound ===");
/* Generate the following variables on the preheader of original loop:

View File

@ -1457,10 +1457,14 @@ destroy_loop_vec_info (loop_vec_info loop_vinfo)
{
tree stmt = bsi_stmt (si);
stmt_ann_t ann = stmt_ann (stmt);
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
free (stmt_info);
set_stmt_info ((tree_ann_t)ann, NULL);
if (stmt_info)
{
VEC_free (dr_p, heap, STMT_VINFO_SAME_ALIGN_REFS (stmt_info));
free (stmt_info);
set_stmt_info ((tree_ann_t)ann, NULL);
}
}
}

View File

@ -158,6 +158,10 @@ enum stmt_vec_info_type {
condition_vec_info_type
};
typedef struct data_reference *dr_p;
DEF_VEC_P(dr_p);
DEF_VEC_ALLOC_P(dr_p,heap);
typedef struct _stmt_vec_info {
enum stmt_vec_info_type type;
@ -230,6 +234,10 @@ typedef struct _stmt_vec_info {
in bytes. */
tree misalignment;
/* List of datarefs that are known to have the same alignment as the dataref
of this stmt. */
VEC(dr_p,heap) *same_align_refs;
/* Classify the def of this stmt. */
enum vect_def_type def_type;
@ -252,6 +260,7 @@ typedef struct _stmt_vec_info {
#define STMT_VINFO_VECT_STEP(S) (S)->step
#define STMT_VINFO_VECT_BASE_ALIGNED_P(S) (S)->base_aligned_p
#define STMT_VINFO_VECT_MISALIGNMENT(S) (S)->misalignment
#define STMT_VINFO_SAME_ALIGN_REFS(S) (S)->same_align_refs
#define STMT_VINFO_DEF_TYPE(S) (S)->def_type
static inline void set_stmt_info (tree_ann_t ann, stmt_vec_info stmt_info);