diff options
author | Ira Rosen <irar@il.ibm.com> | 2005-02-12 11:47:19 +0000 |
---|---|---|
committer | Dorit Nuzman <dorit@gcc.gnu.org> | 2005-02-12 11:47:19 +0000 |
commit | e3a8a4eda9b1b2eb6a47f9156830f6fbc70ea794 (patch) | |
tree | 3e01db65e62fe15304ec53e6e8999fbfbd328c54 /gcc | |
parent | c94a75af08ce77997d7566d5fcca097ca177a97f (diff) | |
download | gcc-e3a8a4eda9b1b2eb6a47f9156830f6fbc70ea794.zip gcc-e3a8a4eda9b1b2eb6a47f9156830f6fbc70ea794.tar.gz gcc-e3a8a4eda9b1b2eb6a47f9156830f6fbc70ea794.tar.bz2 |
tree-data-ref.c (array_base_name_differ_p): Check that the bases exist and are objects.
* tree-data-ref.c (array_base_name_differ_p): Check that the bases
exist and are objects. Remove checks for pointer.
* tree-vectorizer.c (vect_create_addr_base_for_vector_ref): Use
STMT_VINFO_VECT_DR_BASE_ADDRESS instead of DR_BASE_NAME.
(vect_create_data_ref_ptr): Likewise.
(vect_base_addr_differ_p): New function.
(vect_analyze_data_ref_dependence): Call vect_base_addr_differ_p.
(vect_analyze_pointer_ref_access): Add output parameter - ptr_init.
Don't set the DR_BASE_NAME field of data-ref.
(vect_get_memtag_and_dr): Use ptr_init instead of DR_BASE_NAME.
From-SVN: r94932
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/vect-96.c | 42 | ||||
-rw-r--r-- | gcc/tree-data-ref.c | 28 | ||||
-rw-r--r-- | gcc/tree-vectorizer.c | 85 |
5 files changed, 141 insertions, 33 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bfaa691..ceebb3a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2005-02-12 Ira Rosen <irar@il.ibm.com> + + * tree-data-ref.c (array_base_name_differ_p): Check that the bases + exist and are objects. Remove checks for pointer. + * tree-vectorizer.c (vect_create_addr_base_for_vector_ref): Use + STMT_VINFO_VECT_DR_BASE_ADDRESS instead of DR_BASE_NAME. + (vect_create_data_ref_ptr): Likewise. + (vect_base_addr_differ_p): New function. + (vect_analyze_data_ref_dependence): Call vect_base_addr_differ_p. + (vect_analyze_pointer_ref_access): Add output parameter - ptr_init. + Don't set the DR_BASE_NAME field of data-ref. + (vect_get_memtag_and_dr): Use ptr_init instead of DR_BASE_NAME. + 2005-02-12 Uros Bizjak <uros@kss-loka.si> * optabs.h (enum optab_index): Add new OTI_ldexp. @@ -14,7 +27,7 @@ to implement ldexpf, ldexp and ldexpl built-ins as inline x87 intrinsics. -2005-02-13 Ira Rosen <irar@il.ibm.com> +2005-02-12 Ira Rosen <irar@il.ibm.com> * tree-vectorizer.h (struct _stmt_vec_info): Rename a field: base to base_address. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 408e128..7f518d0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2005-02-12 Ira Rosen <irar@il.ibm.com> + + * gcc.dg/vect/vect-96.c: New test. + 2005-02-12 Uros Bizjak <uros@kss-loka.si> * gcc.dg/builtins-34.c: Also check ldexp*. diff --git a/gcc/testsuite/gcc.dg/vect/vect-96.c b/gcc/testsuite/gcc.dg/vect/vect-96.c new file mode 100644 index 0000000..c296060 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-96.c @@ -0,0 +1,42 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +struct tmp +{ + int x; + int ia[N]; +}; + +int main1 (int off) +{ + struct tmp sb[N]; + struct tmp *pp = &sb[off]; + int i, ib[N]; + + for (i = 0; i < N; i++) + pp->ia[i] = ib[i]; + + /* check results: */ + for (i = 0; i < N; i++) + { + if (pp->ia[i] = ib[i]) + abort(); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (8); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" } } */ diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c index c6ca753..55b34fb 100644 --- a/gcc/tree-data-ref.c +++ b/gcc/tree-data-ref.c @@ -109,9 +109,15 @@ array_base_name_differ_p (struct data_reference *a, { tree base_a = DR_BASE_NAME (a); tree base_b = DR_BASE_NAME (b); - tree ta = TREE_TYPE (base_a); - tree tb = TREE_TYPE (base_b); + tree ta, tb; + if (!base_a || !base_b) + return false; + + ta = TREE_TYPE (base_a); + tb = TREE_TYPE (base_b); + + gcc_assert (!POINTER_TYPE_P (ta) && !POINTER_TYPE_P (tb)); /* Determine if same base. Example: for the array accesses a[i], b[i] or pointer accesses *a, *b, bases are a, b. */ @@ -179,24 +185,6 @@ array_base_name_differ_p (struct data_reference *a, return true; } - if (!alias_sets_conflict_p (get_alias_set (base_a), get_alias_set (base_b))) - { - *differ_p = true; - return true; - } - - /* An instruction writing through a restricted pointer is - "independent" of any instruction reading or writing through a - different pointer, in the same block/scope. */ - if ((TREE_CODE (ta) == POINTER_TYPE && TYPE_RESTRICT (ta) - && !DR_IS_READ(a)) - || (TREE_CODE (tb) == POINTER_TYPE && TYPE_RESTRICT (tb) - && !DR_IS_READ(b))) - { - *differ_p = true; - return true; - } - return false; } diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c index f18d0bb..72fec3f 100644 --- a/gcc/tree-vectorizer.c +++ b/gcc/tree-vectorizer.c @@ -223,19 +223,20 @@ static bool vect_compute_data_ref_alignment (struct data_reference *); static bool vect_analyze_data_ref_access (struct data_reference *); static bool vect_can_force_dr_alignment_p (tree, unsigned int); static struct data_reference * vect_analyze_pointer_ref_access - (tree, tree, bool); + (tree, tree, bool, tree*); static bool vect_can_advance_ivs_p (loop_vec_info); static tree vect_get_base_and_offset (struct data_reference *, tree, tree, loop_vec_info, tree *, tree *, tree *, bool*); -static struct data_reference * vect_analyze_pointer_ref_access - (tree, tree, bool); static tree vect_get_ptr_offset (tree, tree, tree *); static tree vect_get_memtag_and_dr (tree, tree, bool, loop_vec_info, tree, struct data_reference **); static bool vect_analyze_offset_expr (tree, struct loop *, tree, tree *, tree *, tree *); static tree vect_strip_conversion (tree); +static bool vect_base_addr_differ_p (struct data_reference *, + struct data_reference *drb, bool *); + /* Utility functions for the code transformation. */ static tree vect_create_destination_var (tree, tree); @@ -1962,7 +1963,7 @@ vect_create_addr_base_for_vector_ref (tree stmt, struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info); tree data_ref_base = unshare_expr (STMT_VINFO_VECT_DR_BASE_ADDRESS (stmt_info)); - tree base_name = unshare_expr (DR_BASE_NAME (dr)); + tree base_name = build_fold_indirect_ref (data_ref_base); tree ref = DR_REF (dr); tree scalar_type = TREE_TYPE (ref); tree scalar_ptr_type = build_pointer_type (scalar_type); @@ -2132,7 +2133,6 @@ vect_create_data_ref_ptr (tree stmt, block_stmt_iterator *bsi, tree offset, { tree base_name; stmt_vec_info stmt_info = vinfo_for_stmt (stmt); - struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info); loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info); struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo); tree vectype = STMT_VINFO_VECTYPE (stmt_info); @@ -2156,7 +2156,9 @@ vect_create_data_ref_ptr (tree stmt, block_stmt_iterator *bsi, tree offset, tree data_ref_ptr; tree type, tmp, size; - base_name = unshare_expr (DR_BASE_NAME (dr)); + base_name = build_fold_indirect_ref (unshare_expr ( + STMT_VINFO_VECT_DR_BASE_ADDRESS (stmt_info))); + if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC)) { tree data_ref_base = base_name; @@ -4089,6 +4091,61 @@ vect_analyze_scalar_cycles (loop_vec_info loop_vinfo) } +/* Function vect_base_addr_differ_p. + + This is the simplest data dependence test: determines whether the + data references A and B access the same array/region. Returns + false when the property is not computable at compile time. + Otherwise return true, and DIFFER_P will record the result. This + utility will not be necessary when alias_sets_conflict_p will be + less conservative. */ + + +static bool +vect_base_addr_differ_p (struct data_reference *dra, + struct data_reference *drb, + bool *differ_p) +{ + tree stmt_a = DR_STMT (dra); + stmt_vec_info stmt_info_a = vinfo_for_stmt (stmt_a); + tree stmt_b = DR_STMT (drb); + stmt_vec_info stmt_info_b = vinfo_for_stmt (stmt_b); + tree addr_a = STMT_VINFO_VECT_DR_BASE_ADDRESS (stmt_info_a); + tree addr_b = STMT_VINFO_VECT_DR_BASE_ADDRESS (stmt_info_b); + tree type_a = TREE_TYPE (addr_a); + tree type_b = TREE_TYPE (addr_b); + HOST_WIDE_INT alias_set_a, alias_set_b; + + gcc_assert (POINTER_TYPE_P (type_a) && POINTER_TYPE_P (type_b)); + + /* Both references are ADDR_EXPR, i.e., we have the objects. */ + if (TREE_CODE (addr_a) == ADDR_EXPR && TREE_CODE (addr_b) == ADDR_EXPR) + return array_base_name_differ_p (dra, drb, differ_p); + + alias_set_a = (TREE_CODE (addr_a) == ADDR_EXPR) ? + get_alias_set (TREE_OPERAND (addr_a, 0)) : get_alias_set (addr_a); + alias_set_b = (TREE_CODE (addr_b) == ADDR_EXPR) ? + get_alias_set (TREE_OPERAND (addr_b, 0)) : get_alias_set (addr_b); + + if (!alias_sets_conflict_p (alias_set_a, alias_set_b)) + { + *differ_p = true; + return true; + } + + /* An instruction writing through a restricted pointer is "independent" of any + instruction reading or writing through a different pointer, in the same + block/scope. */ + else if ((TYPE_RESTRICT (type_a) && !DR_IS_READ (dra)) + || (TYPE_RESTRICT (type_b) && !DR_IS_READ (drb))) + { + *differ_p = true; + return true; + } + return false; +} + + /* Function vect_analyze_data_ref_dependence. Return TRUE if there (might) exist a dependence between a memory-reference @@ -4102,7 +4159,7 @@ vect_analyze_data_ref_dependence (struct data_reference *dra, bool differ_p; struct data_dependence_relation *ddr; - if (!array_base_name_differ_p (dra, drb, &differ_p)) + if (!vect_base_addr_differ_p (dra, drb, &differ_p)) { if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS, LOOP_LOC (loop_vinfo))) @@ -4660,7 +4717,8 @@ vect_analyze_data_ref_accesses (loop_vec_info loop_vinfo) that represents it (DR). Otherwise - return NULL. */ static struct data_reference * -vect_analyze_pointer_ref_access (tree memref, tree stmt, bool is_read) +vect_analyze_pointer_ref_access (tree memref, tree stmt, bool is_read, + tree *ptr_init) { stmt_vec_info stmt_info = vinfo_for_stmt (stmt); loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info); @@ -4758,7 +4816,8 @@ vect_analyze_pointer_ref_access (tree memref, tree stmt, bool is_read) fprintf (vect_dump, "Access function of ptr indx: "); print_generic_expr (vect_dump, indx_access_fn, TDF_SLIM); } - dr = init_data_ref (stmt, memref, init, indx_access_fn, is_read); + dr = init_data_ref (stmt, memref, NULL_TREE, indx_access_fn, is_read); + *ptr_init = init; return dr; } @@ -4806,6 +4865,7 @@ vect_get_memtag_and_dr (tree memref, tree stmt, bool is_read, tree ref_to_be_analyzed, tag, dr_base; struct data_reference *new_dr; bool base_aligned_p; + tree ptr_init; if (*dr) { @@ -4889,12 +4949,13 @@ vect_get_memtag_and_dr (tree memref, tree stmt, bool is_read, switch (TREE_CODE (memref)) { case INDIRECT_REF: - new_dr = vect_analyze_pointer_ref_access (memref, stmt, is_read); + new_dr = vect_analyze_pointer_ref_access (memref, stmt, is_read, + &ptr_init); if (!new_dr) return NULL_TREE; *dr = new_dr; - symbl = DR_BASE_NAME (new_dr); - ref_to_be_analyzed = DR_BASE_NAME (new_dr); + symbl = ptr_init; + ref_to_be_analyzed = ptr_init; break; case ARRAY_REF: |