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
This commit is contained in:
parent
c94a75af08
commit
e3a8a4eda9
5 changed files with 141 additions and 33 deletions
|
@ -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.
|
||||
|
|
|
@ -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*.
|
||||
|
|
42
gcc/testsuite/gcc.dg/vect/vect-96.c
Normal file
42
gcc/testsuite/gcc.dg/vect/vect-96.c
Normal file
|
@ -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" } } */
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Add table
Reference in a new issue