Commit 86a07404 by Ira Rosen Committed by Ira Rosen

expr.c (highest_pow2_factor): Make extern.

        * expr.c (highest_pow2_factor): Make extern.
        * tree-data-ref.c (ptr_decl_may_alias_p): New function.
        (ptr_ptr_may_alias_p, may_alias_p, record_ptr_differ_p,
        record_array_differ_p, array_ptr_differ_p): Likewise.
        (base_object_differ_p): Rename (from array_base_name_differ_p). Support
        additional cases. Call the above functions.
        (base_addr_differ_p): Moved from tree-vect-analyze.c. Call
        base_object_differ_p when there are two base objects. Otherwise, compare
        base address and offset. Call may_alias_p.
        (dump_data_reference): Use a correct field name.
        (analyze_array): Make static. Initialize new data-ref fields.
        (analyze_indirect_ref): New function.
        (init_data_ref): Initialize new data-ref fields.
        (strip_conversion): Moved from tree-vect-analyze.c.
        (analyze_offset_expr, get_ptr_offset, address_analysis, object_analysis):
        Likewise.
        (analyze_offset): New function.
        (create_data_ref): Likewise.
        (initialize_data_dependence_relation): Call base_addr_differ_p. Compare
        dimensions for ARRAY_REFs only.
        (build_classic_dist_vector): Make static.
        (access_functions_are_affine_or_constant_p): Call macro to get the
        address of access functions.
        (compute_all_dependences): Add new parameter
        compute_self_and_read_read_dependences. Compute self and read-read
        dependences if it is true.
        (find_data_references_in_loop): Call create_data_ref. Initialize new
        data-ref fields.
        (compute_data_dependences_for_loop): Add new parameter
        compute_self_and_read_read_dependences. Remove parameter nb_loops,
        compute nb_loops. Call compute_all_dependences, build_classic_dist_vector
        and build_classic_dir_vector with correct parameters.
        (analyze_all_data_dependences): Call compute_data_dependences_for_loop with
        correct parameters. Compare dimensions for ARRAY_REFs only.
        (free_data_refs): Call macro to free access functions.
        * tree-data-ref.h (struct first_location_in_loop): New structure. Move
        fields from stmt_vinfo.
        (struct base_object_info): New structure.
        (struct data_reference): Move fields to base_object_info. Add fields
        first_location and object_info for above structures. Move fields from
        stmt_info: memtag, ptr_info, subvars, misalignment. Add new field aligned_to.
        Add macros to access the new fields.
        Update functions declarations.
        * tree-flow.h (is_aliased_with): Declare.
        * tree-loop-linear.c (linear_transform_loops): Call
        compute_data_dependences_for_loop with correct parameters.
        * tree-ssa-alias.c (is_aliased_with): New function.
        * tree-vect-analyze.c (vect_get_ptr_offset): Remove.
        (vect_analyze_offset_expr, vect_base_addr_differ_p): Likewise.
        (vect_analyze_data_ref_dependence): Get ddr. Remove call to
        vect_base_addr_differ_p, compute_subscript_distance and
        build_classic_dist_vector. Add printings. Check absolute value of
        distance.
        (vect_analyze_data_ref_dependences): Go through ddrs instead of data-refs.
        (vect_compute_data_ref_alignment): Get the fields of data-ref instead of
        stmt. Check aligned_to. Check if the base is aligned. Remove conversion
        to bytes. Add printing.
        (vect_compute_data_refs_alignment): Go through loads and stores in one loop.
        (vect_enhance_data_refs_alignment, vect_analyze_data_refs_alignment,
        vect_analyze_data_ref_access): Likewise.
        (vect_analyze_pointer_ref_access): Remove.
        (vect_address_analysis, vect_object_analysis): Likewise.
        (vect_analyze_data_refs): Call compute_data_dependences_for_loop to find
        and analyze data-refs in the loop.
        * tree-vect-transform.c (vect_create_addr_base_for_vector_ref): Get the
        fields of data-ref instead of stmt. Add init to the offset from the base.
        (vect_create_data_ref_ptr): Get the fields of data-ref instead of stmt.
        (vect_update_init_of_dr): Likewise.
        (vect_update_inits_of_drs): Go through loads and stores in one loop.
        * tree-vectorizer.c (new_stmt_vec_info): Remove initialization of removed
        fields.
        (new_loop_vec_info): Initialize new fields.
        (destroy_loop_vec_info): Free new fields.
        (vect_strip_conversion): Remove.
        * tree-vectorizer.h (enum verbosity_levels): Add new verbosity level.
        (struct _loop_vec_info): Unify data_ref_writes and data_ref_reads into
        datarefs. Add new field ddrs.
        Add macros for the new fields access.
        (struct _stmt_vec_info): Remove: base_address, initial_offset, step,
        base_aligned_p, misalignment, memtag, ptr_info and subvars.
        Remove their macros.
        * tree.h (highest_pow2_factor): Declare.

From-SVN: r102356
parent 4fdfb204
2005-07-25 Ira Rosen <irar@il.ibm.com>
* expr.c (highest_pow2_factor): Make extern.
* tree-data-ref.c (ptr_decl_may_alias_p): New function.
(ptr_ptr_may_alias_p, may_alias_p, record_ptr_differ_p,
record_array_differ_p, array_ptr_differ_p): Likewise.
(base_object_differ_p): Rename (from array_base_name_differ_p). Support
additional cases. Call the above functions.
(base_addr_differ_p): Moved from tree-vect-analyze.c. Call
base_object_differ_p when there are two base objects. Otherwise, compare
base address and offset. Call may_alias_p.
(dump_data_reference): Use a correct field name.
(analyze_array): Make static. Initialize new data-ref fields.
(analyze_indirect_ref): New function.
(init_data_ref): Initialize new data-ref fields.
(strip_conversion): Moved from tree-vect-analyze.c.
(analyze_offset_expr, get_ptr_offset, address_analysis, object_analysis):
Likewise.
(analyze_offset): New function.
(create_data_ref): Likewise.
(initialize_data_dependence_relation): Call base_addr_differ_p. Compare
dimensions for ARRAY_REFs only.
(build_classic_dist_vector): Make static.
(access_functions_are_affine_or_constant_p): Call macro to get the
address of access functions.
(compute_all_dependences): Add new parameter
compute_self_and_read_read_dependences. Compute self and read-read
dependences if it is true.
(find_data_references_in_loop): Call create_data_ref. Initialize new
data-ref fields.
(compute_data_dependences_for_loop): Add new parameter
compute_self_and_read_read_dependences. Remove parameter nb_loops,
compute nb_loops. Call compute_all_dependences, build_classic_dist_vector
and build_classic_dir_vector with correct parameters.
(analyze_all_data_dependences): Call compute_data_dependences_for_loop with
correct parameters. Compare dimensions for ARRAY_REFs only.
(free_data_refs): Call macro to free access functions.
* tree-data-ref.h (struct first_location_in_loop): New structure. Move
fields from stmt_vinfo.
(struct base_object_info): New structure.
(struct data_reference): Move fields to base_object_info. Add fields
first_location and object_info for above structures. Move fields from
stmt_info: memtag, ptr_info, subvars, misalignment. Add new field aligned_to.
Add macros to access the new fields.
Update functions declarations.
* tree-flow.h (is_aliased_with): Declare.
* tree-loop-linear.c (linear_transform_loops): Call
compute_data_dependences_for_loop with correct parameters.
* tree-ssa-alias.c (is_aliased_with): New function.
* tree-vect-analyze.c (vect_get_ptr_offset): Remove.
(vect_analyze_offset_expr, vect_base_addr_differ_p): Likewise.
(vect_analyze_data_ref_dependence): Get ddr. Remove call to
vect_base_addr_differ_p, compute_subscript_distance and
build_classic_dist_vector. Add printings. Check absolute value of
distance.
(vect_analyze_data_ref_dependences): Go through ddrs instead of data-refs.
(vect_compute_data_ref_alignment): Get the fields of data-ref instead of
stmt. Check aligned_to. Check if the base is aligned. Remove conversion
to bytes. Add printing.
(vect_compute_data_refs_alignment): Go through loads and stores in one loop.
(vect_enhance_data_refs_alignment, vect_analyze_data_refs_alignment,
vect_analyze_data_ref_access): Likewise.
(vect_analyze_pointer_ref_access): Remove.
(vect_address_analysis, vect_object_analysis): Likewise.
(vect_analyze_data_refs): Call compute_data_dependences_for_loop to find
and analyze data-refs in the loop.
* tree-vect-transform.c (vect_create_addr_base_for_vector_ref): Get the
fields of data-ref instead of stmt. Add init to the offset from the base.
(vect_create_data_ref_ptr): Get the fields of data-ref instead of stmt.
(vect_update_init_of_dr): Likewise.
(vect_update_inits_of_drs): Go through loads and stores in one loop.
* tree-vectorizer.c (new_stmt_vec_info): Remove initialization of removed
fields.
(new_loop_vec_info): Initialize new fields.
(destroy_loop_vec_info): Free new fields.
(vect_strip_conversion): Remove.
* tree-vectorizer.h (enum verbosity_levels): Add new verbosity level.
(struct _loop_vec_info): Unify data_ref_writes and data_ref_reads into
datarefs. Add new field ddrs.
Add macros for the new fields access.
(struct _stmt_vec_info): Remove: base_address, initial_offset, step,
base_aligned_p, misalignment, memtag, ptr_info and subvars.
Remove their macros.
* tree.h (highest_pow2_factor): Declare.
2005-07-25 Jakub Jelinek <jakub@redhat.com>
* calls.c (store_one_arg): Check for sibling call MEM arguments
......
......@@ -145,7 +145,6 @@ static void store_constructor (tree, rtx, int, HOST_WIDE_INT);
static rtx store_field (rtx, HOST_WIDE_INT, HOST_WIDE_INT, enum machine_mode,
tree, tree, int);
static unsigned HOST_WIDE_INT highest_pow2_factor (tree);
static unsigned HOST_WIDE_INT highest_pow2_factor_for_target (tree, tree);
static int is_aligning_offset (tree, tree);
......@@ -6047,7 +6046,7 @@ safe_from_p (rtx x, tree exp, int top_p)
/* Return the highest power of two that EXP is known to be a multiple of.
This is used in updating alignment of MEMs in array references. */
static unsigned HOST_WIDE_INT
unsigned HOST_WIDE_INT
highest_pow2_factor (tree exp)
{
unsigned HOST_WIDE_INT c0, c1;
......
2005-07-25 Ira Rosen <irar@il.ibm.com>
* gcc.dg/vect/vect.exp: Change verbosity level to 4.
* gfortran.dg/vect/vect.exp, g++.dg/vect/vect.exp: Likewise.
* gcc.dg/vect/pr20122.c: Add vectorizable version of the loop.
* gcc.dg/vect/vect-100.c: New test.
* gcc.dg/vect/vect-101.c, gcc.dg/vect/vect-102.c,
gcc.dg/vect/vect-103.c, gcc.dg/vect/vect-104.c,
gcc.dg/vect/vect-105.c, gcc.dg/vect/vect-115.c: Likewise.
* gcc.dg/vect/vect-116.c: Renamed (from vect-100.c).
* gcc.dg/vect/vect-43.c: Add vectorizable version of the loop.
* gcc.dg/vect/vect-91.c: Now 3 loops are vectorizable.
* gfortran.dg/vect/vect-4.f90: Now vectorizable.
* gfortran.dg/vect/pr19049.f90: New testcase.
* g++.dg/vect/pr21218.cc, gcc.dg/tree-ssa/ltrans-8.c: Likewise.
2005-07-25 Jakub Jelinek <jakub@redhat.com>
* gcc.c-torture/execute/20050713-1.c: New test.
......
/* { dg-do compile } */
struct A
{
double d[2];
double foo(int i) { return d[i]; }
};
struct B : public A {};
void bar(B& b)
{
for (int i=0; i<2; ++i)
b.d[i] = b.foo(i);
}
/* { dg-final { cleanup-tree-dump "vect" } } */
......@@ -40,7 +40,7 @@ set DEFAULT_VECTCFLAGS ""
# These flags are used for all targets.
lappend DEFAULT_VECTCFLAGS "-O2" "-ftree-vectorize" \
"-ftree-vectorizer-verbose=3" "-fdump-tree-vect-stats"
"-ftree-vectorizer-verbose=4" "-fdump-tree-vect-stats"
# Skip these tests for targets that do not support generating vector
# code. Set additional target-dependent vector flags, which can be
......
/* { dg-do compile } */
/* { dg-options "-O2 -ftree-loop-linear -fdump-tree-ltrans-all" } */
double foo(double *a)
{
int i,j;
double r = 0.0;
for (i=0; i<8; ++i)
for (j=0; j<8; ++j)
r += a[j*8+i];
return r;
}
/* { dg-final { scan-tree-dump-times "transformed loop" 1 "ltrans"} } */
......@@ -7,8 +7,10 @@ typedef short ashort __attribute__ ((__aligned__(16)));
ashort Kernshort[24];
static void VecBug(ashort Kernel[8][24]) __attribute__((noinline));
static void VecBug(ashort Kernel[8][24]);
static void VecBug2(ashort Kernel[8][24]) __attribute__((noinline));
static void VecBug2(ashort Kernel[8][24]);
/* Doesn't occur of only inner-loop. */
/* Not vectorizable: Kernel may alias Kernshort - a global array. */
static void VecBug(ashort Kernel[8][24])
{
int k,i;
......@@ -17,6 +19,21 @@ static void VecBug(ashort Kernel[8][24])
Kernshort[i] = Kernel[k][i];
}
/* Vectorizable: Kernshort2 is local. */
static void VecBug2(ashort Kernel[8][24])
{
int k,i;
ashort Kernshort2[24];
for (k = 0; k<8; k++)
for (i = 0; i<24; i++)
Kernshort2[i] = Kernel[k][i];
for (k = 0; k<8; k++)
for (i = 0; i<24; i++)
if (Kernshort2[i] != Kernel[k][i])
abort ();
}
int main (int argc, char **argv)
{
check_vect ();
......@@ -29,6 +46,7 @@ int main (int argc, char **argv)
Kernel[k][i] = 0;
VecBug(Kernel);
VecBug2(Kernel);
return 0;
}
......
/* Assuming we can vectorize char multiplication, here's an execute test. */
/* { dg-require-effective-target vect_int } */
#include <stdlib.h>
#include <stdarg.h>
#include "tree-vect.h"
extern void abort (void);
void foo()
#define N 9
struct extraction
{
static unsigned char A[256], B[256], C[256];
int a[N];
int b[N];
};
static int a[N] = {1,2,3,4,5,6,7,8,9};
static int b[N] = {2,3,4,5,6,7,8,9,0};
int main1 () {
int i;
struct extraction *p;
p = (struct extraction *) malloc (sizeof (struct extraction));
/* Not vectorizable: p may alias a and/or b, since they are globals. */
for (i = 0; i < N; i++)
{
p->a[i] = a[i];
p->b[i] = b[i];
}
/* check results: */
for (i = 0; i < N; i++)
{
if (p->a[i] != a[i] || p->b[i] != b[i])
abort();
}
return 0;
}
int main2 () {
int i;
int c[N] = {1,2,3,4,5,6,7,8,9};
int d[N] = {2,3,4,5,6,7,8,9,0};
struct extraction *p;
p = (struct extraction *) malloc (sizeof (struct extraction));
for (i = 0; i < 256; ++i)
A[i] = B[i] = i;
/* Vectorizable: c and d are local arrays. */
for (i = 0; i < N; i++)
{
p->a[i] = c[i];
p->b[i] = d[i];
}
for (i = 0; i < 256; ++i)
C[i] = A[i] * B[i];
/* check results: */
for (i = 0; i < N; i++)
{
if (p->a[i] != c[i] || p->b[i] != d[i])
abort();
}
for (i = 0; i < 256; ++i)
if (C[i] != (unsigned char)(i * i))
abort ();
return 0;
}
int main()
int main (void)
{
check_vect ();
foo();
main1 ();
main2 ();
return 0;
}
/* Requires versioning. */
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
/* { dg-require-effective-target vect_int } */
#include <stdlib.h>
#include <stdarg.h>
#include "tree-vect.h"
#define N 9
struct extraction
{
int a[N];
int b[N];
};
static int a[N] = {1,2,3,4,5,6,7,8,9};
static int b[N] = {2,3,4,5,6,7,8,9,0};
int main1 (int x, int y) {
int i;
struct extraction *p;
p = (struct extraction *) malloc (sizeof (struct extraction));
/* Not vectorizable: different unknown offset. */
for (i = 0; i < N; i++)
{
*((int *)p + x + i) = a[i];
*((int *)p + y + i) = b[i];
}
/* check results: */
for (i = 0; i < N; i++)
{
if (p->a[i] != a[i] || p->b[i] != b[i])
abort();
}
return 0;
}
int main (void)
{
check_vect ();
return main1 (0, N);
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" } } */
/* { dg-final { scan-tree-dump-times "can't determine dependence" 1 "vect" } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
/* { dg-require-effective-target vect_int } */
#include <stdlib.h>
#include <stdarg.h>
#include "tree-vect.h"
#define N 9
struct extraction
{
int a[N];
int b[N];
};
static int a[N] = {1,2,3,4,5,6,7,8,9};
static int b[N] = {2,3,4,5,6,7,8,9,9};
int main1 (int x, int y) {
int i;
struct extraction *p;
p = (struct extraction *) malloc (sizeof (struct extraction));
for (i = 0; i < N; i++)
{
p->a[i] = a[i];
if (x == 135)
abort (); /* to avoid vectorization */
}
/* Not vectorizable: distance 1. */
for (i = 0; i < N - 1; i++)
{
*((int *)p + x + i) = *((int *)p + x + i + 1);
}
/* check results: */
for (i = 0; i < N; i++)
{
if (p->a[i] != b[i])
abort();
}
return 0;
}
int main (void)
{
check_vect ();
return main1 (0, N);
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" } } */
/* { dg-final { scan-tree-dump-times "possible dependence between data-refs" 1 "vect" } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
/* { dg-require-effective-target vect_int } */
#include <stdlib.h>
#include <stdarg.h>
#include "tree-vect.h"
#define N 9
struct extraction
{
int a[N];
int b[N];
};
static int a[N] = {1,2,3,4,5,6,7,8,9};
static int b[N] = {17,24,7,0,2,3,4,31,82};
static int c[N] = {9,17,24,7,0,2,3,4,31};
int main1 (int x, int y) {
int i;
struct extraction *p;
p = (struct extraction *) malloc (sizeof (struct extraction));
for (i = 0; i < N; i++)
{
p->a[i] = a[i];
p->b[i] = b[i];
if (x == 135)
abort (); /* to avoid vectorization */
}
/* Vectorizable: distance > VF. */
for (i = 0; i < N; i++)
{
*((int *)p + x + i) = *((int *)p + x + i + 8);
}
/* check results: */
for (i = 0; i < N; i++)
{
if (p->a[i] != c[i])
abort();
}
return 0;
}
int main (void)
{
check_vect ();
return main1 (0, N);
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
/* { dg-final { scan-tree-dump-times "dependence distance modulo vf == 0" 1 "vect" } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
/* { dg-require-effective-target vect_int } */
#include <stdlib.h>
#include <stdarg.h>
#include "tree-vect.h"
#define N 3
struct extraction
{
int a[N][N];
int b[N][N];
};
static int a[N][N] = {{1,2,3},{4,5,6},{7,8,9}};
static int b[N][N] = {{17,24,7},{0,2,3},{4,31,82}};
static int c[N][N] = {{1,2,3},{4,6,8},{8,9,9}};
int main1 (int x) {
int i,j;
struct extraction *p;
p = (struct extraction *) malloc (sizeof (struct extraction));
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
{
p->a[i][j] = a[i][j];
p->b[i][j] = b[i][j];
if (x == 135)
abort (); /* to avoid vectorization */
}
}
/* Not vectorizable: distance = 1. */
for (i = 1; i < N; i++)
{
for (j = 0; j < N; j++)
{
*((int *)p + x + i + j) = *((int *)p + x + i + j + 1);
}
}
/* check results: */
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
{
if (p->a[i][j] != c[i][j])
abort();
}
}
return 0;
}
int main (void)
{
check_vect ();
return main1 (N);
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" } } */
/* { dg-final { scan-tree-dump-times "possible dependence between data-refs" 1 "vect" } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
/* { dg-require-effective-target vect_int } */
#include <stdlib.h>
#include <stdarg.h>
#include "tree-vect.h"
#define N 4
struct extraction
{
int a[N][N];
int b[N][N];
};
static int a[N][N] = {{1,2,3,11},{4,5,6,12},{7,8,9,13},{34,45,67,83}};
static int b[N][N] = {{17,28,15,23},{0,2,3,24},{4,31,82,25},{29,31,432,256}};
static int c[N][N] = {{1,2,3,11},{4,9,13,34},{45,67,83,13},{34,45,67,83}};
int main1 (int x) {
int i,j;
struct extraction *p;
p = (struct extraction *) malloc (sizeof (struct extraction));
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
{
p->a[i][j] = a[i][j];
p->b[i][j] = b[i][j];
if (x == 135)
abort (); /* to avoid vectorization */
}
}
/* Vectorizable: distance > number of iterations. */
for (i = 1; i < N; i++)
{
for (j = 0; j < N; j++)
{
*((int *)p + x + i + j) = *((int *)p + x + i + j + 5);
}
}
/* check results: */
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
{
if (p->a[i][j] != c[i][j])
abort();
}
}
return 0;
}
int main (void)
{
check_vect ();
return main1 (N);
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
/* { dg-final { scan-tree-dump-times "possible dependence between data-refs" 0 "vect" } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
/* { dg-require-effective-target vect_int } */
#include <stdarg.h>
#include "tree-vect.h"
#define N 16
struct s{
int b[N];
int c[N];
int m;
};
struct t{
struct s strc_s;
int m;
};
struct test1{
struct t strc_t;
struct t *ptr_t;
int k;
int l;
};
int main1 ()
{
int i;
struct test1 tmp1;
int a[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
struct t tmp2;
tmp1.ptr_t = &tmp2;
/* DR bases comparison: record and array. */
for (i = 0; i < N; i++)
{
tmp1.strc_t.strc_s.b[i] = a[i];
}
/* Check results. */
for (i = 0; i < N; i++)
{
if (tmp1.strc_t.strc_s.b[i] != a[i])
abort();
}
/* DR bases comparison: record containing ptr and array. */
for (i = 0; i < N; i++)
{
tmp1.ptr_t->strc_s.c[i] = a[i];
}
/* Check results. */
for (i = 0; i < N; i++)
{
if (tmp1.ptr_t->strc_s.c[i] != a[i])
abort();
}
return 0;
}
int main (void)
{
check_vect ();
return main1 ();
}
/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
/* Assuming we can vectorize char multiplication, here's an execute test. */
#include <stdarg.h>
#include "tree-vect.h"
extern void abort (void);
void foo()
{
static unsigned char A[256], B[256], C[256];
int i;
for (i = 0; i < 256; ++i)
A[i] = B[i] = i;
for (i = 0; i < 256; ++i)
C[i] = A[i] * B[i];
for (i = 0; i < 256; ++i)
if (C[i] != (unsigned char)(i * i))
abort ();
}
int main()
{
check_vect ();
foo();
return 0;
}
......@@ -29,7 +29,7 @@ main1 (afloat * pa)
afloat pb[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
afloat pc[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
/* Not vectorizable: pa may alias pb and/or pc, since their addresses escape. */
for (i = 0; i < N; i++)
{
pa[i] = pb[i] * pc[i];
......@@ -40,6 +40,29 @@ main1 (afloat * pa)
return 0;
}
int
main2 (afloat * pa)
{
int i;
afloat pb[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
afloat pc[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
/* Vectorizable: pb and pc addresses do not escape. */
for (i = 0; i < N; i++)
{
pa[i] = pb[i] * pc[i];
}
/* check results: */
for (i = 0; i < N; i++)
{
if (pa[i] != (pb[i] * pc[i]))
abort ();
}
return 0;
}
int main (void)
{
int i;
......@@ -50,6 +73,7 @@ int main (void)
check_vect ();
main1 (a);
main2 (a);
return 0;
}
......
......@@ -11,10 +11,7 @@ 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. */
align the other. */
int
main1 (int * pa)
......@@ -60,11 +57,8 @@ main3 ()
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" { xfail vect_no_int_add } } } */
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 3 "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 { scan-tree-dump-times "accesses have the same alignment." 3 "vect" } } */
/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 3 "vect" } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
......@@ -24,7 +24,7 @@ set DEFAULT_VECTCFLAGS ""
# These flags are used for all targets.
lappend DEFAULT_VECTCFLAGS "-O2" "-ftree-vectorize" \
"-ftree-vectorizer-verbose=3" "-fdump-tree-vect-stats"
"-ftree-vectorizer-verbose=4" "-fdump-tree-vect-stats"
# If the target system supports vector instructions, the default action
# for a test is 'run', otherwise it's 'compile'. Save current default.
......
! { dg-do compile }
! { dg-require-effective-target vect_float }
subroutine s111 (ntimes,ld,n,ctime,dtime,a,b,c,d,e,aa,bb,cc)
! linear dependence testing
! no dependence - vectorizable
! but not consecutive access
integer ntimes, ld, n, i, nl
real a(n), b(n), c(n), d(n), e(n), aa(ld,n), bb(ld,n), cc(ld,n)
real t1, t2, second, chksum, ctime, dtime, cs1d
do 1 nl = 1,2*ntimes
do 10 i = 2,n,2
a(i) = a(i-1) + b(i)
10 continue
call dummy(ld,n,a,b,c,d,e,aa,bb,cc,1.)
1 continue
return
end
! { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" } }
! { dg-final { scan-tree-dump-times "complicated access pattern" 1 "vect" } }
! { dg-final { cleanup-tree-dump "vect" } }
......@@ -9,10 +9,8 @@ DIMENSION X(64), Y(64)
Y = Y + A * X
END
! 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" 1 "vect" { xfail *-*-* } } }
! { dg-final { scan-tree-dump-times "accesses have the same alignment." 1 "vect" { xfail *-*-* } } }
! { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } }
! { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" } }
! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" } }
! { dg-final { scan-tree-dump-times "accesses have the same alignment." 1 "vect" } }
! { dg-final { cleanup-tree-dump "vect" } }
......@@ -25,7 +25,7 @@ set DEFAULT_VECTCFLAGS ""
# These flags are used for all targets.
lappend DEFAULT_VECTCFLAGS "-O2" "-ftree-vectorize" \
"-ftree-vectorizer-verbose=3" "-fdump-tree-vect-stats"
"-ftree-vectorizer-verbose=4" "-fdump-tree-vect-stats"
# If the target system supports vector instructions, the default action
# for a test is 'run', otherwise it's 'compile'. Save current default.
......
......@@ -24,6 +24,50 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
#include "lambda.h"
/** {base_address + offset + init} is the first location accessed by data-ref
in the loop, and step is the stride of data-ref in the loop in bytes;
e.g.:
Example 1 Example 2
data-ref a[j].b[i][j] a + x + 16B (a is int*)
First location info:
base_address &a a
offset j_0*D_j + i_0*D_i + C_a x
init C_b 16
step D_j 4
access_fn NULL {16, +, 1}
Base object info:
base_object a NULL
access_fn <access_fns of indexes of b> NULL
**/
struct first_location_in_loop
{
tree base_address;
tree offset;
tree init;
tree step;
/* Access function related to first location in the loop. */
VEC(tree,heap) *access_fns;
};
struct base_object_info
{
/* The object. */
tree base_object;
/* A list of chrecs. Access functions related to BASE_OBJECT. */
VEC(tree,heap) *access_fns;
};
enum data_ref_type {
ARRAY_REF_TYPE,
POINTER_REF_TYPE
};
struct data_reference
{
/* A pointer to the statement that contains this DR. */
......@@ -32,27 +76,74 @@ struct data_reference
/* A pointer to the ARRAY_REF node. */
tree ref;
/* The name of the array. */
tree base_name;
/* A list of chrecs. */
VEC(tree,heap) *access_fns;
/* Auxiliary info specific to a pass. */
int aux;
/* True when the data reference is in RHS of a stmt. */
bool is_read;
/* First location accessed by the data-ref in the loop. */
struct first_location_in_loop first_location;
/* Base object related info. */
struct base_object_info object_info;
/* Aliasing information. This field represents the symbol that
should be aliased by a pointer holding the address of this data
reference. If the original data reference was a pointer
dereference, then this field contains the memory tag that should
be used by the new vector-pointer. */
tree memtag;
struct ptr_info_def *ptr_info;
subvar_t subvars;
/* Alignment information. */
/* The offset of the data-reference from its base in bytes. */
tree misalignment;
/* The maximum data-ref's alignment. */
tree aligned_to;
/* The type of the data-ref. */
enum data_ref_type type;
};
#define DR_STMT(DR) DR->stmt
#define DR_REF(DR) DR->ref
#define DR_BASE_NAME(DR) DR->base_name
#define DR_ACCESS_FNS(DR) DR->access_fns
#define DR_STMT(DR) (DR)->stmt
#define DR_REF(DR) (DR)->ref
#define DR_BASE_OBJECT(DR) (DR)->object_info.base_object
#define DR_TYPE(DR) (DR)->type
#define DR_ACCESS_FNS(DR)\
(DR_TYPE(DR) == ARRAY_REF_TYPE ? \
(DR)->object_info.access_fns : (DR)->first_location.access_fns)
#define DR_ACCESS_FN(DR, I) VEC_index (tree, DR_ACCESS_FNS (DR), I)
#define DR_NUM_DIMENSIONS(DR) VEC_length (tree, DR_ACCESS_FNS (DR))
#define DR_IS_READ(DR) DR->is_read
#define DR_IS_READ(DR) (DR)->is_read
#define DR_BASE_ADDRESS(DR) (DR)->first_location.base_address
#define DR_OFFSET(DR) (DR)->first_location.offset
#define DR_INIT(DR) (DR)->first_location.init
#define DR_STEP(DR) (DR)->first_location.step
#define DR_MEMTAG(DR) (DR)->memtag
#define DR_ALIGNED_TO(DR) (DR)->aligned_to
#define DR_OFFSET_MISALIGNMENT(DR) (DR)->misalignment
#define DR_PTR_INFO(DR) (DR)->ptr_info
#define DR_SUBVARS(DR) (DR)->subvars
#define DR_ACCESS_FNS_ADDR(DR) \
(DR_TYPE(DR) == ARRAY_REF_TYPE ? \
&((DR)->object_info.access_fns) : &((DR)->first_location.access_fns))
#define DR_SET_ACCESS_FNS(DR, ACC_FNS) \
{ \
if (DR_TYPE(DR) == ARRAY_REF_TYPE) \
(DR)->object_info.access_fns = ACC_FNS; \
else \
(DR)->first_location.access_fns = ACC_FNS; \
}
#define DR_FREE_ACCESS_FNS(DR) \
{ \
if (DR_TYPE(DR) == ARRAY_REF_TYPE) \
VEC_free (tree, heap, (DR)->object_info.access_fns); \
else \
VEC_free (tree, heap, (DR)->first_location.access_fns); \
}
enum data_dependence_direction {
dir_positive,
......@@ -156,10 +247,8 @@ extern struct data_dependence_relation *initialize_data_dependence_relation
(struct data_reference *, struct data_reference *);
extern void compute_affine_dependence (struct data_dependence_relation *);
extern void analyze_all_data_dependences (struct loops *);
extern void compute_data_dependences_for_loop (unsigned, struct loop *,
extern void compute_data_dependences_for_loop (struct loop *, bool,
varray_type *, varray_type *);
extern struct data_reference * init_data_ref (tree, tree, tree, tree, bool);
extern struct data_reference *analyze_array (tree, tree, bool);
extern void dump_subscript (FILE *, struct subscript *);
extern void dump_ddrs (FILE *, varray_type);
......@@ -171,13 +260,10 @@ extern void dump_data_dependence_relation (FILE *,
extern void dump_data_dependence_relations (FILE *, varray_type);
extern void dump_data_dependence_direction (FILE *,
enum data_dependence_direction);
extern bool array_base_name_differ_p (struct data_reference *,
struct data_reference *, bool *);
extern void free_dependence_relation (struct data_dependence_relation *);
extern void free_dependence_relations (varray_type);
extern void free_data_refs (varray_type);
extern void compute_subscript_distance (struct data_dependence_relation *);
extern bool build_classic_dist_vector (struct data_dependence_relation *, int, int);
......
......@@ -606,6 +606,7 @@ extern void debug_points_to_info (void);
extern void dump_points_to_info_for (FILE *, tree);
extern void debug_points_to_info_for (tree);
extern bool may_be_aliased (tree);
extern bool is_aliased_with (tree, tree);
extern struct ptr_info_def *get_ptr_info (tree);
extern void add_type_alias (tree, tree);
extern void new_type_alias (tree, tree);
......
......@@ -295,7 +295,7 @@ linear_transform_loops (struct loops *loops)
"dependence_relations");
compute_data_dependences_for_loop (depth, loop_nest,
compute_data_dependences_for_loop (loop_nest, true,
&datarefs, &dependence_relations);
if (dump_file && (dump_flags & TDF_DETAILS))
{
......
......@@ -2219,6 +2219,40 @@ may_be_aliased (tree var)
}
/* Given two symbols return TRUE if one is in the alias set of the other. */
bool
is_aliased_with (tree tag, tree sym)
{
size_t i;
varray_type aliases;
if (var_ann (sym)->is_alias_tag)
{
aliases = var_ann (tag)->may_aliases;
if (aliases == NULL)
return false;
for (i = 0; i < VARRAY_ACTIVE_SIZE (aliases); i++)
if (VARRAY_TREE (aliases, i) == sym)
return true;
}
else
{
aliases = var_ann (sym)->may_aliases;
if (aliases == NULL)
return false;
for (i = 0; i < VARRAY_ACTIVE_SIZE (aliases); i++)
if (VARRAY_TREE (aliases, i) == tag)
return true;
}
return false;
}
/* Add VAR to the list of may-aliases of PTR's type tag. If PTR
doesn't already have a type tag, create one. */
......
......@@ -189,8 +189,7 @@ vect_create_addr_base_for_vector_ref (tree stmt,
{
stmt_vec_info stmt_info = vinfo_for_stmt (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 data_ref_base = unshare_expr (DR_BASE_ADDRESS (dr));
tree base_name = build_fold_indirect_ref (data_ref_base);
tree ref = DR_REF (dr);
tree scalar_type = TREE_TYPE (ref);
......@@ -199,9 +198,11 @@ vect_create_addr_base_for_vector_ref (tree stmt,
tree new_temp;
tree addr_base, addr_expr;
tree dest, new_stmt;
tree base_offset = unshare_expr (STMT_VINFO_VECT_INIT_OFFSET (stmt_info));
tree base_offset = unshare_expr (DR_OFFSET (dr));
tree init = unshare_expr (DR_INIT (dr));
/* Create base_offset */
base_offset = size_binop (PLUS_EXPR, base_offset, init);
dest = create_tmp_var (TREE_TYPE (base_offset), "base_off");
add_referenced_tmp_var (dest);
base_offset = force_gimple_operand (base_offset, &new_stmt, false, dest);
......@@ -212,7 +213,7 @@ vect_create_addr_base_for_vector_ref (tree stmt,
tree tmp = create_tmp_var (TREE_TYPE (base_offset), "offset");
add_referenced_tmp_var (tmp);
offset = fold_build2 (MULT_EXPR, TREE_TYPE (offset), offset,
STMT_VINFO_VECT_STEP (stmt_info));
DR_STEP (dr));
base_offset = fold_build2 (PLUS_EXPR, TREE_TYPE (base_offset),
base_offset, offset);
base_offset = force_gimple_operand (base_offset, &new_stmt, false, tmp);
......@@ -328,9 +329,9 @@ vect_create_data_ref_ptr (tree stmt, block_stmt_iterator *bsi, tree offset,
tree ptr_update;
tree data_ref_ptr;
tree type, tmp, size;
struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
base_name = build_fold_indirect_ref (unshare_expr (
STMT_VINFO_VECT_DR_BASE_ADDRESS (stmt_info)));
base_name = build_fold_indirect_ref (unshare_expr (DR_BASE_ADDRESS (dr)));
if (vect_print_dump_info (REPORT_DETAILS))
{
......@@ -357,9 +358,9 @@ vect_create_data_ref_ptr (tree stmt, block_stmt_iterator *bsi, tree offset,
/** (2) Add aliasing information to the new vector-pointer:
(The points-to info (SSA_NAME_PTR_INFO) may be defined later.) **/
(The points-to info (DR_PTR_INFO) may be defined later.) **/
tag = STMT_VINFO_MEMTAG (stmt_info);
tag = DR_MEMTAG (dr);
gcc_assert (tag);
/* If tag is a variable (and NOT_A_TAG) than a new type alias
......@@ -369,7 +370,7 @@ vect_create_data_ref_ptr (tree stmt, block_stmt_iterator *bsi, tree offset,
else
var_ann (vect_ptr)->type_mem_tag = tag;
var_ann (vect_ptr)->subvars = STMT_VINFO_SUBVARS (stmt_info);
var_ann (vect_ptr)->subvars = DR_SUBVARS (dr);
/** (3) Calculate the initial address the vector-pointer, and set
the vector-pointer to point to it before the loop: **/
......@@ -397,9 +398,8 @@ vect_create_data_ref_ptr (tree stmt, block_stmt_iterator *bsi, tree offset,
if (only_init) /* No update in loop is required. */
{
/* Copy the points-to information if it exists. */
if (STMT_VINFO_PTR_INFO (stmt_info))
duplicate_ssa_name_ptr_info (vect_ptr_init,
STMT_VINFO_PTR_INFO (stmt_info));
if (DR_PTR_INFO (dr))
duplicate_ssa_name_ptr_info (vect_ptr_init, DR_PTR_INFO (dr));
return vect_ptr_init;
}
......@@ -433,8 +433,8 @@ vect_create_data_ref_ptr (tree stmt, block_stmt_iterator *bsi, tree offset,
data_ref_ptr = TREE_OPERAND (vec_stmt, 0);
/* Copy the points-to information if it exists. */
if (STMT_VINFO_PTR_INFO (stmt_info))
duplicate_ssa_name_ptr_info (data_ref_ptr, STMT_VINFO_PTR_INFO (stmt_info));
if (DR_PTR_INFO (dr))
duplicate_ssa_name_ptr_info (data_ref_ptr, DR_PTR_INFO (dr));
return data_ref_ptr;
}
......@@ -2625,18 +2625,16 @@ vect_gen_niters_for_prolog_loop (loop_vec_info loop_vinfo, tree loop_niters)
NITERS iterations were peeled from LOOP. DR represents a data reference
in LOOP. This function updates the information recorded in DR to
account for the fact that the first NITERS iterations had already been
executed. Specifically, it updates the OFFSET field of stmt_info. */
executed. Specifically, it updates the OFFSET field of DR. */
static void
vect_update_init_of_dr (struct data_reference *dr, tree niters)
{
stmt_vec_info stmt_info = vinfo_for_stmt (DR_STMT (dr));
tree offset = STMT_VINFO_VECT_INIT_OFFSET (stmt_info);
tree offset = DR_OFFSET (dr);
niters = fold_build2 (MULT_EXPR, TREE_TYPE (niters), niters,
STMT_VINFO_VECT_STEP (stmt_info));
niters = fold_build2 (MULT_EXPR, TREE_TYPE (niters), niters, DR_STEP (dr));
offset = fold_build2 (PLUS_EXPR, TREE_TYPE (offset), offset, niters);
STMT_VINFO_VECT_INIT_OFFSET (stmt_info) = offset;
DR_OFFSET (dr) = offset;
}
......@@ -2652,21 +2650,14 @@ static void
vect_update_inits_of_drs (loop_vec_info loop_vinfo, tree niters)
{
unsigned int i;
varray_type loop_write_datarefs = LOOP_VINFO_DATAREF_WRITES (loop_vinfo);
varray_type loop_read_datarefs = LOOP_VINFO_DATAREF_READS (loop_vinfo);
varray_type datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
if (vect_dump && (dump_flags & TDF_DETAILS))
fprintf (vect_dump, "=== vect_update_inits_of_dr ===");
for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_write_datarefs); i++)
{
struct data_reference *dr = VARRAY_GENERIC_PTR (loop_write_datarefs, i);
vect_update_init_of_dr (dr, niters);
}
for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_read_datarefs); i++)
for (i = 0; i < VARRAY_ACTIVE_SIZE (datarefs); i++)
{
struct data_reference *dr = VARRAY_GENERIC_PTR (loop_read_datarefs, i);
struct data_reference *dr = VARRAY_GENERIC_PTR (datarefs, i);
vect_update_init_of_dr (dr, niters);
}
}
......
......@@ -1347,14 +1347,6 @@ new_stmt_vec_info (tree stmt, loop_vec_info loop_vinfo)
STMT_VINFO_DEF_TYPE (res) = vect_unknown_def_type;
else
STMT_VINFO_DEF_TYPE (res) = vect_loop_def;
STMT_VINFO_MEMTAG (res) = NULL;
STMT_VINFO_PTR_INFO (res) = NULL;
STMT_VINFO_SUBVARS (res) = NULL;
STMT_VINFO_VECT_DR_BASE_ADDRESS (res) = NULL;
STMT_VINFO_VECT_INIT_OFFSET (res) = NULL_TREE;
STMT_VINFO_VECT_STEP (res) = NULL_TREE;
STMT_VINFO_VECT_BASE_ALIGNED_P (res) = false;
STMT_VINFO_VECT_MISALIGNMENT (res) = NULL_TREE;
STMT_VINFO_SAME_ALIGN_REFS (res) = VEC_alloc (dr_p, heap, 5);
return res;
......@@ -1407,10 +1399,8 @@ new_loop_vec_info (struct loop *loop)
LOOP_VINFO_VECTORIZABLE_P (res) = 0;
LOOP_PEELING_FOR_ALIGNMENT (res) = 0;
LOOP_VINFO_VECT_FACTOR (res) = 0;
VARRAY_GENERIC_PTR_INIT (LOOP_VINFO_DATAREF_WRITES (res), 20,
"loop_write_datarefs");
VARRAY_GENERIC_PTR_INIT (LOOP_VINFO_DATAREF_READS (res), 20,
"loop_read_datarefs");
VARRAY_GENERIC_PTR_INIT (LOOP_VINFO_DATAREFS (res), 20, "loop_datarefs");
VARRAY_GENERIC_PTR_INIT (LOOP_VINFO_DDRS (res), 20, "loop_ddrs");
LOOP_VINFO_UNALIGNED_DR (res) = NULL;
return res;
......@@ -1470,39 +1460,13 @@ destroy_loop_vec_info (loop_vec_info loop_vinfo)
}
free (LOOP_VINFO_BBS (loop_vinfo));
varray_clear (LOOP_VINFO_DATAREF_WRITES (loop_vinfo));
varray_clear (LOOP_VINFO_DATAREF_READS (loop_vinfo));
varray_clear (LOOP_VINFO_DATAREFS (loop_vinfo));
varray_clear (LOOP_VINFO_DDRS (loop_vinfo));
free (loop_vinfo);
}
/* Function vect_strip_conversions
Strip conversions that don't narrow the mode. */
tree
vect_strip_conversion (tree expr)
{
tree to, ti, oprnd0;
while (TREE_CODE (expr) == NOP_EXPR || TREE_CODE (expr) == CONVERT_EXPR)
{
to = TREE_TYPE (expr);
oprnd0 = TREE_OPERAND (expr, 0);
ti = TREE_TYPE (oprnd0);
if (!INTEGRAL_TYPE_P (to) || !INTEGRAL_TYPE_P (ti))
return NULL_TREE;
if (GET_MODE_SIZE (TYPE_MODE (to)) < GET_MODE_SIZE (TYPE_MODE (ti)))
return NULL_TREE;
expr = oprnd0;
}
return expr;
}
/* Function vect_force_dr_alignment_p.
Returns whether the alignment of a DECL can be forced to be aligned
......
......@@ -73,6 +73,7 @@ enum verbosity_levels {
REPORT_VECTORIZED_LOOPS,
REPORT_UNVECTORIZED_LOOPS,
REPORT_ALIGNMENT,
REPORT_DR_DETAILS,
REPORT_BAD_FORM_LOOPS,
REPORT_OUTER_LOOPS,
REPORT_DETAILS,
......@@ -116,27 +117,29 @@ typedef struct _loop_vec_info {
unaligned_dr. */
int peeling_for_alignment;
/* All data references in the loop that are being written to. */
varray_type data_ref_writes;
/* All data references in the loop. */
varray_type datarefs;
/* All data references in the loop that are being read from. */
varray_type data_ref_reads;
/* All data dependences in the loop. */
varray_type ddrs;
/* The loop location in the source. */
LOC loop_line_number;
} *loop_vec_info;
/* Access Functions. */
/* Access Functions. */
#define LOOP_VINFO_LOOP(L) (L)->loop
#define LOOP_VINFO_BBS(L) (L)->bbs
#define LOOP_VINFO_EXIT_COND(L) (L)->exit_cond
#define LOOP_VINFO_NITERS(L) (L)->num_iters
#define LOOP_VINFO_VECTORIZABLE_P(L) (L)->vectorizable
#define LOOP_VINFO_VECT_FACTOR(L) (L)->vectorization_factor
#define LOOP_VINFO_DATAREF_WRITES(L) (L)->data_ref_writes
#define LOOP_VINFO_DATAREF_READS(L) (L)->data_ref_reads
#define LOOP_VINFO_DATAREFS(L) (L)->datarefs
#define LOOP_VINFO_DDRS(L) (L)->ddrs
#define LOOP_VINFO_INT_NITERS(L) (TREE_INT_CST_LOW ((L)->num_iters))
#define LOOP_PEELING_FOR_ALIGNMENT(L) (L)->peeling_for_alignment
#define LOOP_VINFO_UNALIGNED_DR(L) (L)->unaligned_dr
#define LOOP_VINFO_LOC(L) (L)->loop_line_number
#define LOOP_VINFO_NITERS_KNOWN_P(L) \
(host_integerp ((L)->num_iters,0) \
......@@ -192,45 +195,6 @@ typedef struct _stmt_vec_info {
/* Information about the data-ref (access function, etc). */
struct data_reference *data_ref_info;
/* Aliasing information. This field represents the symbol that
should be aliased by a pointer holding the address of this data
reference. If the original data reference was a pointer
dereference, then this field contains the memory tag that should
be used by the new vector-pointer. */
tree memtag;
struct ptr_info_def *ptr_info;
subvar_t subvars;
/** The following fields are used to store the information about
data-reference. {base_address + initial_offset} is the first location
accessed by data-ref in the loop, and step is the stride of data-ref in
the loop in bytes;
e.g.:
Example 1 Example 2
data-ref a[j].b[i][j] a + 4B (a is int*)
base_address &a a
initial_offset j_0*D_j + i_0*D_i + C 4
step D_j 4
data-reference structure info:
base_name a NULL
access_fn <access_fns of indexes of b> (0, +, 1)
**/
/* The above base_address, offset and step. */
tree base_address;
tree initial_offset;
tree step;
/* Alignment information. Whether the base of the data-reference is aligned
to vectype. */
bool base_aligned_p;
/* Alignment information. The offset of the data-reference from its base
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;
......@@ -249,14 +213,6 @@ typedef struct _stmt_vec_info {
#define STMT_VINFO_VECTYPE(S) (S)->vectype
#define STMT_VINFO_VEC_STMT(S) (S)->vectorized_stmt
#define STMT_VINFO_DATA_REF(S) (S)->data_ref_info
#define STMT_VINFO_MEMTAG(S) (S)->memtag
#define STMT_VINFO_PTR_INFO(S) (S)->ptr_info
#define STMT_VINFO_SUBVARS(S) (S)->subvars
#define STMT_VINFO_VECT_DR_BASE_ADDRESS(S)(S)->base_address
#define STMT_VINFO_VECT_INIT_OFFSET(S) (S)->initial_offset
#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
......
......@@ -4174,4 +4174,7 @@ extern void init_object_sizes (void);
extern void fini_object_sizes (void);
extern unsigned HOST_WIDE_INT compute_builtin_object_size (tree, int);
/* In expr.c. */
extern unsigned HOST_WIDE_INT highest_pow2_factor (tree);
#endif /* GCC_TREE_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment