]> gcc.gnu.org Git - gcc.git/commitdiff
expr.c (highest_pow2_factor): Make extern.
authorIra Rosen <irar@il.ibm.com>
Mon, 25 Jul 2005 12:05:07 +0000 (12:05 +0000)
committerIra Rosen <irar@gcc.gnu.org>
Mon, 25 Jul 2005 12:05:07 +0000 (12:05 +0000)
        * 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

31 files changed:
gcc/ChangeLog
gcc/expr.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/vect/pr21218.cc [new file with mode: 0644]
gcc/testsuite/g++.dg/vect/vect.exp
gcc/testsuite/gcc.dg/tree-ssa/ltrans-8.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/pr20122.c
gcc/testsuite/gcc.dg/vect/vect-100.c
gcc/testsuite/gcc.dg/vect/vect-101.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-102.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-103.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-104.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-105.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-115.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-116.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-43.c
gcc/testsuite/gcc.dg/vect/vect-91.c
gcc/testsuite/gcc.dg/vect/vect.exp
gcc/testsuite/gfortran.dg/vect/pr19049.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/vect/vect-4.f90
gcc/testsuite/gfortran.dg/vect/vect.exp
gcc/tree-data-ref.c
gcc/tree-data-ref.h
gcc/tree-flow.h
gcc/tree-loop-linear.c
gcc/tree-ssa-alias.c
gcc/tree-vect-analyze.c
gcc/tree-vect-transform.c
gcc/tree-vectorizer.c
gcc/tree-vectorizer.h
gcc/tree.h

index 396314105e979b2735bb6163a7c0ae38d3eacbc5..68be3ab65cf165118a5252d619f5de0392ba0115 100644 (file)
@@ -1,3 +1,88 @@
+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
index 60d45f3ad2598101acd4536452dd653800c5fed0..c263ebf95e848f23d9857d72bcfae70f946784f3 100644 (file)
@@ -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;
index a5d540ca5cb35ccfb0af89d666c35a4ba34453ba..4656f1b6b628d85a61c35d85471feec52fd54459 100644 (file)
@@ -1,3 +1,19 @@
+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.
diff --git a/gcc/testsuite/g++.dg/vect/pr21218.cc b/gcc/testsuite/g++.dg/vect/pr21218.cc
new file mode 100644 (file)
index 0000000..73331d2
--- /dev/null
@@ -0,0 +1,18 @@
+/* { 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" } } */
+
index 1a084d0e1aee4e0cc1928349acae01096ebb3c83..f36310166735210c3121ddf6fd7adf460e393966 100644 (file)
@@ -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
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ltrans-8.c b/gcc/testsuite/gcc.dg/tree-ssa/ltrans-8.c
new file mode 100644 (file)
index 0000000..80c9c01
--- /dev/null
@@ -0,0 +1,13 @@
+/* { 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"} } */ 
index 7fef9887fb2446bc71dcdcef82a399a280feecd4..a713e5e1fa84f63f9b485ed287fa961117528ab7 100644 (file)
@@ -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;
 }
index 3b803fc71b6a0fb708c0343f9d83abb68779f503..c1b9e401897860c5e171819792dde32a6be20831 100644 (file)
@@ -1,28 +1,78 @@
-/* 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));
 
-  for (i = 0; i < 256; ++i)
-    A[i] = B[i] = i;
+  /* 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];
+    }
 
-  for (i = 0; i < 256; ++i)
-    C[i] = A[i] * B[i];
+  /* check results: */
+  for (i = 0; i < N; i++)
+    {
+       if (p->a[i] != a[i] || p->b[i] != b[i])
+         abort();
+    }
 
-  for (i = 0; i < 256; ++i)
-    if (C[i] != (unsigned char)(i * i))
-      abort ();
+  return 0;
 }
 
-int main()
-{
-  check_vect ();
-  foo();
+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));
+
+  /* Vectorizable: c and d are local arrays.  */
+  for (i = 0; i < N; i++)
+    {
+      p->a[i] = c[i];
+      p->b[i] = d[i];
+    }
+
+  /* check results: */
+  for (i = 0; i < N; i++)
+    {
+       if (p->a[i] != c[i] || p->b[i] != d[i])
+         abort();
+    }
+
   return 0;
 }
+
+int main (void)
+{ 
+  check_vect ();
+
+  main1 ();
+  main2 ();
+  
+  return 0;    
+}
+
+/* Requires versioning.  */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/vect-101.c b/gcc/testsuite/gcc.dg/vect/vect-101.c
new file mode 100644 (file)
index 0000000..e195a58
--- /dev/null
@@ -0,0 +1,49 @@
+/* { 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" } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/vect-102.c b/gcc/testsuite/gcc.dg/vect/vect-102.c
new file mode 100644 (file)
index 0000000..af3261d
--- /dev/null
@@ -0,0 +1,55 @@
+/* { 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" } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/vect-103.c b/gcc/testsuite/gcc.dg/vect/vect-103.c
new file mode 100644 (file)
index 0000000..effa97e
--- /dev/null
@@ -0,0 +1,57 @@
+/* { 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" } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/vect-104.c b/gcc/testsuite/gcc.dg/vect/vect-104.c
new file mode 100644 (file)
index 0000000..6d16da6
--- /dev/null
@@ -0,0 +1,66 @@
+/* { 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" } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/vect-105.c b/gcc/testsuite/gcc.dg/vect/vect-105.c
new file mode 100644 (file)
index 0000000..c8f8e5b
--- /dev/null
@@ -0,0 +1,66 @@
+/* { 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" } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/vect-115.c b/gcc/testsuite/gcc.dg/vect/vect-115.c
new file mode 100644 (file)
index 0000000..fe055fb
--- /dev/null
@@ -0,0 +1,75 @@
+/* { 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" } } */
+  
+
diff --git a/gcc/testsuite/gcc.dg/vect/vect-116.c b/gcc/testsuite/gcc.dg/vect/vect-116.c
new file mode 100644 (file)
index 0000000..3b803fc
--- /dev/null
@@ -0,0 +1,28 @@
+/* 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;
+}
index 6cea83206f92069cf23e95a5c858f0444e53e9db..12db333b39bbfdf7622dab65277d8fdbbc280a66 100644 (file)
@@ -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;
 }
 
index 96099f4fe0b0b3e77388d9fed1abac43d75d3144..d72bd4c8cf016b90537194e20e339096b59bd8cd 100644 (file)
@@ -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" } } */
index 8c53541003da37acecddb0d0543d311223250462..07b7e946f803bbf0f4f7de20f85369751e3d8097 100644 (file)
@@ -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.
diff --git a/gcc/testsuite/gfortran.dg/vect/pr19049.f90 b/gcc/testsuite/gfortran.dg/vect/pr19049.f90
new file mode 100644 (file)
index 0000000..6c8030c
--- /dev/null
@@ -0,0 +1,24 @@
+! { 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" } }
+
index e83c05c5e50b756d0c8578d88b9b7044dd1f90b3..74f4e97678e8d2800e85291fb1461ee36ec25a19 100644 (file)
@@ -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" } }
index dfaaeb9b5dc114bd72c27a39e73324b8d5445436..7f1ec2d7ce1ca44dd507db275f5acfc5d7487b3a 100644 (file)
@@ -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.
index d48f020a495e58cad543c0e19643603bc89d1148..05361a2fc1628f451dfbbf381bbafd24b354aac7 100644 (file)
@@ -94,6 +94,180 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #include "tree-scalar-evolution.h"
 #include "tree-pass.h"
 
+static tree object_analysis (tree, tree, bool, struct data_reference **, 
+                            tree *, tree *, tree *, tree *, tree *,
+                            struct ptr_info_def **, subvar_t *);
+static struct data_reference * init_data_ref (tree, tree, tree, tree, bool, 
+                                             tree, tree, tree, tree, tree, 
+                                             struct ptr_info_def *,
+                                             enum  data_ref_type);
+
+/* Determine if PTR and DECL may alias, the result is put in ALIASED.
+   Return FALSE if there is no type memory tag for PTR.
+*/
+static bool
+ptr_decl_may_alias_p (tree ptr, tree decl, 
+                     struct data_reference *ptr_dr, 
+                     bool *aliased)
+{
+  tree tag;
+   
+  gcc_assert (TREE_CODE (ptr) == SSA_NAME && DECL_P (decl));
+
+  tag = get_var_ann (SSA_NAME_VAR (ptr))->type_mem_tag;
+  if (!tag)
+    tag = DR_MEMTAG (ptr_dr);
+  if (!tag)
+    return false;
+  
+  *aliased = is_aliased_with (tag, decl);      
+  return true;
+}
+
+
+/* Determine if two pointers may alias, the result is put in ALIASED.
+   Return FALSE if there is no type memory tag for one of the pointers.
+*/
+static bool
+ptr_ptr_may_alias_p (tree ptr_a, tree ptr_b, 
+                    struct data_reference *dra, 
+                    struct data_reference *drb, 
+                    bool *aliased)
+{  
+  tree tag_a, tag_b;
+
+  tag_a = get_var_ann (SSA_NAME_VAR (ptr_a))->type_mem_tag;
+  if (!tag_a)
+    tag_a = DR_MEMTAG (dra);
+  if (!tag_a)
+    return false;
+  tag_b = get_var_ann (SSA_NAME_VAR (ptr_b))->type_mem_tag;
+  if (!tag_b)
+    tag_b = DR_MEMTAG (drb);
+  if (!tag_b)
+    return false;
+  *aliased = (tag_a == tag_b);
+  return true;
+}
+
+
+/* Determine if BASE_A and BASE_B may alias, the result is put in ALIASED.
+   Return FALSE if there is no type memory tag for one of the symbols.
+*/
+static bool
+may_alias_p (tree base_a, tree base_b,
+            struct data_reference *dra,
+            struct data_reference *drb,
+            bool *aliased)
+{
+  if (TREE_CODE (base_a) == ADDR_EXPR || TREE_CODE (base_b) == ADDR_EXPR)
+    {
+      if (TREE_CODE (base_a) == ADDR_EXPR && TREE_CODE (base_b) == ADDR_EXPR)
+       {
+        *aliased = (TREE_OPERAND (base_a, 0) == TREE_OPERAND (base_b, 0));
+        return true;
+       }
+      if (TREE_CODE (base_a) == ADDR_EXPR)
+       return ptr_decl_may_alias_p (base_b, TREE_OPERAND (base_a, 0), drb, 
+                                    aliased);
+      else
+       return ptr_decl_may_alias_p (base_a, TREE_OPERAND (base_b, 0), dra, 
+                                    aliased);
+    }
+
+  return ptr_ptr_may_alias_p (base_a, base_b, dra, drb, aliased);
+}
+
+
+/* Determine if a pointer (BASE_A) and a record/union access (BASE_B)
+   are not aliased. Return TRUE if they differ.  */
+static bool
+record_ptr_differ_p (struct data_reference *dra,
+                    struct data_reference *drb)
+{
+  bool aliased;
+  tree base_a = DR_BASE_OBJECT (dra);
+  tree base_b = DR_BASE_OBJECT (drb);
+
+  if (TREE_CODE (base_b) != COMPONENT_REF)
+    return false;
+
+  /* Peel COMPONENT_REFs to get to the base. Do not peel INDIRECT_REFs.
+     For a.b.c.d[i] we will get a, and for a.b->c.d[i] we will get a.b.  
+     Probably will be unnecessary with struct alias analysis.  */
+  while (TREE_CODE (base_b) == COMPONENT_REF)
+     base_b = TREE_OPERAND (base_b, 0);
+  /* Compare a record/union access (b.c[i] or p->c[i]) and a pointer
+     ((*q)[i]).  */
+  if (TREE_CODE (base_a) == INDIRECT_REF
+      && ((TREE_CODE (base_b) == VAR_DECL
+          && (ptr_decl_may_alias_p (TREE_OPERAND (base_a, 0), base_b, dra, 
+                                    &aliased)
+              && !aliased))
+         || (TREE_CODE (base_b) == INDIRECT_REF
+             && (ptr_ptr_may_alias_p (TREE_OPERAND (base_a, 0), 
+                                      TREE_OPERAND (base_b, 0), dra, drb, 
+                                      &aliased)
+                 && !aliased))))
+    return true;
+  else
+    return false;
+}
+
+    
+/* Determine if an array access (BASE_A) and a record/union access (BASE_B)
+   are not aliased. Return TRUE if they differ.  */
+static bool
+record_array_differ_p (struct data_reference *dra,
+                      struct data_reference *drb)
+{  
+  bool aliased;
+  tree base_a = DR_BASE_OBJECT (dra);
+  tree base_b = DR_BASE_OBJECT (drb);
+
+  if (TREE_CODE (base_b) != COMPONENT_REF)
+    return false;
+
+  /* Peel COMPONENT_REFs to get to the base. Do not peel INDIRECT_REFs.
+     For a.b.c.d[i] we will get a, and for a.b->c.d[i] we will get a.b.  
+     Probably will be unnecessary with struct alias analysis.  */
+  while (TREE_CODE (base_b) == COMPONENT_REF)
+     base_b = TREE_OPERAND (base_b, 0);
+
+  /* Compare a record/union access (b.c[i] or p->c[i]) and an array access 
+     (a[i]). In case of p->c[i] use alias analysis to verify that p is not
+     pointing to a.  */
+  if (TREE_CODE (base_a) == VAR_DECL
+      && (TREE_CODE (base_b) == VAR_DECL
+         || (TREE_CODE (base_b) == INDIRECT_REF
+             && (ptr_decl_may_alias_p (TREE_OPERAND (base_b, 0), base_a, drb, 
+                                       &aliased)
+                 && !aliased))))
+    return true;
+  else
+    return false;
+}
+
+
+/* Determine if an array access (BASE_A) and a pointer (BASE_B)
+   are not aliased. Return TRUE if they differ.  */
+static bool
+array_ptr_differ_p (tree base_a, tree base_b,       
+                   struct data_reference *drb)
+{  
+  bool aliased;
+
+  /* In case one of the bases is a pointer (a[i] and (*p)[i]), we check with the
+     help of alias analysis that p is not pointing to a.  */
+  if (TREE_CODE (base_a) == VAR_DECL && TREE_CODE (base_b) == INDIRECT_REF 
+      && (ptr_decl_may_alias_p (TREE_OPERAND (base_b, 0), base_a, drb, &aliased)
+         && !aliased))
+    return true;
+  else
+    return false;
+}
+
+
 /* 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.
@@ -101,13 +275,14 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
    utility will not be necessary when alias_sets_conflict_p will be
    less conservative.  */
 
-bool
-array_base_name_differ_p (struct data_reference *a,
-                          struct data_reference *b,
-                          bool *differ_p)
+static bool
+base_object_differ_p (struct data_reference *a,
+                     struct data_reference *b,
+                     bool *differ_p)
 {
-  tree base_a = DR_BASE_NAME (a);
-  tree base_b = DR_BASE_NAME (b);
+  tree base_a = DR_BASE_OBJECT (a);
+  tree base_b = DR_BASE_OBJECT (b);
+  bool aliased;
 
   if (!base_a || !base_b)
     return false;
@@ -152,6 +327,26 @@ array_base_name_differ_p (struct data_reference *a,
       return true;
     }
 
+  /* In case one of the bases is a pointer (a[i] and (*p)[i]), we check with the
+     help of alias analysis that p is not pointing to a.  */
+  if (array_ptr_differ_p (base_a, base_b, b) 
+      || array_ptr_differ_p (base_b, base_a, a))
+    {
+      *differ_p = true;
+      return true;
+    }
+
+  /* If the bases are pointers ((*q)[i] and (*p)[i]), we check with the
+     help of alias analysis they don't point to the same bases.  */
+  if (TREE_CODE (base_a) == INDIRECT_REF && TREE_CODE (base_b) == INDIRECT_REF 
+      && (may_alias_p (TREE_OPERAND (base_a, 0), TREE_OPERAND (base_b, 0), a, b, 
+                      &aliased)
+         && !aliased))
+    {
+      *differ_p = true;
+      return true;
+    }
+
   /* Compare two record/union bases s.a and t.b: s != t or (a != b and
      s and t are not unions).  */
   if (TREE_CODE (base_a) == COMPONENT_REF && TREE_CODE (base_b) == COMPONENT_REF
@@ -166,13 +361,18 @@ array_base_name_differ_p (struct data_reference *a,
       return true;
     }
 
-  /* Compare a record/union access and an array access.  */ 
-  if ((TREE_CODE (base_a) == VAR_DECL
-       && (TREE_CODE (base_b) == COMPONENT_REF
-           && TREE_CODE (TREE_OPERAND (base_b, 0)) == VAR_DECL))
-      || (TREE_CODE (base_b) == VAR_DECL
-       && (TREE_CODE (base_a) == COMPONENT_REF
-           && TREE_CODE (TREE_OPERAND (base_a, 0)) == VAR_DECL)))
+  /* Compare a record/union access (b.c[i] or p->c[i]) and a pointer
+     ((*q)[i]).  */
+  if (record_ptr_differ_p (a, b) || record_ptr_differ_p (b, a))
+    {
+      *differ_p = true;
+      return true;
+    }
+
+  /* Compare a record/union access (b.c[i] or p->c[i]) and an array access 
+     (a[i]). In case of p->c[i] use alias analysis to verify that p is not
+     pointing to a.  */
+  if (record_array_differ_p (a, b) || record_array_differ_p (b, a))
     {
       *differ_p = true;
       return true;
@@ -181,6 +381,90 @@ array_base_name_differ_p (struct data_reference *a,
   return false;
 }
 
+/* Function 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
+base_addr_differ_p (struct data_reference *dra,
+                   struct data_reference *drb,
+                   bool *differ_p)
+{
+  tree addr_a = DR_BASE_ADDRESS (dra);
+  tree addr_b = DR_BASE_ADDRESS (drb);
+  tree type_a, type_b;
+  bool aliased;
+
+  if (!addr_a || !addr_b)
+    return false;
+
+  type_a = TREE_TYPE (addr_a);
+  type_b = TREE_TYPE (addr_b);
+
+  gcc_assert (POINTER_TYPE_P (type_a) &&  POINTER_TYPE_P (type_b));
+  
+  /* Compare base objects first if possible. If DR_BASE_OBJECT is NULL, it means
+     that the data-ref is of INDIRECT_REF, and alias analysis will be applied to 
+     reveal the dependence.  */
+  if (DR_BASE_OBJECT (dra) && DR_BASE_OBJECT (drb))
+    return base_object_differ_p (dra, drb, differ_p);
+
+  /* If base addresses are the same, we check the offsets, since the access of 
+     the data-ref is described by {base addr + offset} and its access function,
+     i.e., in order to decide whether the bases of data-refs are the same we 
+     compare both base addresses and offsets.  */
+  if (addr_a == addr_b 
+      || (TREE_CODE (addr_a) == ADDR_EXPR && TREE_CODE (addr_b) == ADDR_EXPR
+         && TREE_OPERAND (addr_a, 0) == TREE_OPERAND (addr_b, 0)))
+    {
+      /* Compare offsets.  */
+      tree offset_a = DR_OFFSET (dra); 
+      tree offset_b = DR_OFFSET (drb);
+      
+      gcc_assert (!DR_BASE_OBJECT (dra) && !DR_BASE_OBJECT (drb));
+
+      STRIP_NOPS (offset_a);
+      STRIP_NOPS (offset_b);
+
+      /* FORNOW: we only compare offsets that are MULT_EXPR, i.e., we don't handle
+        PLUS_EXPR.  */
+      if ((offset_a == offset_b)
+         || (TREE_CODE (offset_a) == MULT_EXPR 
+             && TREE_CODE (offset_b) == MULT_EXPR
+             && TREE_OPERAND (offset_a, 0) == TREE_OPERAND (offset_b, 0)
+             && TREE_OPERAND (offset_a, 1) == TREE_OPERAND (offset_b, 1)))
+       {
+         *differ_p = false;
+         return true;
+       }
+    }
+
+  /* Apply alias analysis.  */
+  if (may_alias_p (addr_a, addr_b, dra, drb, &aliased) && !aliased)
+    {
+      *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;
+}
+
+
 /* Returns true iff A divides B.  */
 
 static inline bool 
@@ -262,7 +546,7 @@ dump_data_reference (FILE *outf,
   fprintf (outf, "  ref: ");
   print_generic_stmt (outf, DR_REF (dr), 0);
   fprintf (outf, "  base_name: ");
-  print_generic_stmt (outf, DR_BASE_NAME (dr), 0);
+  print_generic_stmt (outf, DR_BASE_OBJECT (dr), 0);
   
   for (i = 0; i < DR_NUM_DIMENSIONS (dr); i++)
     {
@@ -546,10 +830,11 @@ analyze_array_indexes (struct loop *loop,
    set to true when REF is in the right hand side of an
    assignment.  */
 
-struct data_reference *
+static struct data_reference *
 analyze_array (tree stmt, tree ref, bool is_read)
 {
   struct data_reference *res;
+  VEC(tree,heap) *acc_fns;
 
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
@@ -563,10 +848,19 @@ analyze_array (tree stmt, tree ref, bool is_read)
   
   DR_STMT (res) = stmt;
   DR_REF (res) = ref;
-  DR_ACCESS_FNS (res) = VEC_alloc (tree, heap, 3);
-  DR_BASE_NAME (res) = analyze_array_indexes 
-    (loop_containing_stmt (stmt), &(DR_ACCESS_FNS (res)), ref, stmt);
+  acc_fns = VEC_alloc (tree, heap, 3);
+  DR_BASE_OBJECT (res) = analyze_array_indexes 
+    (loop_containing_stmt (stmt), &acc_fns, ref, stmt);
+  DR_TYPE (res) = ARRAY_REF_TYPE;
+  DR_SET_ACCESS_FNS (res, acc_fns);
   DR_IS_READ (res) = is_read;
+  DR_BASE_ADDRESS (res) = NULL_TREE;
+  DR_OFFSET (res) = NULL_TREE;
+  DR_INIT (res) = NULL_TREE;
+  DR_STEP (res) = NULL_TREE;
+  DR_OFFSET_MISALIGNMENT (res) = NULL_TREE;
+  DR_MEMTAG (res) = NULL_TREE;
+  DR_PTR_INFO (res) = NULL;
   
   if (dump_file && (dump_flags & TDF_DETAILS))
     fprintf (dump_file, ")\n");
@@ -574,6 +868,76 @@ analyze_array (tree stmt, tree ref, bool is_read)
   return res;
 }
 
+
+/* Analyze an indirect memory reference, REF, that comes from STMT.
+   IS_READ is true if this is an indirect load, and false if it is
+   an indirect store.
+   Return a new data reference structure representing the indirect_ref, or
+   NULL if we cannot describe the access function.  */
+  
+static struct data_reference *
+analyze_indirect_ref (tree stmt, tree ref, bool is_read) 
+{
+  struct loop *loop = loop_containing_stmt (stmt);
+  tree ptr_ref = TREE_OPERAND (ref, 0);
+  tree access_fn = analyze_scalar_evolution (loop, ptr_ref);
+  tree init = initial_condition_in_loop_num (access_fn, loop->num);
+  tree base_address = NULL_TREE, evolution, step = NULL_TREE;
+  struct ptr_info_def *ptr_info = NULL;
+
+  if (TREE_CODE (ptr_ref) == SSA_NAME)
+    ptr_info = SSA_NAME_PTR_INFO (ptr_ref);
+
+  STRIP_NOPS (init);   
+  if (access_fn == chrec_dont_know || !init || init == chrec_dont_know)
+    {
+      if (dump_file && (dump_flags & TDF_DETAILS))
+       {
+         fprintf (dump_file, "\nBad access function of ptr: ");
+         print_generic_expr (dump_file, ref, TDF_SLIM);
+         fprintf (dump_file, "\n");
+       }
+      return NULL;
+    }
+
+  if (dump_file && (dump_flags & TDF_DETAILS))
+    {
+      fprintf (dump_file, "\nAccess function of ptr: ");
+      print_generic_expr (dump_file, access_fn, TDF_SLIM);
+      fprintf (dump_file, "\n");
+    }
+
+  if (!expr_invariant_in_loop_p (loop, init))
+    {
+    if (dump_file && (dump_flags & TDF_DETAILS))
+       fprintf (dump_file, "\ninitial condition is not loop invariant.\n");    
+    }
+  else
+    {
+      base_address = init;
+      evolution = evolution_part_in_loop_num (access_fn, loop->num);
+      if (evolution != chrec_dont_know)
+       {       
+         if (!evolution)
+           step = ssize_int (0);
+         else  
+           {
+             if (TREE_CODE (evolution) == INTEGER_CST)
+               step = fold_convert (ssizetype, evolution);
+             else
+               if (dump_file && (dump_flags & TDF_DETAILS))
+                 fprintf (dump_file, "\nnon constant step for ptr access.\n"); 
+           }
+       }
+      else
+       if (dump_file && (dump_flags & TDF_DETAILS))
+         fprintf (dump_file, "\nunknown evolution of ptr.\n"); 
+    }
+  return init_data_ref (stmt, ref, NULL_TREE, access_fn, is_read, base_address, 
+                       NULL_TREE, step, NULL_TREE, NULL_TREE, 
+                       ptr_info, POINTER_REF_TYPE);
+}
+
 /* For a data reference REF contained in the statement STMT, initialize
    a DATA_REFERENCE structure, and return it.  */
 
@@ -582,9 +946,17 @@ init_data_ref (tree stmt,
               tree ref,
               tree base,
               tree access_fn,
-              bool is_read)
+              bool is_read,
+              tree base_address,
+              tree init_offset,
+              tree step,
+              tree misalign,
+              tree memtag,
+               struct ptr_info_def *ptr_info,
+              enum data_ref_type type)
 {
   struct data_reference *res;
+  VEC(tree,heap) *acc_fns;
 
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
@@ -598,10 +970,19 @@ init_data_ref (tree stmt,
   
   DR_STMT (res) = stmt;
   DR_REF (res) = ref;
-  DR_ACCESS_FNS (res) = VEC_alloc (tree, heap, 5);
-  DR_BASE_NAME (res) = base;
+  DR_BASE_OBJECT (res) = base;
+  DR_TYPE (res) = type;
+  acc_fns = VEC_alloc (tree, heap, 3);
+  DR_SET_ACCESS_FNS (res, acc_fns);
   VEC_quick_push (tree, DR_ACCESS_FNS (res), access_fn);
   DR_IS_READ (res) = is_read;
+  DR_BASE_ADDRESS (res) = base_address;
+  DR_OFFSET (res) = init_offset;
+  DR_INIT (res) = NULL_TREE;
+  DR_STEP (res) = step;
+  DR_OFFSET_MISALIGNMENT (res) = misalign;
+  DR_MEMTAG (res) = memtag;
+  DR_PTR_INFO (res) = ptr_info;
   
   if (dump_file && (dump_flags & TDF_DETAILS))
     fprintf (dump_file, ")\n");
@@ -611,6 +992,869 @@ init_data_ref (tree stmt,
 
 \f
 
+/* Function strip_conversions
+
+   Strip conversions that don't narrow the mode.  */
+
+static tree 
+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; 
+}
+\f
+
+/* Function analyze_offset_expr
+
+   Given an offset expression EXPR received from get_inner_reference, analyze
+   it and create an expression for INITIAL_OFFSET by substituting the variables 
+   of EXPR with initial_condition of the corresponding access_fn in the loop. 
+   E.g., 
+      for i
+         for (j = 3; j < N; j++)
+            a[j].b[i][j] = 0;
+        
+   For a[j].b[i][j], EXPR will be 'i * C_i + j * C_j + C'. 'i' cannot be 
+   substituted, since its access_fn in the inner loop is i. 'j' will be 
+   substituted with 3. An INITIAL_OFFSET will be 'i * C_i + C`', where
+   C` =  3 * C_j + C.
+
+   Compute MISALIGN (the misalignment of the data reference initial access from
+   its base). Misalignment can be calculated only if all the variables can be 
+   substituted with constants, otherwise, we record maximum possible alignment
+   in ALIGNED_TO. In the above example, since 'i' cannot be substituted, MISALIGN 
+   will be NULL_TREE, and the biggest divider of C_i (a power of 2) will be 
+   recorded in ALIGNED_TO.
+
+   STEP is an evolution of the data reference in this loop in bytes.
+   In the above example, STEP is C_j.
+
+   Return FALSE, if the analysis fails, e.g., there is no access_fn for a 
+   variable. In this case, all the outputs (INITIAL_OFFSET, MISALIGN, ALIGNED_TO
+   and STEP) are NULL_TREEs. Otherwise, return TRUE.
+
+*/
+
+static bool
+analyze_offset_expr (tree expr, 
+                    struct loop *loop, 
+                    tree *initial_offset,
+                    tree *misalign,
+                    tree *aligned_to,
+                    tree *step)
+{
+  tree oprnd0;
+  tree oprnd1;
+  tree left_offset = ssize_int (0);
+  tree right_offset = ssize_int (0);
+  tree left_misalign = ssize_int (0);
+  tree right_misalign = ssize_int (0);
+  tree left_step = ssize_int (0);
+  tree right_step = ssize_int (0);
+  enum tree_code code;
+  tree init, evolution;
+  tree left_aligned_to = NULL_TREE, right_aligned_to = NULL_TREE;
+
+  *step = NULL_TREE;
+  *misalign = NULL_TREE;
+  *aligned_to = NULL_TREE;  
+  *initial_offset = NULL_TREE;
+
+  /* Strip conversions that don't narrow the mode.  */
+  expr = strip_conversion (expr);
+  if (!expr)
+    return false;
+
+  /* Stop conditions:
+     1. Constant.  */
+  if (TREE_CODE (expr) == INTEGER_CST)
+    {
+      *initial_offset = fold_convert (ssizetype, expr);
+      *misalign = fold_convert (ssizetype, expr);      
+      *step = ssize_int (0);
+      return true;
+    }
+
+  /* 2. Variable. Try to substitute with initial_condition of the corresponding
+     access_fn in the current loop.  */
+  if (SSA_VAR_P (expr))
+    {
+      tree access_fn = analyze_scalar_evolution (loop, expr);
+
+      if (access_fn == chrec_dont_know)
+       /* No access_fn.  */
+       return false;
+
+      init = initial_condition_in_loop_num (access_fn, loop->num);
+      if (init == expr && !expr_invariant_in_loop_p (loop, init))
+       /* Not enough information: may be not loop invariant.  
+          E.g., for a[b[i]], we get a[D], where D=b[i]. EXPR is D, its 
+          initial_condition is D, but it depends on i - loop's induction
+          variable.  */          
+       return false;
+
+      evolution = evolution_part_in_loop_num (access_fn, loop->num);
+      if (evolution && TREE_CODE (evolution) != INTEGER_CST)
+       /* Evolution is not constant.  */
+       return false;
+
+      if (TREE_CODE (init) == INTEGER_CST)
+       *misalign = fold_convert (ssizetype, init);
+      else
+       /* Not constant, misalignment cannot be calculated.  */
+       *misalign = NULL_TREE;
+
+      *initial_offset = fold_convert (ssizetype, init); 
+
+      *step = evolution ? fold_convert (ssizetype, evolution) : ssize_int (0);
+      return true;      
+    }
+
+  /* Recursive computation.  */
+  if (!BINARY_CLASS_P (expr))
+    {
+      /* We expect to get binary expressions (PLUS/MINUS and MULT).  */
+      if (dump_file && (dump_flags & TDF_DETAILS))
+        {
+         fprintf (dump_file, "\nNot binary expression ");
+          print_generic_expr (dump_file, expr, TDF_SLIM);
+         fprintf (dump_file, "\n");
+       }
+      return false;
+    }
+  oprnd0 = TREE_OPERAND (expr, 0);
+  oprnd1 = TREE_OPERAND (expr, 1);
+
+  if (!analyze_offset_expr (oprnd0, loop, &left_offset, &left_misalign, 
+                           &left_aligned_to, &left_step)
+      || !analyze_offset_expr (oprnd1, loop, &right_offset, &right_misalign, 
+                              &right_aligned_to, &right_step))
+    return false;
+
+  /* The type of the operation: plus, minus or mult.  */
+  code = TREE_CODE (expr);
+  switch (code)
+    {
+    case MULT_EXPR:
+      if (TREE_CODE (right_offset) != INTEGER_CST)
+       /* RIGHT_OFFSET can be not constant. For example, for arrays of variable 
+          sized types. 
+          FORNOW: We don't support such cases.  */
+       return false;
+
+      /* Strip conversions that don't narrow the mode.  */
+      left_offset = strip_conversion (left_offset);      
+      if (!left_offset)
+       return false;      
+      /* Misalignment computation.  */
+      if (SSA_VAR_P (left_offset))
+       {
+         /* If the left side contains variables that can't be substituted with 
+            constants, the misalignment is unknown. However, if the right side 
+            is a multiple of some alignment, we know that the expression is
+            aligned to it. Therefore, we record such maximum possible value.
+          */
+         *misalign = NULL_TREE;
+         *aligned_to = ssize_int (highest_pow2_factor (right_offset));
+       }
+      else 
+       {
+         /* The left operand was successfully substituted with constant.  */     
+         if (left_misalign)
+           {
+             /* In case of EXPR '(i * C1 + j) * C2', LEFT_MISALIGN is 
+                NULL_TREE.  */
+             *misalign  = size_binop (code, left_misalign, right_misalign);
+             if (left_aligned_to && right_aligned_to)
+               *aligned_to = size_binop (MIN_EXPR, left_aligned_to, 
+                                         right_aligned_to);
+             else 
+               *aligned_to = left_aligned_to ? 
+                 left_aligned_to : right_aligned_to;
+           }
+         else
+           *misalign = NULL_TREE; 
+       }
+
+      /* Step calculation.  */
+      /* Multiply the step by the right operand.  */
+      *step  = size_binop (MULT_EXPR, left_step, right_offset);
+      break;
+   
+    case PLUS_EXPR:
+    case MINUS_EXPR:
+      /* Combine the recursive calculations for step and misalignment.  */
+      *step = size_binop (code, left_step, right_step);
+
+      /* Unknown alignment.  */
+      if ((!left_misalign && !left_aligned_to)
+         || (!right_misalign && !right_aligned_to))
+       {
+         *misalign = NULL_TREE;
+         *aligned_to = NULL_TREE;
+         break;
+       }
+
+      if (left_misalign && right_misalign)
+       *misalign = size_binop (code, left_misalign, right_misalign);
+      else
+       *misalign = left_misalign ? left_misalign : right_misalign;
+
+      if (left_aligned_to && right_aligned_to)
+       *aligned_to = size_binop (MIN_EXPR, left_aligned_to, right_aligned_to);
+      else 
+       *aligned_to = left_aligned_to ? left_aligned_to : right_aligned_to;
+
+      break;
+
+    default:
+      gcc_unreachable ();
+    }
+
+  /* Compute offset.  */
+  *initial_offset = fold_convert (ssizetype, 
+                                 fold_build2 (code, TREE_TYPE (left_offset), 
+                                              left_offset, 
+                                              right_offset));
+  return true;
+}
+
+/* Function address_analysis
+
+   Return the BASE of the address expression EXPR.
+   Also compute the OFFSET from BASE, MISALIGN and STEP.
+
+   Input:
+   EXPR - the address expression that is being analyzed
+   STMT - the statement that contains EXPR or its original memory reference
+   IS_READ - TRUE if STMT reads from EXPR, FALSE if writes to EXPR
+   DR - data_reference struct for the original memory reference
+
+   Output:
+   BASE (returned value) - the base of the data reference EXPR.
+   INITIAL_OFFSET - initial offset of EXPR from BASE (an expression)
+   MISALIGN - offset of EXPR from BASE in bytes (a constant) or NULL_TREE if the
+              computation is impossible 
+   ALIGNED_TO - maximum alignment of EXPR or NULL_TREE if MISALIGN can be 
+                calculated (doesn't depend on variables)
+   STEP - evolution of EXPR in the loop
+   If something unexpected is encountered (an unsupported form of data-ref),
+   then NULL_TREE is returned.  
+ */
+
+static tree
+address_analysis (tree expr, tree stmt, bool is_read, struct data_reference *dr, 
+                 tree *offset, tree *misalign, tree *aligned_to, tree *step)
+{
+  tree oprnd0, oprnd1, base_address, offset_expr, base_addr0, base_addr1;
+  tree address_offset = ssize_int (0), address_misalign = ssize_int (0);
+  tree dummy, address_aligned_to = NULL_TREE;
+  struct ptr_info_def *dummy1;
+  subvar_t dummy2;
+
+  switch (TREE_CODE (expr))
+    {
+    case PLUS_EXPR:
+    case MINUS_EXPR:
+      /* EXPR is of form {base +/- offset} (or {offset +/- base}).  */
+      oprnd0 = TREE_OPERAND (expr, 0);
+      oprnd1 = TREE_OPERAND (expr, 1);
+
+      STRIP_NOPS (oprnd0);
+      STRIP_NOPS (oprnd1);
+      
+      /* Recursively try to find the base of the address contained in EXPR.
+        For offset, the returned base will be NULL.  */
+      base_addr0 = address_analysis (oprnd0, stmt, is_read, dr, &address_offset, 
+                                    &address_misalign, &address_aligned_to, 
+                                    step);
+
+      base_addr1 = address_analysis (oprnd1, stmt, is_read,  dr, &address_offset, 
+                                    &address_misalign, &address_aligned_to, 
+                                    step);
+
+      /* We support cases where only one of the operands contains an 
+        address.  */
+      if ((base_addr0 && base_addr1) || (!base_addr0 && !base_addr1))
+       {
+         if (dump_file && (dump_flags & TDF_DETAILS))
+           {
+             fprintf (dump_file, 
+                   "\neither more than one address or no addresses in expr ");
+             print_generic_expr (dump_file, expr, TDF_SLIM);
+             fprintf (dump_file, "\n");
+           }   
+         return NULL_TREE;
+       }
+
+      /* To revert STRIP_NOPS.  */
+      oprnd0 = TREE_OPERAND (expr, 0);
+      oprnd1 = TREE_OPERAND (expr, 1);
+      
+      offset_expr = base_addr0 ? 
+       fold_convert (ssizetype, oprnd1) : fold_convert (ssizetype, oprnd0);
+
+      /* EXPR is of form {base +/- offset} (or {offset +/- base}). If offset is 
+        a number, we can add it to the misalignment value calculated for base,
+        otherwise, misalignment is NULL.  */
+      if (TREE_CODE (offset_expr) == INTEGER_CST && address_misalign)
+       {
+         *misalign = size_binop (TREE_CODE (expr), address_misalign, 
+                                 offset_expr);
+         *aligned_to = address_aligned_to;
+       }
+      else
+       {
+         *misalign = NULL_TREE;
+         *aligned_to = NULL_TREE;
+       }
+
+      /* Combine offset (from EXPR {base + offset}) with the offset calculated
+        for base.  */
+      *offset = size_binop (TREE_CODE (expr), address_offset, offset_expr);
+      return base_addr0 ? base_addr0 : base_addr1;
+
+    case ADDR_EXPR:
+      base_address = object_analysis (TREE_OPERAND (expr, 0), stmt, is_read, 
+                                     &dr, offset, misalign, aligned_to, step, 
+                                     &dummy, &dummy1, &dummy2);
+      return base_address;
+
+    case SSA_NAME:
+      if (!POINTER_TYPE_P (TREE_TYPE (expr)))
+       {
+         if (dump_file && (dump_flags & TDF_DETAILS))
+           {
+             fprintf (dump_file, "\nnot pointer SSA_NAME ");
+             print_generic_expr (dump_file, expr, TDF_SLIM);
+             fprintf (dump_file, "\n");
+           }   
+         return NULL_TREE;
+       }
+      *aligned_to = ssize_int (TYPE_ALIGN_UNIT (TREE_TYPE (TREE_TYPE (expr))));
+      *misalign = ssize_int (0);
+      *offset = ssize_int (0);
+      *step = ssize_int (0);
+      return expr;
+      
+    default:
+      return NULL_TREE;
+    }
+}
+
+
+/* Function object_analysis
+
+   Create a data-reference structure DR for MEMREF.
+   Return the BASE of the data reference MEMREF if the analysis is possible.
+   Also compute the INITIAL_OFFSET from BASE, MISALIGN and STEP.
+   E.g., for EXPR a.b[i] + 4B, BASE is a, and OFFSET is the overall offset  
+   'a.b[i] + 4B' from a (can be an expression), MISALIGN is an OFFSET 
+   instantiated with initial_conditions of access_functions of variables, 
+   and STEP is the evolution of the DR_REF in this loop.
+   
+   Function get_inner_reference is used for the above in case of ARRAY_REF and
+   COMPONENT_REF.
+
+   The structure of the function is as follows:
+   Part 1:
+   Case 1. For handled_component_p refs 
+          1.1 build data-reference structure for MEMREF
+          1.2 call get_inner_reference
+            1.2.1 analyze offset expr received from get_inner_reference
+          (fall through with BASE)
+   Case 2. For declarations 
+          2.1 set MEMTAG
+   Case 3. For INDIRECT_REFs 
+          3.1 build data-reference structure for MEMREF
+         3.2 analyze evolution and initial condition of MEMREF
+         3.3 set data-reference structure for MEMREF
+          3.4 call address_analysis to analyze INIT of the access function
+         3.5 extract memory tag
+
+   Part 2:
+   Combine the results of object and address analysis to calculate 
+   INITIAL_OFFSET, STEP and misalignment info.   
+
+   Input:
+   MEMREF - the memory reference that is being analyzed
+   STMT - the statement that contains MEMREF
+   IS_READ - TRUE if STMT reads from MEMREF, FALSE if writes to MEMREF
+   
+   Output:
+   BASE_ADDRESS (returned value) - the base address of the data reference MEMREF
+                                   E.g, if MEMREF is a.b[k].c[i][j] the returned
+                                  base is &a.
+   DR - data_reference struct for MEMREF
+   INITIAL_OFFSET - initial offset of MEMREF from BASE (an expression)
+   MISALIGN - offset of MEMREF from BASE in bytes (a constant) modulo alignment of 
+              ALIGNMENT or NULL_TREE if the computation is impossible
+   ALIGNED_TO - maximum alignment of EXPR or NULL_TREE if MISALIGN can be 
+                calculated (doesn't depend on variables)
+   STEP - evolution of the DR_REF in the loop
+   MEMTAG - memory tag for aliasing purposes
+   PTR_INFO - NULL or points-to aliasing info from a pointer SSA_NAME
+   SUBVARS - Sub-variables of the variable
+
+   If the analysis of MEMREF evolution in the loop fails, NULL_TREE is returned, 
+   but DR can be created anyway.
+   
+*/
+static tree
+object_analysis (tree memref, tree stmt, bool is_read, 
+                struct data_reference **dr, tree *offset, tree *misalign, 
+                tree *aligned_to, tree *step, tree *memtag,
+                struct ptr_info_def **ptr_info, subvar_t *subvars)
+{
+  tree base = NULL_TREE, base_address = NULL_TREE;
+  tree object_offset = ssize_int (0), object_misalign = ssize_int (0);
+  tree object_step = ssize_int (0), address_step = ssize_int (0);
+  tree address_offset = ssize_int (0), address_misalign = ssize_int (0);
+  HOST_WIDE_INT pbitsize, pbitpos;
+  tree poffset, bit_pos_in_bytes;
+  enum machine_mode pmode;
+  int punsignedp, pvolatilep;
+  tree ptr_step = ssize_int (0), ptr_init = NULL_TREE;
+  struct loop *loop = loop_containing_stmt (stmt);
+  struct data_reference *ptr_dr = NULL;
+  tree object_aligned_to = NULL_TREE, address_aligned_to = NULL_TREE;
+
+ *ptr_info = NULL;
+
+  /* Part 1:  */
+  /* Case 1. handled_component_p refs.  */
+  if (handled_component_p (memref))
+    {
+      /* 1.1 build data-reference structure for MEMREF.  */
+      /* TODO: handle COMPONENT_REFs.  */
+      if (!(*dr))
+       { 
+         if (TREE_CODE (memref) == ARRAY_REF)
+           *dr = analyze_array (stmt, memref, is_read);          
+         else
+           {
+             /* FORNOW.  */
+             if (dump_file && (dump_flags & TDF_DETAILS))
+               {
+                 fprintf (dump_file, "\ndata-ref of unsupported type ");
+                 print_generic_expr (dump_file, memref, TDF_SLIM);
+                 fprintf (dump_file, "\n");
+               }
+             return NULL_TREE;
+           }
+       }
+
+      /* 1.2 call get_inner_reference.  */
+      /* Find the base and the offset from it.  */
+      base = get_inner_reference (memref, &pbitsize, &pbitpos, &poffset,
+                                 &pmode, &punsignedp, &pvolatilep, false);
+      if (!base)
+       {
+         if (dump_file && (dump_flags & TDF_DETAILS))
+           {
+             fprintf (dump_file, "\nfailed to get inner ref for ");
+             print_generic_expr (dump_file, memref, TDF_SLIM);
+             fprintf (dump_file, "\n");
+           }     
+         return NULL_TREE;
+       }
+
+      /* 1.2.1 analyze offset expr received from get_inner_reference.  */
+      if (poffset 
+         && !analyze_offset_expr (poffset, loop, &object_offset, 
+                                  &object_misalign, &object_aligned_to,
+                                  &object_step))
+       {
+         if (dump_file && (dump_flags & TDF_DETAILS))
+           {
+             fprintf (dump_file, "\nfailed to compute offset or step for ");
+             print_generic_expr (dump_file, memref, TDF_SLIM);
+             fprintf (dump_file, "\n");
+           }
+         return NULL_TREE;
+       }
+
+      /* Add bit position to OFFSET and MISALIGN.  */
+
+      bit_pos_in_bytes = ssize_int (pbitpos/BITS_PER_UNIT);
+      /* Check that there is no remainder in bits.  */
+      if (pbitpos%BITS_PER_UNIT)
+       {
+         if (dump_file && (dump_flags & TDF_DETAILS))
+           fprintf (dump_file, "\nbit offset alignment.\n");
+         return NULL_TREE;
+       }
+      object_offset = size_binop (PLUS_EXPR, bit_pos_in_bytes, object_offset);     
+      if (object_misalign) 
+       object_misalign = size_binop (PLUS_EXPR, object_misalign, 
+                                     bit_pos_in_bytes); 
+      
+      memref = base; /* To continue analysis of BASE.  */
+      /* fall through  */
+    }
+  
+  /*  Part 1: Case 2. Declarations.  */ 
+  if (DECL_P (memref))
+    {
+      /* We expect to get a decl only if we already have a DR.  */
+      if (!(*dr))
+       {
+         if (dump_file && (dump_flags & TDF_DETAILS))
+           {
+             fprintf (dump_file, "\nunhandled decl ");
+             print_generic_expr (dump_file, memref, TDF_SLIM);
+             fprintf (dump_file, "\n");
+           }
+         return NULL_TREE;
+       }
+
+      /* TODO: if during the analysis of INDIRECT_REF we get to an object, put 
+        the object in BASE_OBJECT field if we can prove that this is O.K., 
+        i.e., the data-ref access is bounded by the bounds of the BASE_OBJECT.
+        (e.g., if the object is an array base 'a', where 'a[N]', we must prove
+        that every access with 'p' (the original INDIRECT_REF based on '&a')
+        in the loop is within the array boundaries - from a[0] to a[N-1]).
+        Otherwise, our alias analysis can be incorrect.
+        Even if an access function based on BASE_OBJECT can't be build, update
+        BASE_OBJECT field to enable us to prove that two data-refs are 
+        different (without access function, distance analysis is impossible).
+      */
+     if (SSA_VAR_P (memref) && var_can_have_subvars (memref))  
+       *subvars = get_subvars_for_var (memref);
+      base_address = build_fold_addr_expr (memref);
+      /* 2.1 set MEMTAG.  */
+      *memtag = memref;
+    }
+
+  /* Part 1:  Case 3. INDIRECT_REFs.  */
+  else if (TREE_CODE (memref) == INDIRECT_REF)
+    {
+      tree ptr_ref = TREE_OPERAND (memref, 0);
+      if (TREE_CODE (ptr_ref) == SSA_NAME)
+        *ptr_info = SSA_NAME_PTR_INFO (ptr_ref);
+
+      /* 3.1 build data-reference structure for MEMREF.  */
+      ptr_dr = analyze_indirect_ref (stmt, memref, is_read);
+      if (!ptr_dr)
+       {
+         if (dump_file && (dump_flags & TDF_DETAILS))
+           {
+             fprintf (dump_file, "\nfailed to create dr for ");
+             print_generic_expr (dump_file, memref, TDF_SLIM);
+             fprintf (dump_file, "\n");
+           }   
+         return NULL_TREE;      
+       }
+
+      /* 3.2 analyze evolution and initial condition of MEMREF.  */
+      ptr_step = DR_STEP (ptr_dr);
+      ptr_init = DR_BASE_ADDRESS (ptr_dr);
+      if (!ptr_init || !ptr_step || !POINTER_TYPE_P (TREE_TYPE (ptr_init)))
+       {
+         *dr = (*dr) ? *dr : ptr_dr;
+         if (dump_file && (dump_flags & TDF_DETAILS))
+           {
+             fprintf (dump_file, "\nbad pointer access ");
+             print_generic_expr (dump_file, memref, TDF_SLIM);
+             fprintf (dump_file, "\n");
+           }
+         return NULL_TREE;
+       }
+
+      if (integer_zerop (ptr_step) && !(*dr))
+       {
+         if (dump_file && (dump_flags & TDF_DETAILS)) 
+           fprintf (dump_file, "\nptr is loop invariant.\n");  
+         *dr = ptr_dr;
+         return NULL_TREE;
+       
+         /* If there exists DR for MEMREF, we are analyzing the base of
+            handled component (PTR_INIT), which not necessary has evolution in 
+            the loop.  */
+       }
+      object_step = size_binop (PLUS_EXPR, object_step, ptr_step);
+
+      /* 3.3 set data-reference structure for MEMREF.  */
+      if (!*dr)
+        *dr = ptr_dr;
+
+      /* 3.4 call address_analysis to analyze INIT of the access 
+        function.  */
+      base_address = address_analysis (ptr_init, stmt, is_read, *dr, 
+                                      &address_offset, &address_misalign, 
+                                      &address_aligned_to, &address_step);
+      if (!base_address)
+       {
+         if (dump_file && (dump_flags & TDF_DETAILS))
+           {
+             fprintf (dump_file, "\nfailed to analyze address ");
+             print_generic_expr (dump_file, ptr_init, TDF_SLIM);
+             fprintf (dump_file, "\n");
+           }
+         return NULL_TREE;
+       }
+
+      /* 3.5 extract memory tag.  */
+      switch (TREE_CODE (base_address))
+       {
+       case SSA_NAME:
+         *memtag = get_var_ann (SSA_NAME_VAR (base_address))->type_mem_tag;
+         if (!(*memtag) && TREE_CODE (TREE_OPERAND (memref, 0)) == SSA_NAME)
+           *memtag = get_var_ann (
+                     SSA_NAME_VAR (TREE_OPERAND (memref, 0)))->type_mem_tag;
+         break;
+       case ADDR_EXPR:
+         *memtag = TREE_OPERAND (base_address, 0);
+         break;
+       default:
+         if (dump_file && (dump_flags & TDF_DETAILS))
+           {
+             fprintf (dump_file, "\nno memtag for "); 
+             print_generic_expr (dump_file, memref, TDF_SLIM);
+             fprintf (dump_file, "\n");
+           }
+         *memtag = NULL_TREE;
+         break;
+       }
+    }      
+    
+  if (!base_address)
+    {
+      /* MEMREF cannot be analyzed.  */
+      if (dump_file && (dump_flags & TDF_DETAILS))
+       {
+         fprintf (dump_file, "\ndata-ref of unsupported type ");
+         print_generic_expr (dump_file, memref, TDF_SLIM);
+         fprintf (dump_file, "\n");
+       }
+      return NULL_TREE;
+    }
+
+  if (SSA_VAR_P (*memtag) && var_can_have_subvars (*memtag))
+    *subvars = get_subvars_for_var (*memtag);
+       
+  /* Part 2: Combine the results of object and address analysis to calculate 
+     INITIAL_OFFSET, STEP and misalignment info.  */
+  *offset = size_binop (PLUS_EXPR, object_offset, address_offset);
+
+  if ((!object_misalign && !object_aligned_to)
+      || (!address_misalign && !address_aligned_to))
+    {
+      *misalign = NULL_TREE;
+      *aligned_to = NULL_TREE;
+    }  
+  else 
+    {
+      if (object_misalign && address_misalign)
+       *misalign = size_binop (PLUS_EXPR, object_misalign, address_misalign);
+      else
+       *misalign = object_misalign ? object_misalign : address_misalign;
+      if (object_aligned_to && address_aligned_to)
+       *aligned_to = size_binop (MIN_EXPR, object_aligned_to, 
+                                 address_aligned_to);
+      else
+       *aligned_to = object_aligned_to ? 
+         object_aligned_to : address_aligned_to; 
+    }
+  *step = size_binop (PLUS_EXPR, object_step, address_step); 
+
+  return base_address;
+}
+
+/* Function analyze_offset.
+   
+   Extract INVARIANT and CONSTANT parts from OFFSET. 
+
+*/
+static void 
+analyze_offset (tree offset, tree *invariant, tree *constant)
+{
+  tree op0, op1, constant_0, constant_1, invariant_0, invariant_1;
+  enum tree_code code = TREE_CODE (offset);
+
+  *invariant = NULL_TREE;
+  *constant = NULL_TREE;
+
+  /* Not PLUS/MINUS expression - recursion stop condition.  */
+  if (code != PLUS_EXPR && code != MINUS_EXPR)
+    {
+      if (TREE_CODE (offset) == INTEGER_CST)
+       *constant = offset;
+      else
+       *invariant = offset;
+      return;
+    }
+
+  op0 = TREE_OPERAND (offset, 0);
+  op1 = TREE_OPERAND (offset, 1);
+
+  /* Recursive call with the operands.  */
+  analyze_offset (op0, &invariant_0, &constant_0);
+  analyze_offset (op1, &invariant_1, &constant_1);
+
+  /* Combine the results.  */
+  *constant = constant_0 ? constant_0 : constant_1;
+  if (invariant_0 && invariant_1)
+    *invariant = 
+      fold (build (code, TREE_TYPE (invariant_0), invariant_0, invariant_1));
+  else
+    *invariant = invariant_0 ? invariant_0 : invariant_1;
+}
+
+
+/* Function create_data_ref.
+   
+   Create a data-reference structure for MEMREF. Set its DR_BASE_ADDRESS,
+   DR_OFFSET, DR_INIT, DR_STEP, DR_OFFSET_MISALIGNMENT, DR_ALIGNED_TO,
+   DR_MEMTAG, and DR_POINTSTO_INFO fields. 
+
+   Input:
+   MEMREF - the memory reference that is being analyzed
+   STMT - the statement that contains MEMREF
+   IS_READ - TRUE if STMT reads from MEMREF, FALSE if writes to MEMREF
+
+   Output:
+   DR (returned value) - data_reference struct for MEMREF
+*/
+
+static struct data_reference *
+create_data_ref (tree memref, tree stmt, bool is_read)
+{
+  struct data_reference *dr = NULL;
+  tree base_address, offset, step, misalign, memtag;
+  struct loop *loop = loop_containing_stmt (stmt);
+  tree invariant = NULL_TREE, constant = NULL_TREE;
+  tree type_size, init_cond;
+  struct ptr_info_def *ptr_info;
+  subvar_t subvars = NULL;
+  tree aligned_to;
+
+  if (!memref)
+    return NULL;
+
+  base_address = object_analysis (memref, stmt, is_read, &dr, &offset, 
+                                 &misalign, &aligned_to, &step, &memtag, 
+                                 &ptr_info, &subvars);
+  if (!dr || !base_address)
+    {
+      if (dump_file && (dump_flags & TDF_DETAILS))
+       {
+         fprintf (dump_file, "\ncreate_data_ref: failed to create a dr for ");
+         print_generic_expr (dump_file, memref, TDF_SLIM);
+         fprintf (dump_file, "\n");
+       }
+      return NULL;
+    }
+
+  DR_BASE_ADDRESS (dr) = base_address;
+  DR_OFFSET (dr) = offset;
+  DR_INIT (dr) = ssize_int (0);
+  DR_STEP (dr) = step;
+  DR_OFFSET_MISALIGNMENT (dr) = misalign;
+  DR_ALIGNED_TO (dr) = aligned_to;
+  DR_MEMTAG (dr) = memtag;
+  DR_PTR_INFO (dr) = ptr_info;
+  DR_SUBVARS (dr) = subvars;
+  
+  type_size = fold_convert (ssizetype, TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dr))));
+
+  /* Change the access function for INIDIRECT_REFs, according to 
+     DR_BASE_ADDRESS.  Analyze OFFSET calculated in object_analysis. OFFSET is 
+     an expression that can contain loop invariant expressions and constants.
+     We put the constant part in the initial condition of the access function
+     (for data dependence tests), and in DR_INIT of the data-ref. The loop
+     invariant part is put in DR_OFFSET. 
+     The evolution part of the access function is STEP calculated in
+     object_analysis divided by the size of data type.
+  */
+  if (!DR_BASE_OBJECT (dr))
+    {
+      tree access_fn;
+      tree new_step;
+
+      /* Extract CONSTANT and INVARIANT from OFFSET, and put them in DR_INIT and
+        DR_OFFSET fields of DR.  */
+      analyze_offset (offset, &invariant, &constant); 
+      if (constant)
+       {
+         DR_INIT (dr) = fold_convert (ssizetype, constant);
+         init_cond = fold (build (TRUNC_DIV_EXPR, TREE_TYPE (constant), 
+                                  constant, type_size));
+       }
+      else
+       DR_INIT (dr) = init_cond = ssize_int (0);;
+
+      if (invariant)
+       DR_OFFSET (dr) = invariant;
+      else
+       DR_OFFSET (dr) = ssize_int (0);
+
+      /* Update access function.  */
+      access_fn = DR_ACCESS_FN (dr, 0);
+      new_step = size_binop (TRUNC_DIV_EXPR,  
+                            fold_convert (ssizetype, step), type_size);
+
+      access_fn = chrec_replace_initial_condition (access_fn, init_cond);
+      access_fn = reset_evolution_in_loop (loop->num, access_fn, new_step);
+
+      VEC_replace (tree, DR_ACCESS_FNS (dr), 0, access_fn);
+    }
+
+  if (dump_file && (dump_flags & TDF_DETAILS))
+    {
+      struct ptr_info_def *pi = DR_PTR_INFO (dr);
+
+      fprintf (dump_file, "\nCreated dr for ");
+      print_generic_expr (dump_file, memref, TDF_SLIM);
+      fprintf (dump_file, "\n\tbase_address: ");
+      print_generic_expr (dump_file, DR_BASE_ADDRESS (dr), TDF_SLIM);
+      fprintf (dump_file, "\n\toffset from base address: ");
+      print_generic_expr (dump_file, DR_OFFSET (dr), TDF_SLIM);
+      fprintf (dump_file, "\n\tconstant offset from base address: ");
+      print_generic_expr (dump_file, DR_INIT (dr), TDF_SLIM);
+      fprintf (dump_file, "\n\tbase_object: ");
+      print_generic_expr (dump_file, DR_BASE_OBJECT (dr), TDF_SLIM);
+      fprintf (dump_file, "\n\tstep: ");
+      print_generic_expr (dump_file, DR_STEP (dr), TDF_SLIM);
+      fprintf (dump_file, "B\n\tmisalignment from base: ");
+      print_generic_expr (dump_file, DR_OFFSET_MISALIGNMENT (dr), TDF_SLIM);
+      if (DR_OFFSET_MISALIGNMENT (dr))
+       fprintf (dump_file, "B");
+      if (DR_ALIGNED_TO (dr))
+       {
+         fprintf (dump_file, "\n\taligned to: ");
+         print_generic_expr (dump_file, DR_ALIGNED_TO (dr), TDF_SLIM);
+       }
+      fprintf (dump_file, "\n\tmemtag: ");
+      print_generic_expr (dump_file, DR_MEMTAG (dr), TDF_SLIM);
+      fprintf (dump_file, "\n");
+      if (pi && pi->name_mem_tag)
+        {
+          fprintf (dump_file, "\n\tnametag: ");
+          print_generic_expr (dump_file, pi->name_mem_tag, TDF_SLIM);
+          fprintf (dump_file, "\n");
+        }
+    }  
+  return dr;  
+}
+
+
 /* Returns true when all the functions of a tree_vec CHREC are the
    same.  */
 
@@ -692,43 +1936,58 @@ initialize_data_dependence_relation (struct data_reference *a,
 {
   struct data_dependence_relation *res;
   bool differ_p;
+  unsigned int i;  
   
   res = xmalloc (sizeof (struct data_dependence_relation));
   DDR_A (res) = a;
   DDR_B (res) = b;
 
-  if (a == NULL || b == NULL 
-      || DR_BASE_NAME (a) == NULL_TREE
-      || DR_BASE_NAME (b) == NULL_TREE)
-    DDR_ARE_DEPENDENT (res) = chrec_dont_know;    
+  if (a == NULL || b == NULL)
+    {
+      DDR_ARE_DEPENDENT (res) = chrec_dont_know;    
+      return res;
+    }   
+
+  /* When A and B are arrays and their dimensions differ, we directly
+     initialize the relation to "there is no dependence": chrec_known.  */
+  if (DR_BASE_OBJECT (a) && DR_BASE_OBJECT (b)
+      && DR_NUM_DIMENSIONS (a) != DR_NUM_DIMENSIONS (b))
+    {
+      DDR_ARE_DEPENDENT (res) = chrec_known;
+      return res;
+    }
 
-  /* When the dimensions of A and B differ, we directly initialize
-     the relation to "there is no dependence": chrec_known.  */
-  else if (DR_NUM_DIMENSIONS (a) != DR_NUM_DIMENSIONS (b)
-          || (array_base_name_differ_p (a, b, &differ_p) && differ_p))
-    DDR_ARE_DEPENDENT (res) = chrec_known;
-  
-  else
+    /* Compare the bases of the data-refs.  */
+  if (!base_addr_differ_p (a, b, &differ_p))
     {
-      unsigned int i;
-      DDR_AFFINE_P (res) = true;
-      DDR_ARE_DEPENDENT (res) = NULL_TREE;
-      DDR_SUBSCRIPTS_VECTOR_INIT (res, DR_NUM_DIMENSIONS (a));
-      DDR_SIZE_VECT (res) = 0;
-      DDR_DIST_VECT (res) = NULL;
-      DDR_DIR_VECT (res) = NULL;
+      /* Can't determine whether the data-refs access the same memory 
+        region.  */
+      DDR_ARE_DEPENDENT (res) = chrec_dont_know;    
+      return res;
+    }
+  if (differ_p)
+    {
+      DDR_ARE_DEPENDENT (res) = chrec_known;    
+      return res;
+    }
+  
+  DDR_AFFINE_P (res) = true;
+  DDR_ARE_DEPENDENT (res) = NULL_TREE;
+  DDR_SUBSCRIPTS_VECTOR_INIT (res, DR_NUM_DIMENSIONS (a));
+  DDR_SIZE_VECT (res) = 0;
+  DDR_DIST_VECT (res) = NULL;
+  DDR_DIR_VECT (res) = NULL;
       
-      for (i = 0; i < DR_NUM_DIMENSIONS (a); i++)
-       {
-         struct subscript *subscript;
+  for (i = 0; i < DR_NUM_DIMENSIONS (a); i++)
+    {
+      struct subscript *subscript;
          
-         subscript = xmalloc (sizeof (struct subscript));
-         SUB_CONFLICTS_IN_A (subscript) = chrec_dont_know;
-         SUB_CONFLICTS_IN_B (subscript) = chrec_dont_know;
-         SUB_LAST_CONFLICT (subscript) = chrec_dont_know;
-         SUB_DISTANCE (subscript) = chrec_dont_know;
-         VARRAY_PUSH_GENERIC_PTR (DDR_SUBSCRIPTS (res), subscript);
-       }
+      subscript = xmalloc (sizeof (struct subscript));
+      SUB_CONFLICTS_IN_A (subscript) = chrec_dont_know;
+      SUB_CONFLICTS_IN_B (subscript) = chrec_dont_know;
+      SUB_LAST_CONFLICT (subscript) = chrec_dont_know;
+      SUB_DISTANCE (subscript) = chrec_dont_know;
+      VARRAY_PUSH_GENERIC_PTR (DDR_SUBSCRIPTS (res), subscript);
     }
   
   return res;
@@ -1768,7 +3027,7 @@ subscript_dependence_tester (struct data_dependence_relation *ddr)
    starting at FIRST_LOOP_DEPTH. 
    Return TRUE otherwise.  */
 
-bool
+static bool
 build_classic_dist_vector (struct data_dependence_relation *ddr, 
                           int nb_loops, int first_loop_depth)
 {
@@ -2123,7 +3382,7 @@ static bool
 access_functions_are_affine_or_constant_p (struct data_reference *a)
 {
   unsigned int i;
-  VEC(tree,heap) **fns = &DR_ACCESS_FNS (a);
+  VEC(tree,heap) **fns = DR_ACCESS_FNS_ADDR (a);
   tree t;
   
   for (i = 0; VEC_iterate (tree, *fns, i, t); i++)
@@ -2202,13 +3461,15 @@ DEF_VEC_P(ddr_p);
 DEF_VEC_ALLOC_P(ddr_p,heap);
 
 /* Compute a subset of the data dependence relation graph.  Don't
-   compute read-read relations, and avoid the computation of the
-   opposite relation, i.e. when AB has been computed, don't compute BA.
+   compute read-read and self relations if 
+   COMPUTE_SELF_AND_READ_READ_DEPENDENCES is FALSE, and avoid the computation 
+   of the opposite relation, i.e. when AB has been computed, don't compute BA.
    DATAREFS contains a list of data references, and the result is set
    in DEPENDENCE_RELATIONS.  */
 
 static void 
 compute_all_dependences (varray_type datarefs, 
+                        bool compute_self_and_read_read_dependences,
                         VEC(ddr_p,heap) **dependence_relations)
 {
   unsigned int i, j, N;
@@ -2226,12 +3487,17 @@ compute_all_dependences (varray_type datarefs,
 
        a = VARRAY_GENERIC_PTR (datarefs, i);
        b = VARRAY_GENERIC_PTR (datarefs, j);
+       if (DR_IS_READ (a) && DR_IS_READ (b)
+            && !compute_self_and_read_read_dependences)
+         continue;
        ddr = initialize_data_dependence_relation (a, b);
 
        VEC_safe_push (ddr_p, heap, *dependence_relations, ddr);
        compute_affine_dependence (ddr);
        compute_subscript_distance (ddr);
       }
+  if (!compute_self_and_read_read_dependences)
+    return;
 
   /* Compute self dependence relation of each dataref to itself.  */
 
@@ -2263,6 +3529,7 @@ find_data_references_in_loop (struct loop *loop, varray_type *datarefs)
   basic_block bb, *bbs;
   unsigned int i;
   block_stmt_iterator bsi;
+  struct data_reference *dr;
 
   bbs = get_loop_body (loop);
 
@@ -2289,33 +3556,55 @@ find_data_references_in_loop (struct loop *loop, varray_type *datarefs)
          switch (TREE_CODE (stmt))
            {
            case MODIFY_EXPR:
-             if (TREE_CODE (TREE_OPERAND (stmt, 0)) == ARRAY_REF)
-               VARRAY_PUSH_GENERIC_PTR 
-                 (*datarefs, analyze_array (stmt, TREE_OPERAND (stmt, 0),
-                                            false));
-
-             if (TREE_CODE (TREE_OPERAND (stmt, 1)) == ARRAY_REF)
-               VARRAY_PUSH_GENERIC_PTR 
-                 (*datarefs, analyze_array (stmt, TREE_OPERAND (stmt, 1),
-                                            true));
+             {
+               bool one_inserted = false;
+               tree opnd0 = TREE_OPERAND (stmt, 0);
+               tree opnd1 = TREE_OPERAND (stmt, 1);
+               
+               if (TREE_CODE (opnd0) == ARRAY_REF 
+                   || TREE_CODE (opnd0) == INDIRECT_REF)
+                 {
+                   dr = create_data_ref (opnd0, stmt, false);
+                   if (dr) 
+                     {
+                       VARRAY_PUSH_GENERIC_PTR (*datarefs, dr);
+                       one_inserted = true;
+                     }
+                 }
+
+               if (TREE_CODE (opnd1) == ARRAY_REF 
+                   || TREE_CODE (opnd1) == INDIRECT_REF)
+                 {
+                   dr = create_data_ref (opnd1, stmt, true);
+                   if (dr) 
+                     {
+                       VARRAY_PUSH_GENERIC_PTR (*datarefs, dr);
+                       one_inserted = true;
+                     }
+                 }
 
-             if (TREE_CODE (TREE_OPERAND (stmt, 0)) != ARRAY_REF
-                 && TREE_CODE (TREE_OPERAND (stmt, 1)) != ARRAY_REF)
-               goto insert_dont_know_node;
+               if (!one_inserted)
+                 goto insert_dont_know_node;
 
-             break;
+               break;
+             }
 
            case CALL_EXPR:
              {
                tree args;
                bool one_inserted = false;
 
-               for (args = TREE_OPERAND (stmt, 1); args; args = TREE_CHAIN (args))
-                 if (TREE_CODE (TREE_VALUE (args)) == ARRAY_REF)
+               for (args = TREE_OPERAND (stmt, 1); args; 
+                    args = TREE_CHAIN (args))
+                 if (TREE_CODE (TREE_VALUE (args)) == ARRAY_REF
+                     || TREE_CODE (TREE_VALUE (args)) == INDIRECT_REF)
                    {
-                     VARRAY_PUSH_GENERIC_PTR 
-                       (*datarefs, analyze_array (stmt, TREE_VALUE (args), true));
-                     one_inserted = true;
+                     dr = create_data_ref (TREE_VALUE (args), stmt, true);
+                     if (dr)
+                       {
+                         VARRAY_PUSH_GENERIC_PTR (*datarefs, dr);
+                         one_inserted = true;
+                       }
                    }
 
                if (!one_inserted)
@@ -2332,9 +3621,18 @@ find_data_references_in_loop (struct loop *loop, varray_type *datarefs)
                  res = xmalloc (sizeof (struct data_reference));
                  DR_STMT (res) = NULL_TREE;
                  DR_REF (res) = NULL_TREE;
-                 DR_ACCESS_FNS (res) = NULL;
-                 DR_BASE_NAME (res) = NULL;
+                 DR_BASE_OBJECT (res) = NULL;
+                 DR_TYPE (res) = ARRAY_REF_TYPE;
+                 DR_SET_ACCESS_FNS (res, NULL);
+                 DR_BASE_OBJECT (res) = NULL;
                  DR_IS_READ (res) = false;
+                 DR_BASE_ADDRESS (res) = NULL_TREE;
+                 DR_OFFSET (res) = NULL_TREE;
+                 DR_INIT (res) = NULL_TREE;
+                 DR_STEP (res) = NULL_TREE;
+                 DR_OFFSET_MISALIGNMENT (res) = NULL_TREE;
+                 DR_MEMTAG (res) = NULL_TREE;
+                 DR_PTR_INFO (res) = NULL;
                  VARRAY_PUSH_GENERIC_PTR (*datarefs, res);
 
                  free (bbs);
@@ -2362,17 +3660,25 @@ find_data_references_in_loop (struct loop *loop, varray_type *datarefs)
 
 /* Given a loop nest LOOP, the following vectors are returned:
    *DATAREFS is initialized to all the array elements contained in this loop, 
-   *DEPENDENCE_RELATIONS contains the relations between the data references.  */
+   *DEPENDENCE_RELATIONS contains the relations between the data references.  
+   Compute read-read and self relations if 
+   COMPUTE_SELF_AND_READ_READ_DEPENDENCES is TRUE.  */
 
 void
-compute_data_dependences_for_loop (unsigned nb_loops
-                                  struct loop *loop,
+compute_data_dependences_for_loop (struct loop *loop
+                                  bool compute_self_and_read_read_dependences,
                                   varray_type *datarefs,
                                   varray_type *dependence_relations)
 {
-  unsigned int i;
+  unsigned int i, nb_loops;
   VEC(ddr_p,heap) *allrelations;
   struct data_dependence_relation *ddr;
+  struct loop *loop_nest = loop;
+
+  while (loop_nest && loop_nest->outer && loop_nest->outer->outer)
+    loop_nest = loop_nest->outer;
+
+  nb_loops = loop_nest->level;
 
   /* If one of the data references is not computable, give up without
      spending time to compute other dependences.  */
@@ -2390,14 +3696,15 @@ compute_data_dependences_for_loop (unsigned nb_loops,
     }
 
   allrelations = NULL;
-  compute_all_dependences (*datarefs, &allrelations);
+  compute_all_dependences (*datarefs, compute_self_and_read_read_dependences,
+                          &allrelations);
 
   for (i = 0; VEC_iterate (ddr_p, allrelations, i, ddr); i++)
     {
-      if (build_classic_dist_vector (ddr, nb_loops, loop->depth))
+      if (build_classic_dist_vector (ddr, nb_loops, loop_nest->depth))
        {
          VARRAY_PUSH_GENERIC_PTR (*dependence_relations, ddr);
-         build_classic_dir_vector (ddr, nb_loops, loop->depth);
+         build_classic_dir_vector (ddr, nb_loops, loop_nest->depth);
        }
     }
 }
@@ -2438,7 +3745,7 @@ analyze_all_data_dependences (struct loops *loops)
                           "dependence_relations");
 
   /* Compute DDs on the whole function.  */
-  compute_data_dependences_for_loop (loops->num, loops->parray[0], 
+  compute_data_dependences_for_loop (loops->parray[0], false,
                                     &datarefs, &dependence_relations);
 
   if (dump_file)
@@ -2470,8 +3777,10 @@ analyze_all_data_dependences (struct loops *loops)
                  struct data_reference *b = DDR_B (ddr);
                  bool differ_p;        
              
-                 if (DR_NUM_DIMENSIONS (a) != DR_NUM_DIMENSIONS (b)
-                     || (array_base_name_differ_p (a, b, &differ_p) && differ_p))
+                 if ((DR_BASE_OBJECT (a) && DR_BASE_OBJECT (b)
+                      && DR_NUM_DIMENSIONS (a) != DR_NUM_DIMENSIONS (b))
+                     || (base_object_differ_p (a, b, &differ_p) 
+                         && differ_p))
                    nb_basename_differ++;
                  else
                    nb_bot_relations++;
@@ -2533,7 +3842,7 @@ free_data_refs (varray_type datarefs)
        VARRAY_GENERIC_PTR (datarefs, i);
       if (dr)
        {
-         VEC_free (tree, heap, DR_ACCESS_FNS (dr));
+         DR_FREE_ACCESS_FNS (dr);
          free (dr);
        }
     }
index 49e23e43836ac6f7cb0d49d19e2d04244637adea..d0e670149d3c75b36f43c2f5df3f4ea5c67da2c1 100644 (file)
@@ -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_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_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_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);
 
 
 \f
index d41a79c1b72062baec637398ee5cf322df387eed..4a0b48007c59ba532d92e330854fb89d2893cf10 100644 (file)
@@ -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);
index c93765a2eac17ef22642d0ee5fcdb7cba84156d1..0b13e2b5524018d84e0461a9e0b75c274ff31ef6 100644 (file)
@@ -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))
        {
index 76d883ab64ca3e6bc997811a1debf956b4ebdbe7..62c741e9f3427bb70ad2aac00988149c56be43d4 100644 (file)
@@ -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.  */
 
index 267a6ffdde515650be59c81b60b8c9034bec87c0..45deb5c0952c7319dff845d01a66616ecb402599 100644 (file)
@@ -57,234 +57,10 @@ static void vect_mark_relevant (VEC(tree,heap) **, tree, bool, bool);
 static bool vect_stmt_relevant_p (tree, loop_vec_info, bool *, bool *);
 static tree vect_get_loop_niters (struct loop *, tree *);
 static bool vect_analyze_data_ref_dependence
-  (struct data_reference *, struct data_reference *, loop_vec_info);
-static bool vect_compute_data_ref_alignment (struct data_reference *);
+  (struct data_dependence_relation *, loop_vec_info);
+static bool vect_compute_data_ref_alignment (struct data_reference *); 
 static bool vect_analyze_data_ref_access (struct data_reference *);
-static struct data_reference * vect_analyze_pointer_ref_access 
-  (tree, tree, bool, tree, tree *, tree *);
 static bool vect_can_advance_ivs_p (loop_vec_info);
-static tree vect_get_ptr_offset (tree, tree, tree *);
-static bool vect_analyze_offset_expr (tree, struct loop *, tree, tree *, 
-                                     tree *, tree *);
-static bool vect_base_addr_differ_p (struct data_reference *,
-                                    struct data_reference *drb, bool *);
-static tree vect_object_analysis (tree, tree, bool, tree, 
-                                 struct data_reference **, tree *, tree *, 
-                                 tree *, bool *, tree *, struct ptr_info_def **,
-                                 subvar_t *);
-static tree vect_address_analysis (tree, tree, bool, tree, 
-                                  struct data_reference *, tree *, tree *, 
-                                  tree *, bool *);
-
-
-/* Function vect_get_ptr_offset
-
-   Compute the OFFSET modulo vector-type alignment of pointer REF in bits.  */
-
-static tree 
-vect_get_ptr_offset (tree ref ATTRIBUTE_UNUSED, 
-                    tree vectype ATTRIBUTE_UNUSED, 
-                    tree *offset ATTRIBUTE_UNUSED)
-{
-  /* TODO: Use alignment information.  */
-  return NULL_TREE; 
-}
-
-
-/* Function vect_analyze_offset_expr
-
-   Given an offset expression EXPR received from get_inner_reference, analyze
-   it and create an expression for INITIAL_OFFSET by substituting the variables 
-   of EXPR with initial_condition of the corresponding access_fn in the loop. 
-   E.g., 
-      for i
-         for (j = 3; j < N; j++)
-            a[j].b[i][j] = 0;
-        
-   For a[j].b[i][j], EXPR will be 'i * C_i + j * C_j + C'. 'i' cannot be 
-   substituted, since its access_fn in the inner loop is i. 'j' will be 
-   substituted with 3. An INITIAL_OFFSET will be 'i * C_i + C`', where
-   C` =  3 * C_j + C.
-
-   Compute MISALIGN (the misalignment of the data reference initial access from
-   its base) if possible. Misalignment can be calculated only if all the
-   variables can be substituted with constants, or if a variable is multiplied
-   by a multiple of VECTYPE_ALIGNMENT. In the above example, since 'i' cannot
-   be substituted, MISALIGN will be NULL_TREE in case that C_i is not a multiple
-   of VECTYPE_ALIGNMENT, and C` otherwise. (We perform MISALIGN modulo 
-   VECTYPE_ALIGNMENT computation in the caller of this function).
-
-   STEP is an evolution of the data reference in this loop in bytes.
-   In the above example, STEP is C_j.
-
-   Return FALSE, if the analysis fails, e.g., there is no access_fn for a 
-   variable. In this case, all the outputs (INITIAL_OFFSET, MISALIGN and STEP) 
-   are NULL_TREEs. Otherwise, return TRUE.
-
-*/
-
-static bool
-vect_analyze_offset_expr (tree expr, 
-                         struct loop *loop, 
-                         tree vectype_alignment,
-                         tree *initial_offset,
-                         tree *misalign,
-                         tree *step)
-{
-  tree oprnd0;
-  tree oprnd1;
-  tree left_offset = ssize_int (0);
-  tree right_offset = ssize_int (0);
-  tree left_misalign = ssize_int (0);
-  tree right_misalign = ssize_int (0);
-  tree left_step = ssize_int (0);
-  tree right_step = ssize_int (0);
-  enum tree_code code;
-  tree init, evolution;
-
-  *step = NULL_TREE;
-  *misalign = NULL_TREE;
-  *initial_offset = NULL_TREE;
-
-  /* Strip conversions that don't narrow the mode.  */
-  expr = vect_strip_conversion (expr);
-  if (!expr)
-    return false;
-
-  /* Stop conditions:
-     1. Constant.  */
-  if (TREE_CODE (expr) == INTEGER_CST)
-    {
-      *initial_offset = fold_convert (ssizetype, expr);
-      *misalign = fold_convert (ssizetype, expr);      
-      *step = ssize_int (0);
-      return true;
-    }
-
-  /* 2. Variable. Try to substitute with initial_condition of the corresponding
-     access_fn in the current loop.  */
-  if (SSA_VAR_P (expr))
-    {
-      tree access_fn = analyze_scalar_evolution (loop, expr);
-
-      if (access_fn == chrec_dont_know)
-       /* No access_fn.  */
-       return false;
-
-      init = initial_condition_in_loop_num (access_fn, loop->num);
-      if (init == expr && !expr_invariant_in_loop_p (loop, init))
-       /* Not enough information: may be not loop invariant.  
-          E.g., for a[b[i]], we get a[D], where D=b[i]. EXPR is D, its 
-          initial_condition is D, but it depends on i - loop's induction
-          variable.  */          
-       return false;
-
-      evolution = evolution_part_in_loop_num (access_fn, loop->num);
-      if (evolution && TREE_CODE (evolution) != INTEGER_CST)
-       /* Evolution is not constant.  */
-       return false;
-
-      if (TREE_CODE (init) == INTEGER_CST)
-       *misalign = fold_convert (ssizetype, init);
-      else
-       /* Not constant, misalignment cannot be calculated.  */
-       *misalign = NULL_TREE;
-
-      *initial_offset = fold_convert (ssizetype, init); 
-
-      *step = evolution ? fold_convert (ssizetype, evolution) : ssize_int (0);
-      return true;      
-    }
-
-  /* Recursive computation.  */
-  if (!BINARY_CLASS_P (expr))
-    {
-      /* We expect to get binary expressions (PLUS/MINUS and MULT).  */
-      if (vect_print_dump_info (REPORT_DETAILS))
-        {
-         fprintf (vect_dump, "Not binary expression ");
-          print_generic_expr (vect_dump, expr, TDF_SLIM);
-       }
-      return false;
-    }
-  oprnd0 = TREE_OPERAND (expr, 0);
-  oprnd1 = TREE_OPERAND (expr, 1);
-
-  if (!vect_analyze_offset_expr (oprnd0, loop, vectype_alignment, &left_offset, 
-                               &left_misalign, &left_step)
-      || !vect_analyze_offset_expr (oprnd1, loop, vectype_alignment, 
-                                  &right_offset, &right_misalign, &right_step))
-    return false;
-
-  /* The type of the operation: plus, minus or mult.  */
-  code = TREE_CODE (expr);
-  switch (code)
-    {
-    case MULT_EXPR:
-      if (TREE_CODE (right_offset) != INTEGER_CST)
-       /* RIGHT_OFFSET can be not constant. For example, for arrays of variable 
-          sized types. 
-          FORNOW: We don't support such cases.  */
-       return false;
-
-      /* Strip conversions that don't narrow the mode.  */
-      left_offset = vect_strip_conversion (left_offset);      
-      if (!left_offset)
-       return false;      
-      /* Misalignment computation.  */
-      if (SSA_VAR_P (left_offset))
-       {
-         /* If the left side contains variables that can't be substituted with 
-            constants, we check if the right side is a multiple of ALIGNMENT.
-          */
-         if (integer_zerop (size_binop (TRUNC_MOD_EXPR, right_offset, 
-                                 fold_convert (ssizetype, vectype_alignment))))
-           *misalign = ssize_int (0);
-         else
-           /* If the remainder is not zero or the right side isn't constant,
-              we can't compute  misalignment.  */
-           *misalign = NULL_TREE;
-       }
-      else 
-       {
-         /* The left operand was successfully substituted with constant.  */     
-         if (left_misalign)
-           /* In case of EXPR '(i * C1 + j) * C2', LEFT_MISALIGN is 
-              NULL_TREE.  */
-           *misalign  = size_binop (code, left_misalign, right_misalign);
-         else
-           *misalign = NULL_TREE; 
-       }
-
-      /* Step calculation.  */
-      /* Multiply the step by the right operand.  */
-      *step  = size_binop (MULT_EXPR, left_step, right_offset);
-      break;
-   
-    case PLUS_EXPR:
-    case MINUS_EXPR:
-      /* Combine the recursive calculations for step and misalignment.  */
-      *step = size_binop (code, left_step, right_step);
-   
-      if (left_misalign && right_misalign)
-       *misalign  = size_binop (code, left_misalign, right_misalign);
-      else
-       *misalign = NULL_TREE;
-    
-      break;
-
-    default:
-      gcc_unreachable ();
-    }
-
-  /* Compute offset.  */
-  *initial_offset = fold_convert (ssizetype, 
-                                 fold_build2 (code, TREE_TYPE (left_offset),
-                                              left_offset,
-                                              right_offset));
-  return true;
-}
-
 
 /* Function vect_determine_vectorization_factor
 
@@ -780,86 +556,34 @@ 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
    DRA and a memory-reference DRB.  */
-
+      
 static bool
-vect_analyze_data_ref_dependence (struct data_reference *dra,
-                                 struct data_reference *drb, 
-                                 loop_vec_info loop_vinfo)
+vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
+                                  loop_vec_info loop_vinfo)
 {
-  bool differ_p; 
-  struct data_dependence_relation *ddr;
   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
   int vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
   int dist = 0;
   unsigned int loop_depth = 0;
-  struct loop *loop_nest = loop;  
-  stmt_vec_info stmtinfo_a = vinfo_for_stmt (DR_STMT (dra));
+  struct loop *loop_nest = loop;
+  struct data_reference *dra = DDR_A (ddr);
+  struct data_reference *drb = DDR_B (ddr);
+  stmt_vec_info stmtinfo_a = vinfo_for_stmt (DR_STMT (dra)); 
   stmt_vec_info stmtinfo_b = vinfo_for_stmt (DR_STMT (drb));
+         
+  if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
+    return false;
   
-  if (!vect_base_addr_differ_p (dra, drb, &differ_p))
+  if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
     {
       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
         {
           fprintf (vect_dump,
-                "not vectorized: can't determine dependence between: ");
+                   "not vectorized: 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);
@@ -867,57 +591,28 @@ vect_analyze_data_ref_dependence (struct data_reference *dra,
       return true;
     }
 
-  if (differ_p)
-    return false;
-
-  ddr = initialize_data_dependence_relation (dra, drb);
-  compute_affine_dependence (ddr);
-
-  if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
-    return false;
-
-  if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
+  if (!DDR_DIST_VECT (ddr))
     {
       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
         {
-          fprintf (vect_dump, 
-                   "not vectorized: can't determine dependence between "); 
+          fprintf (vect_dump, "not vectorized: 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);
         }
       return true;
-    }
+    }    
 
   /* Find loop depth.  */
-  while (loop_nest)
+  while (loop_nest && loop_nest->outer && loop_nest->outer->outer)
     {
-      if (loop_nest->outer && loop_nest->outer->outer)
-       {
-         loop_nest = loop_nest->outer;
-         loop_depth++;
-       }
-      else
-       break;
-    }
-
-  /* Compute distance vector.  */
-  compute_subscript_distance (ddr);
-  build_classic_dist_vector (ddr, vect_loops_num, loop_nest->depth);
-
-  if (!DDR_DIST_VECT (ddr))
-    {
-      if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
-       {
-         fprintf (vect_dump, "not vectorized: 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);
-       }      
-      return true;
+      loop_nest = loop_nest->outer;
+      loop_depth++;
     }
-
+         
   dist = DDR_DIST_VECT (ddr)[loop_depth];
+  if (vect_print_dump_info (REPORT_DR_DETAILS))
+    fprintf (vect_dump, "dependence distance  = %d.",dist);
 
   /* Same loop iteration.  */
   if (dist % vectorization_factor == 0)
@@ -926,76 +621,59 @@ vect_analyze_data_ref_dependence (struct data_reference *dra,
       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))
-       fprintf (vect_dump, "accesses have the same alignment.");
+        fprintf (vect_dump, "accesses have the same alignment.");
+      if (vect_print_dump_info (REPORT_DR_DETAILS))
+        {
+          fprintf (vect_dump, "dependence distance modulo vf == 0 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);
+        }
       return false;
-    }
+    }    
 
-  if (dist >= vectorization_factor)
-    /* Dependence distance does not create dependence, as far as vectorization
-       is concerned, in this case.  */
-    return false;
-    
+  if (abs (dist) >= vectorization_factor)
+    {
+      /* Dependence distance does not create dependence, as far as vectorization
+         is concerned, in this case.  */
+      if (vect_print_dump_info (REPORT_DR_DETAILS))
+        fprintf (vect_dump, "dependence distance >= VF.");
+       return false;
+    }
+  
   if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
     {
       fprintf (vect_dump,
-       "not vectorized: possible dependence between data-refs ");
+        "not vectorized: 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);
     }
-
+        
   return true;
 }
 
 
 /* Function vect_analyze_data_ref_dependences.
-
+          
    Examine all the data references in the loop, and make sure there do not
    exist any data dependences between them.  */
-
+         
 static bool
 vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo)
 {
-  unsigned int i, j;
-  varray_type loop_write_refs = LOOP_VINFO_DATAREF_WRITES (loop_vinfo);
-  varray_type loop_read_refs = LOOP_VINFO_DATAREF_READS (loop_vinfo);
-
-  /* Examine store-store (output) dependences.  */
+  unsigned int i;
+  varray_type ddrs = LOOP_VINFO_DDRS (loop_vinfo);
 
-  if (vect_print_dump_info (REPORT_DETAILS))
+  if (vect_print_dump_info (REPORT_DETAILS)) 
     fprintf (vect_dump, "=== vect_analyze_dependences ===");
-
-  if (vect_print_dump_info (REPORT_DETAILS))
-    fprintf (vect_dump, "compare all store-store pairs.");
-
-  for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_write_refs); i++)
-    {
-      for (j = i + 1; j < VARRAY_ACTIVE_SIZE (loop_write_refs); j++)
-       {
-         struct data_reference *dra =
-           VARRAY_GENERIC_PTR (loop_write_refs, i);
-         struct data_reference *drb =
-           VARRAY_GENERIC_PTR (loop_write_refs, j);
-         if (vect_analyze_data_ref_dependence (dra, drb, loop_vinfo))
-           return false;
-       }
-    }
-
-  /* Examine load-store (true/anti) dependences.  */
-
-  if (vect_print_dump_info (REPORT_DETAILS))
-    fprintf (vect_dump, "compare all load-store pairs.");
-
-  for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_read_refs); i++)
+     
+  for (i = 0; i < VARRAY_ACTIVE_SIZE (ddrs); i++)
     {
-      for (j = 0; j < VARRAY_ACTIVE_SIZE (loop_write_refs); j++)
-       {
-         struct data_reference *dra = VARRAY_GENERIC_PTR (loop_read_refs, i);
-         struct data_reference *drb =
-           VARRAY_GENERIC_PTR (loop_write_refs, j);
-         if (vect_analyze_data_ref_dependence (dra, drb, loop_vinfo))
-           return false;
-       }
+      struct data_dependence_relation *ddr = VARRAY_GENERIC_PTR (ddrs, i);
+     
+      if (vect_analyze_data_ref_dependence (ddr, loop_vinfo))
+        return false;
     }
 
   return true;
@@ -1021,9 +699,10 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);  
   tree ref = DR_REF (dr);
   tree vectype;
-  tree base, alignment;
-  bool base_aligned_p;
+  tree base, base_addr;
+  bool base_aligned;
   tree misalign;
+  tree aligned_to, alignment;
    
   if (vect_print_dump_info (REPORT_DETAILS))
     fprintf (vect_dump, "vect_compute_data_ref_alignment:");
@@ -1031,12 +710,15 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
   /* Initialize misalignment to unknown.  */
   DR_MISALIGNMENT (dr) = -1;
 
-  misalign = STMT_VINFO_VECT_MISALIGNMENT (stmt_info);
-  base_aligned_p = STMT_VINFO_VECT_BASE_ALIGNED_P (stmt_info);
-  base = build_fold_indirect_ref (STMT_VINFO_VECT_DR_BASE_ADDRESS (stmt_info));
+  misalign = DR_OFFSET_MISALIGNMENT (dr);
+  aligned_to = DR_ALIGNED_TO (dr);
+  base_addr = DR_BASE_ADDRESS (dr);
+  base = build_fold_indirect_ref (base_addr);
   vectype = STMT_VINFO_VECTYPE (stmt_info);
+  alignment = ssize_int (TYPE_ALIGN (vectype)/BITS_PER_UNIT);
 
-  if (!misalign)
+  if ((aligned_to && tree_int_cst_compare (aligned_to, alignment) < 0)
+      || !misalign)
     {
       if (vect_print_dump_info (REPORT_DETAILS))
        {
@@ -1046,7 +728,18 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
       return true;
     }
 
-  if (!base_aligned_p) 
+  if ((DECL_P (base) 
+       && tree_int_cst_compare (ssize_int (DECL_ALIGN_UNIT (base)),
+                               alignment) >= 0)
+      || (TREE_CODE (base_addr) == SSA_NAME
+         && tree_int_cst_compare (ssize_int (TYPE_ALIGN_UNIT (TREE_TYPE (
+                                                     TREE_TYPE (base_addr)))),
+                                  alignment) >= 0))
+    base_aligned = true;
+  else
+    base_aligned = false;   
+
+  if (!base_aligned) 
     {
       if (!vect_can_force_dr_alignment_p (base, TYPE_ALIGN (vectype)))
        {
@@ -1068,15 +761,13 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
     }
 
   /* At this point we assume that the base is aligned.  */
-  gcc_assert (base_aligned_p 
+  gcc_assert (base_aligned
              || (TREE_CODE (base) == VAR_DECL 
                  && DECL_ALIGN (base) >= TYPE_ALIGN (vectype)));
 
-  /* Alignment required, in bytes:  */
-  alignment = ssize_int (TYPE_ALIGN (vectype)/BITS_PER_UNIT);
-
   /* Modulo alignment.  */
   misalign = size_binop (TRUNC_MOD_EXPR, misalign, alignment);
+
   if (tree_int_cst_sgn (misalign) < 0)
     {
       /* Negative misalignment value.  */
@@ -1088,7 +779,10 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
   DR_MISALIGNMENT (dr) = tree_low_cst (misalign, 1);
 
   if (vect_print_dump_info (REPORT_DETAILS))
-    fprintf (vect_dump, "misalign = %d bytes", DR_MISALIGNMENT (dr));
+    {
+      fprintf (vect_dump, "misalign = %d bytes of ref ", DR_MISALIGNMENT (dr));
+      print_generic_expr (vect_dump, ref, TDF_SLIM);
+    }
 
   return true;
 }
@@ -1106,20 +800,12 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
 static bool
 vect_compute_data_refs_alignment (loop_vec_info loop_vinfo)
 {
-  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);
   unsigned int i;
 
-  for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_write_datarefs); i++)
-    {
-      struct data_reference *dr = VARRAY_GENERIC_PTR (loop_write_datarefs, i);
-      if (!vect_compute_data_ref_alignment (dr))
-       return false;
-    }
-
-  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);
       if (!vect_compute_data_ref_alignment (dr))
        return false;
     }
@@ -1141,13 +827,13 @@ vect_compute_data_refs_alignment (loop_vec_info loop_vinfo)
 static void
 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 loop_datarefs = LOOP_VINFO_DATAREFS (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;
+  bool check_loads;
 
   /*
      This pass will require a cost model to guide it whether to apply peeling 
@@ -1248,10 +934,10 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
 
      TODO: Use a better cost model.  */
 
-  for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_write_datarefs); i++)
+  for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_datarefs); i++)
     {
-      dr0 = VARRAY_GENERIC_PTR (loop_write_datarefs, i);
-      if (!aligned_access_p (dr0))
+      dr0 = VARRAY_GENERIC_PTR (loop_datarefs, i);
+      if (!DR_IS_READ (dr0) && !aligned_access_p (dr0))
        {
          LOOP_VINFO_UNALIGNED_DR (loop_vinfo) = dr0;
          LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo) = DR_MISALIGNMENT (dr0);
@@ -1285,14 +971,15 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
          npeel = LOOP_VINFO_VECT_FACTOR (loop_vinfo) - mis;
        }
 
-      datarefs = loop_write_datarefs;
+      datarefs = loop_datarefs;
+      check_loads = false;
       for (j = 0; j < 2; j++)
        {
          for (i = 0; i < VARRAY_ACTIVE_SIZE (datarefs); i++)
            {
              struct data_reference *dr = VARRAY_GENERIC_PTR (datarefs, i);
 
-             if (dr == dr0)
+             if (dr == dr0 || (!check_loads && DR_IS_READ (dr)))
                continue;
              if (known_alignment_for_access_p (dr)
                  && DR_MISALIGNMENT (dr) == DR_MISALIGNMENT (dr0))
@@ -1309,7 +996,7 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
              else
                DR_MISALIGNMENT (dr) = -1;
            }
-         datarefs = loop_read_datarefs;
+         check_loads = true;
        }
 
       same_align_drs = 
@@ -1334,8 +1021,7 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
 static bool
 vect_analyze_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 = LOOP_VINFO_DATAREFS (loop_vinfo);
   enum dr_alignment_support supportable_dr_alignment;
   unsigned int i;
 
@@ -1364,29 +1050,19 @@ vect_analyze_data_refs_alignment (loop_vec_info loop_vinfo)
   /* Finally, check that all the data references in the loop can be
      handled with respect to their alignment.  */
 
-  for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_read_datarefs); i++)
-    {
-      struct data_reference *dr = VARRAY_GENERIC_PTR (loop_read_datarefs, i);
-      supportable_dr_alignment = vect_supportable_dr_alignment (dr);
-      if (!supportable_dr_alignment)
-       {
-         if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
-           fprintf (vect_dump, "not vectorized: unsupported unaligned load.");
-         return false;
-       }
-      if (supportable_dr_alignment != dr_aligned 
-         && (vect_print_dump_info (REPORT_ALIGNMENT)))
-       fprintf (vect_dump, "Vectorizing an unaligned access.");
-    }
-  for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_write_datarefs); i++)
+  for (i = 0; i < VARRAY_ACTIVE_SIZE (datarefs); i++)
     {
-      struct data_reference *dr = VARRAY_GENERIC_PTR (loop_write_datarefs, i);
+      struct data_reference *dr = VARRAY_GENERIC_PTR (datarefs, i);
       supportable_dr_alignment = vect_supportable_dr_alignment (dr);
       if (!supportable_dr_alignment)
        {
-         if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
-           fprintf (vect_dump, "not vectorized: unsupported unaligned store.");
-         return false;
+            if (DR_IS_READ (dr))
+              fprintf (vect_dump,
+                       "not vectorized: unsupported unaligned load.");
+            else
+              fprintf (vect_dump,
+                       "not vectorized: unsupported unaligned store.");
+           return false;
        }
       if (supportable_dr_alignment != dr_aligned 
          && (vect_print_dump_info (REPORT_ALIGNMENT)))
@@ -1395,7 +1071,6 @@ vect_analyze_data_refs_alignment (loop_vec_info loop_vinfo)
   if (LOOP_VINFO_UNALIGNED_DR (loop_vinfo)
       && vect_print_dump_info (REPORT_ALIGNMENT))
     fprintf (vect_dump, "Alignment of access forced using peeling.");
-
   return true;
 }
 
@@ -1408,9 +1083,7 @@ vect_analyze_data_refs_alignment (loop_vec_info loop_vinfo)
 static bool
 vect_analyze_data_ref_access (struct data_reference *dr)
 {
-  tree stmt = DR_STMT (dr);
-  stmt_vec_info stmt_info = vinfo_for_stmt (stmt); 
-  tree step = STMT_VINFO_VECT_STEP (stmt_info);
+  tree step = DR_STEP (dr);
   tree scalar_type = TREE_TYPE (DR_REF (dr));
 
   if (!step || tree_int_cst_compare (step, TYPE_SIZE_UNIT (scalar_type)))
@@ -1436,29 +1109,15 @@ static bool
 vect_analyze_data_ref_accesses (loop_vec_info loop_vinfo)
 {
   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_print_dump_info (REPORT_DETAILS))
     fprintf (vect_dump, "=== vect_analyze_data_ref_accesses ===");
 
-  for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_write_datarefs); i++)
+  for (i = 0; i < VARRAY_ACTIVE_SIZE (datarefs); i++)
     {
-      struct data_reference *dr = VARRAY_GENERIC_PTR (loop_write_datarefs, i);
-      bool ok = vect_analyze_data_ref_access (dr);
-      if (!ok)
-       {
-         if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
-           fprintf (vect_dump, "not vectorized: complicated access pattern.");
-         return false;
-       }
-    }
-
-  for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_read_datarefs); i++)
-    {
-      struct data_reference *dr = VARRAY_GENERIC_PTR (loop_read_datarefs, i);
-      bool ok = vect_analyze_data_ref_access (dr);
-      if (!ok)
+      struct data_reference *dr = VARRAY_GENERIC_PTR (datarefs, i);
+      if (!vect_analyze_data_ref_access (dr))
        {
          if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
            fprintf (vect_dump, "not vectorized: complicated access pattern.");
@@ -1470,640 +1129,106 @@ vect_analyze_data_ref_accesses (loop_vec_info loop_vinfo)
 }
 
 
-/* Function vect_analyze_pointer_ref_access.
-
-   Input:
-   STMT - a stmt that contains a data-ref.
-   MEMREF - a data-ref in STMT, which is an INDIRECT_REF.
-   ACCESS_FN - the access function of MEMREF.
-
-   Output:
-   If the data-ref access is vectorizable, return a data_reference structure
-   that represents it (DR). Otherwise - return NULL.  
-   STEP - the stride of MEMREF in the loop.
-   INIT - the initial condition of MEMREF in the loop.
-*/
-
-static struct data_reference *
-vect_analyze_pointer_ref_access (tree memref, tree stmt, bool is_read, 
-                                tree access_fn, tree *ptr_init, tree *ptr_step)
-{
-  stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
-  loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
-  struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
-  tree step, init;     
-  tree reftype, innertype;
-  tree indx_access_fn; 
-  int loopnum = loop->num;
-  struct data_reference *dr;
-
-  if (!vect_is_simple_iv_evolution (loopnum, access_fn, &init, &step))
-    {
-      if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
-       fprintf (vect_dump, "not vectorized: pointer access is not simple.");   
-      return NULL;
-    }
-
-  STRIP_NOPS (init);
-
-  if (!expr_invariant_in_loop_p (loop, init))
-    {
-      if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
-       fprintf (vect_dump, 
-                "not vectorized: initial condition is not loop invariant.");   
-      return NULL;
-    }
-
-  if (TREE_CODE (step) != INTEGER_CST)
-    {
-      if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
-       fprintf (vect_dump, 
-               "not vectorized: non constant step for pointer access.");       
-      return NULL;
-    }
-
-  reftype = TREE_TYPE (TREE_OPERAND (memref, 0));
-  if (!POINTER_TYPE_P (reftype)) 
-    {
-      if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
-       fprintf (vect_dump, "not vectorized: unexpected pointer access form."); 
-      return NULL;
-    }
-
-  if (!POINTER_TYPE_P (TREE_TYPE (init))) 
-    {
-      if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
-       fprintf (vect_dump, "not vectorized: unexpected pointer access form.");
-      return NULL;
-    }
-
-  *ptr_step = fold_convert (ssizetype, step);
-  innertype = TREE_TYPE (reftype);
-  if (!COMPLETE_TYPE_P (innertype))
-    {
-      if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
-       fprintf (vect_dump, "not vectorized: pointer to incomplete type.");
-      return NULL;
-    }
-   
-  /* Check that STEP is a multiple of type size.  */
-  if (!integer_zerop (size_binop (TRUNC_MOD_EXPR, *ptr_step, 
-                       fold_convert (ssizetype, TYPE_SIZE_UNIT (innertype)))))
-    {
-      if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
-       fprintf (vect_dump, "not vectorized: non consecutive access."); 
-      return NULL;
-    }
-   
-  indx_access_fn = 
-       build_polynomial_chrec (loopnum, integer_zero_node, integer_one_node);
-  if (vect_print_dump_info (REPORT_DETAILS))
-    {
-      fprintf (vect_dump, "Access function of ptr indx: ");
-      print_generic_expr (vect_dump, indx_access_fn, TDF_SLIM);
-    }
-  dr = init_data_ref (stmt, memref, NULL_TREE, indx_access_fn, is_read);
-  *ptr_init = init;
-  return dr;
-}
-
-
-/* Function vect_address_analysis
-
-   Return the BASE of the address expression EXPR.
-   Also compute the INITIAL_OFFSET from BASE, MISALIGN and STEP.
-
-   Input:
-   EXPR - the address expression that is being analyzed
-   STMT - the statement that contains EXPR or its original memory reference
-   IS_READ - TRUE if STMT reads from EXPR, FALSE if writes to EXPR
-   VECTYPE - the type that defines the alignment (i.e, we compute
-             alignment relative to TYPE_ALIGN(VECTYPE))
-   DR - data_reference struct for the original memory reference
-
-   Output:
-   BASE (returned value) - the base of the data reference EXPR.
-   INITIAL_OFFSET - initial offset of EXPR from BASE (an expression)
-   MISALIGN - offset of EXPR from BASE in bytes (a constant) or NULL_TREE if the
-              computation is impossible
-   STEP - evolution of EXPR in the loop
-   BASE_ALIGNED - indicates if BASE is aligned
-   If something unexpected is encountered (an unsupported form of data-ref),
-   then NULL_TREE is returned.  
- */
-
-static tree
-vect_address_analysis (tree expr, tree stmt, bool is_read, tree vectype, 
-                      struct data_reference *dr, tree *offset, tree *misalign,
-                      tree *step, bool *base_aligned)
-{
-  tree oprnd0, oprnd1, base_address, offset_expr, base_addr0, base_addr1;
-  tree address_offset = ssize_int (0), address_misalign = ssize_int (0);
-  tree dummy;
-  struct ptr_info_def *dummy1;
-  subvar_t dummy2;
-
-  switch (TREE_CODE (expr))
-    {
-    case PLUS_EXPR:
-    case MINUS_EXPR:
-      /* EXPR is of form {base +/- offset} (or {offset +/- base}).  */
-      oprnd0 = TREE_OPERAND (expr, 0);
-      oprnd1 = TREE_OPERAND (expr, 1);
-
-      STRIP_NOPS (oprnd0);
-      STRIP_NOPS (oprnd1);
-      
-      /* Recursively try to find the base of the address contained in EXPR.
-        For offset, the returned base will be NULL.  */
-      base_addr0 = vect_address_analysis (oprnd0, stmt, is_read, vectype, dr, 
-                                    &address_offset, &address_misalign, step, 
-                                    base_aligned);
-
-      base_addr1 = vect_address_analysis (oprnd1, stmt, is_read, vectype, dr, 
-                                    &address_offset, &address_misalign, step, 
-                                    base_aligned);
-
-      /* We support cases where only one of the operands contains an 
-        address.  */
-      if ((base_addr0 && base_addr1) || (!base_addr0 && !base_addr1))
-       return NULL_TREE;
-
-      /* To revert STRIP_NOPS.  */
-      oprnd0 = TREE_OPERAND (expr, 0);
-      oprnd1 = TREE_OPERAND (expr, 1);
-      
-      offset_expr = base_addr0 ? 
-       fold_convert (ssizetype, oprnd1) : fold_convert (ssizetype, oprnd0);
-
-      /* EXPR is of form {base +/- offset} (or {offset +/- base}). If offset is 
-        a number, we can add it to the misalignment value calculated for base,
-        otherwise, misalignment is NULL.  */
-      if (TREE_CODE (offset_expr) == INTEGER_CST && address_misalign)
-       *misalign = size_binop (TREE_CODE (expr), address_misalign, 
-                               offset_expr);
-      else
-       *misalign = NULL_TREE;
-
-      /* Combine offset (from EXPR {base + offset}) with the offset calculated
-        for base.  */
-      *offset = size_binop (TREE_CODE (expr), address_offset, offset_expr);
-      return base_addr0 ? base_addr0 : base_addr1;
-
-    case ADDR_EXPR:
-      base_address = vect_object_analysis (TREE_OPERAND (expr, 0), stmt,
-                                          is_read, vectype, &dr, offset, 
-                                          misalign, step, base_aligned, 
-                                          &dummy, &dummy1, &dummy2);
-      return base_address;
-
-    case SSA_NAME:
-      if (!POINTER_TYPE_P (TREE_TYPE (expr)))
-       return NULL_TREE;
-
-      if (TYPE_ALIGN (TREE_TYPE (TREE_TYPE (expr))) < TYPE_ALIGN (vectype)) 
-       {
-         if (vect_get_ptr_offset (expr, vectype, misalign))
-           *base_aligned = true;         
-         else
-           *base_aligned = false;
-       }
-      else
-       {         
-         *base_aligned = true;
-         *misalign = ssize_int (0);
-       }
-      *offset = ssize_int (0);
-      *step = ssize_int (0);
-      return expr;
-      
-    default:
-      return NULL_TREE;
-    }
-}
-
-
-/* Function vect_object_analysis
-
-   Return the BASE of the data reference MEMREF.
-   Also compute the INITIAL_OFFSET from BASE, MISALIGN and STEP.
-   E.g., for EXPR a.b[i] + 4B, BASE is a, and OFFSET is the overall offset  
-   'a.b[i] + 4B' from a (can be an expression), MISALIGN is an OFFSET 
-   instantiated with initial_conditions of access_functions of variables, 
-   modulo alignment, and STEP is the evolution of the DR_REF in this loop.
-
-   Function get_inner_reference is used for the above in case of ARRAY_REF and
-   COMPONENT_REF.
-
-   The structure of the function is as follows:
-   Part 1:
-   Case 1. For handled_component_p refs 
-          1.1 call get_inner_reference
-            1.1.1 analyze offset expr received from get_inner_reference
-         1.2. build data-reference structure for MEMREF
-        (fall through with BASE)
-   Case 2. For declarations 
-          2.1 check alignment
-          2.2 update DR_BASE_NAME if necessary for alias
-   Case 3. For INDIRECT_REFs 
-          3.1 get the access function
-         3.2 analyze evolution of MEMREF
-         3.3 set data-reference structure for MEMREF
-          3.4 call vect_address_analysis to analyze INIT of the access function
-
-   Part 2:
-   Combine the results of object and address analysis to calculate 
-   INITIAL_OFFSET, STEP and misalignment info.   
-
-   Input:
-   MEMREF - the memory reference that is being analyzed
-   STMT - the statement that contains MEMREF
-   IS_READ - TRUE if STMT reads from MEMREF, FALSE if writes to MEMREF
-   VECTYPE - the type that defines the alignment (i.e, we compute
-             alignment relative to TYPE_ALIGN(VECTYPE))
-   
-   Output:
-   BASE_ADDRESS (returned value) - the base address of the data reference MEMREF
-                                   E.g, if MEMREF is a.b[k].c[i][j] the returned
-                                  base is &a.
-   DR - data_reference struct for MEMREF
-   INITIAL_OFFSET - initial offset of MEMREF from BASE (an expression)
-   MISALIGN - offset of MEMREF from BASE in bytes (a constant) or NULL_TREE if 
-              the computation is impossible
-   STEP - evolution of the DR_REF in the loop
-   BASE_ALIGNED - indicates if BASE is aligned
-   MEMTAG - memory tag for aliasing purposes
-   PTR_INFO - NULL or points-to aliasing info from a pointer SSA_NAME
-   SUBVAR - Sub-variables of the variable
-   If something unexpected is encountered (an unsupported form of data-ref),
-   then NULL_TREE is returned.  */
-
-static tree
-vect_object_analysis (tree memref, tree stmt, bool is_read,
-                     tree vectype, struct data_reference **dr,
-                     tree *offset, tree *misalign, tree *step,
-                     bool *base_aligned, tree *memtag,
-                     struct ptr_info_def **ptr_info, subvar_t *subvars)
-{
-  tree base = NULL_TREE, base_address = NULL_TREE;
-  tree object_offset = ssize_int (0), object_misalign = ssize_int (0);
-  tree object_step = ssize_int (0), address_step = ssize_int (0);
-  bool object_base_aligned = true, address_base_aligned = true;
-  tree address_offset = ssize_int (0), address_misalign = ssize_int (0);
-  HOST_WIDE_INT pbitsize, pbitpos;
-  tree poffset, bit_pos_in_bytes;
-  enum machine_mode pmode;
-  int punsignedp, pvolatilep;
-  tree ptr_step = ssize_int (0), ptr_init = NULL_TREE;
-  stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
-  loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
-  struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
-  struct data_reference *ptr_dr = NULL;
-  tree access_fn, evolution_part, address_to_analyze;
-
-  *ptr_info = NULL;
-   
-  /* Part 1: */
-  /* Case 1. handled_component_p refs.  */
-  if (handled_component_p (memref))
-    {
-      /* 1.1 call get_inner_reference.  */
-      /* Find the base and the offset from it.  */
-      base = get_inner_reference (memref, &pbitsize, &pbitpos, &poffset,
-                                 &pmode, &punsignedp, &pvolatilep, false);
-      if (!base)
-       return NULL_TREE;
-
-      /* 1.1.1 analyze offset expr received from get_inner_reference.  */
-      if (poffset 
-         && !vect_analyze_offset_expr (poffset, loop, TYPE_SIZE_UNIT (vectype), 
-                               &object_offset, &object_misalign, &object_step))
-       {
-         if (vect_print_dump_info (REPORT_DETAILS))
-           {
-             fprintf (vect_dump, "failed to compute offset or step for ");
-             print_generic_expr (vect_dump, memref, TDF_SLIM);
-           }
-         return NULL_TREE;
-       }
-
-      /* Add bit position to OFFSET and MISALIGN.  */
-
-      bit_pos_in_bytes = ssize_int (pbitpos/BITS_PER_UNIT);
-      /* Check that there is no remainder in bits.  */
-      if (pbitpos%BITS_PER_UNIT)
-       {
-         if (vect_print_dump_info (REPORT_DETAILS))
-           fprintf (vect_dump, "bit offset alignment.");
-         return NULL_TREE;
-       }
-      object_offset = size_binop (PLUS_EXPR, bit_pos_in_bytes, object_offset);     
-      if (object_misalign) 
-       object_misalign = size_binop (PLUS_EXPR, object_misalign, 
-                                     bit_pos_in_bytes); 
-
-      /* Create data-reference for MEMREF. TODO: handle COMPONENT_REFs.  */
-      if (!(*dr))
-       { 
-         if (TREE_CODE (memref) == ARRAY_REF)
-           *dr = analyze_array (stmt, memref, is_read);
-         else
-           /* FORNOW.  */
-           return NULL_TREE;
-       }
-      memref = base; /* To continue analysis of BASE.  */
-      /* fall through  */
-    }
-  
-  /*  Part 1: Case 2. Declarations.  */ 
-  if (DECL_P (memref))
-    {
-      /* We expect to get a decl only if we already have a DR.  */
-      if (!(*dr))
-       {
-         if (vect_print_dump_info (REPORT_DETAILS))
-           {
-             fprintf (vect_dump, "unhandled decl ");
-             print_generic_expr (vect_dump, memref, TDF_SLIM);
-           }
-         return NULL_TREE;
-       }
-
-      /* 2.1 check the alignment.  */
-      if (DECL_ALIGN (memref) >= TYPE_ALIGN (vectype))
-       object_base_aligned = true;
-      else
-       object_base_aligned = false;
-
-      /* 2.2 update DR_BASE_NAME if necessary.  */
-      if (!DR_BASE_NAME ((*dr)))
-       /* For alias analysis.  In case the analysis of INDIRECT_REF brought 
-          us to object.  */
-       DR_BASE_NAME ((*dr)) = memref;
-
-      if (SSA_VAR_P (memref) && var_can_have_subvars (memref)) 
-       *subvars = get_subvars_for_var (memref);
-      base_address = build_fold_addr_expr (memref);
-      *memtag = memref;
-    }
-
-  /* Part 1:  Case 3. INDIRECT_REFs.  */
-  else if (TREE_CODE (memref) == INDIRECT_REF)
-    {
-      tree ptr_ref = TREE_OPERAND (memref, 0);
-      if (TREE_CODE (ptr_ref) == SSA_NAME)
-        *ptr_info = SSA_NAME_PTR_INFO (ptr_ref);
-
-      /* 3.1 get the access function.  */
-      access_fn = analyze_scalar_evolution (loop, ptr_ref);
-      if (!access_fn)
-       {
-         if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
-           fprintf (vect_dump, "not vectorized: complicated pointer access."); 
-         return NULL_TREE;
-       }
-      if (vect_print_dump_info (REPORT_DETAILS))
-       {
-         fprintf (vect_dump, "Access function of ptr: ");
-         print_generic_expr (vect_dump, access_fn, TDF_SLIM);
-       }
-
-      /* 3.2 analyze evolution of MEMREF.  */
-      evolution_part = evolution_part_in_loop_num (access_fn, loop->num);
-      if (evolution_part)
-       {
-         ptr_dr = vect_analyze_pointer_ref_access (memref, stmt, is_read, 
-                                        access_fn, &ptr_init, &ptr_step);
-         if (!(ptr_dr))
-           return NULL_TREE; 
-         
-         object_step = size_binop (PLUS_EXPR, object_step, ptr_step);
-         address_to_analyze = ptr_init;
-       }
-      else
-       {
-         if (!(*dr))
-           {
-             if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
-               fprintf (vect_dump, "not vectorized: ptr is loop invariant.");  
-             return NULL_TREE;
-           }
-         /* Since there exists DR for MEMREF, we are analyzing the init of 
-            the access function, which not necessary has evolution in the 
-            loop.  */
-         address_to_analyze = initial_condition_in_loop_num (access_fn,
-                                                              loop->num);
-       }
-      
-      /* 3.3 set data-reference structure for MEMREF.  */
-      *dr = (*dr) ? *dr : ptr_dr;
-
-      /* 3.4 call vect_address_analysis to analyze INIT of the access 
-        function.  */
-      base_address = vect_address_analysis (address_to_analyze, stmt, is_read, 
-                              vectype, *dr, &address_offset, &address_misalign, 
-                              &address_step, &address_base_aligned);
-      if (!base_address)
-       return NULL_TREE;
-
-      switch (TREE_CODE (base_address))
-       {
-       case SSA_NAME:
-         *memtag = get_var_ann (SSA_NAME_VAR (base_address))->type_mem_tag;
-         if (!(*memtag) && TREE_CODE (TREE_OPERAND (memref, 0)) == SSA_NAME)
-           *memtag = get_var_ann (
-                     SSA_NAME_VAR (TREE_OPERAND (memref, 0)))->type_mem_tag;
-         break;
-       case ADDR_EXPR:
-         *memtag = TREE_OPERAND (base_address, 0);
-         break;
-       default:
-         if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
-           {
-             fprintf (vect_dump, "not vectorized: no memtag ref: "); 
-             print_generic_expr (vect_dump, memref, TDF_SLIM);
-           }
-         return NULL_TREE;
-       }
-    }
-           
-  if (!base_address)
-    /* MEMREF cannot be analyzed.  */
-    return NULL_TREE;
-
-  if (SSA_VAR_P (*memtag) && var_can_have_subvars (*memtag))
-    *subvars = get_subvars_for_var (*memtag);
-
-  /* Part 2: Combine the results of object and address analysis to calculate 
-     INITIAL_OFFSET, STEP and misalignment info.  */
-  *offset = size_binop (PLUS_EXPR, object_offset, address_offset);
-  if (object_misalign && address_misalign)
-    *misalign = size_binop (PLUS_EXPR, object_misalign, address_misalign);
-  else
-    *misalign = NULL_TREE;
-  *step = size_binop (PLUS_EXPR, object_step, address_step); 
-  *base_aligned = object_base_aligned && address_base_aligned;
-
-  if (vect_print_dump_info (REPORT_DETAILS))
-    {
-      fprintf (vect_dump, "Results of object analysis for: ");
-      print_generic_expr (vect_dump, memref, TDF_SLIM);
-      fprintf (vect_dump, "\n\tbase_address: ");
-      print_generic_expr (vect_dump, base_address, TDF_SLIM);
-      fprintf (vect_dump, "\n\toffset: ");
-      print_generic_expr (vect_dump, *offset, TDF_SLIM);
-      fprintf (vect_dump, "\n\tstep: ");
-      print_generic_expr (vect_dump, *step, TDF_SLIM);
-      fprintf (vect_dump, "\n\tbase aligned %d\n\tmisalign: ", *base_aligned);
-      print_generic_expr (vect_dump, *misalign, TDF_SLIM);
-    }
-  return base_address;
-}
-
-
 /* Function vect_analyze_data_refs.
 
-   Find all the data references in the loop.
+  Find all the data references in the loop.
 
-   The general structure of the analysis of data refs in the vectorizer is as 
+   The general structure of the analysis of data refs in the vectorizer is as
    follows:
-   1- vect_analyze_data_refs(loop): 
-      Find and analyze all data-refs in the loop:
-          foreach ref
-            base_address = vect_object_analysis(ref)
-      1.1- vect_object_analysis(ref): 
-           Analyze ref, and build a DR (data_reference struct) for it;
-           compute base, initial_offset, step and alignment. 
-           Call get_inner_reference for refs handled in this function.
-           Call vect_addr_analysis(addr) to analyze pointer type expressions.
-      Set ref_stmt.base, ref_stmt.initial_offset, ref_stmt.alignment,  
-      ref_stmt.memtag, ref_stmt.ptr_info and ref_stmt.step accordingly. 
-   2- vect_analyze_dependences(): apply dependence testing using ref_stmt.DR
+   1- vect_analyze_data_refs(loop): call compute_data_dependences_for_loop to
+      find and analyze all data-refs in the loop and their dependences.
+   2- vect_analyze_dependences(): apply dependence testing using ddrs.
    3- vect_analyze_drs_alignment(): check that ref_stmt.alignment is ok.
    4- vect_analyze_drs_access(): check that ref_stmt.step is ok.
 
-   FORNOW: Handle aligned INDIRECT_REFs and ARRAY_REFs 
-          which base is really an array (not a pointer) and which alignment 
-          can be forced. This restriction will be relaxed.  */
+*/
 
 static bool
-vect_analyze_data_refs (loop_vec_info loop_vinfo)
+vect_analyze_data_refs (loop_vec_info loop_vinfo)  
 {
   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
-  basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
-  int nbbs = loop->num_nodes;
-  block_stmt_iterator si;
-  int j;
-  struct data_reference *dr;
+  unsigned int i;
+  varray_type datarefs;
+  tree scalar_type;
 
   if (vect_print_dump_info (REPORT_DETAILS))
     fprintf (vect_dump, "=== vect_analyze_data_refs ===");
 
-  for (j = 0; j < nbbs; j++)
-    {
-      basic_block bb = bbs[j];
-      for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
-       {
-         bool is_read = false;
-         tree stmt = bsi_stmt (si);
-         stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
-         varray_type *datarefs = NULL;
-         tree memref = NULL;
-         tree scalar_type, vectype;      
-         tree base, offset, misalign, step, tag;
-         struct ptr_info_def *ptr_info;
-         bool base_aligned;
-         subvar_t subvars = NULL;
-         bool no_vuse, no_vmaymust;
-
-         /* Assumption: there exists a data-ref in stmt, if and only if 
-             it has vuses/vdefs.  */
-
-         no_vuse = ZERO_SSA_OPERANDS (stmt, SSA_OP_VUSE);
-         no_vmaymust = ZERO_SSA_OPERANDS (stmt,
-                                          SSA_OP_VMAYDEF | SSA_OP_VMUSTDEF);
-         if (no_vuse && no_vmaymust)
-           continue;
+  compute_data_dependences_for_loop (loop, false,
+                                     &(LOOP_VINFO_DATAREFS (loop_vinfo)),
+                                     &(LOOP_VINFO_DDRS (loop_vinfo)));
 
-         if (!no_vuse && !no_vmaymust)
-           {
-             if (vect_print_dump_info (REPORT_DETAILS))
-               {
-                 fprintf (vect_dump, "unexpected vdefs and vuses in stmt: ");
-                 print_generic_expr (vect_dump, stmt, TDF_SLIM);
-               }
-             return false;
-           }
-
-         if (TREE_CODE (stmt) != MODIFY_EXPR)
-           {
-             if (vect_print_dump_info (REPORT_DETAILS))
-               {
-                 fprintf (vect_dump, "unexpected vops in stmt: ");
-                 print_generic_expr (vect_dump, stmt, TDF_SLIM);
-               }
-             return false;
-           }
-
-         if (!no_vuse)
-           {
-             memref = TREE_OPERAND (stmt, 1);
-             datarefs = &(LOOP_VINFO_DATAREF_READS (loop_vinfo));
-             is_read = true;
-           } 
-         else /* vdefs */
-           {
-             memref = TREE_OPERAND (stmt, 0);
-             datarefs = &(LOOP_VINFO_DATAREF_WRITES (loop_vinfo));
-             is_read = false;
-           }
-         
-         scalar_type = TREE_TYPE (memref);
-         vectype = get_vectype_for_scalar_type (scalar_type);
-         if (!vectype)
-           {
-             if (vect_print_dump_info (REPORT_DETAILS))
-               {
-                 fprintf (vect_dump, "no vectype for stmt: ");
-                 print_generic_expr (vect_dump, stmt, TDF_SLIM);
-                 fprintf (vect_dump, " scalar_type: ");
-                 print_generic_expr (vect_dump, scalar_type, TDF_DETAILS);
-               }
-             /* It is not possible to vectorize this data reference.  */
-             return false;
-           }
-        /* Analyze MEMREF. If it is of a supported form, build data_reference
-            struct for it (DR).  */
-         dr = NULL; 
-         base = vect_object_analysis (memref, stmt, is_read, vectype, &dr, 
-                                      &offset, &misalign, &step, 
-                                      &base_aligned, &tag, &ptr_info,
-                                      &subvars);
-         if (!base)
-           {
-             if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
-               {
-                 fprintf (vect_dump, "not vectorized: unhandled data ref: "); 
-                 print_generic_expr (vect_dump, stmt, TDF_SLIM);
-               }
-             return false;
-           }
-         STMT_VINFO_VECT_DR_BASE_ADDRESS (stmt_info) = base;
-         STMT_VINFO_VECT_INIT_OFFSET (stmt_info) = offset;
-         STMT_VINFO_VECT_STEP (stmt_info) = step;
-         STMT_VINFO_VECT_MISALIGNMENT (stmt_info) = misalign;
-         STMT_VINFO_VECT_BASE_ALIGNED_P (stmt_info) = base_aligned;
-         STMT_VINFO_MEMTAG (stmt_info) = tag;
-         STMT_VINFO_PTR_INFO (stmt_info) = ptr_info;
-         STMT_VINFO_SUBVARS (stmt_info) = subvars;
-         STMT_VINFO_VECTYPE (stmt_info) = vectype;
-         VARRAY_PUSH_GENERIC_PTR (*datarefs, dr);
-         STMT_VINFO_DATA_REF (stmt_info) = dr;
-       }
+  /* Go through the data-refs, check that the analysis succeeded. Update pointer
+     from stmt_vec_info struct to DR and vectype.  */
+  datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
+  for (i = 0; i < VARRAY_ACTIVE_SIZE (datarefs); i++)
+    {
+      struct data_reference *dr = VARRAY_GENERIC_PTR (datarefs, i);
+      tree stmt;
+      stmt_vec_info stmt_info;
+   
+      if (!dr || !DR_REF (dr))
+        {
+          if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
+              fprintf (vect_dump, "not vectorized: unhandled data-ref ");
+          return false;
+        }
+      /* Update DR field in stmt_vec_info struct.  */
+      stmt = DR_STMT (dr);
+      stmt_info = vinfo_for_stmt (stmt);
+  
+      if (STMT_VINFO_DATA_REF (stmt_info))
+        {
+          if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
+            {
+              fprintf (vect_dump,
+                       "not vectorized: more than one data ref in stmt: ");
+              print_generic_expr (vect_dump, stmt, TDF_SLIM);
+            }
+          return false;
+        }
+      STMT_VINFO_DATA_REF (stmt_info) = dr;
+     
+      /* Check that analysis of the data-ref succeeded.  */
+      if (!DR_BASE_ADDRESS (dr) || !DR_OFFSET (dr) || !DR_INIT (dr)
+          || !DR_STEP (dr))   
+        {
+          if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
+            {
+              fprintf (vect_dump, "not vectorized: data ref analysis failed ");
+              print_generic_expr (vect_dump, stmt, TDF_SLIM);
+            }
+          return false;
+        }
+      if (!DR_MEMTAG (dr))
+        {
+          if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
+            {
+              fprintf (vect_dump, "not vectorized: no memory tag for ");
+              print_generic_expr (vect_dump, DR_REF (dr), TDF_SLIM);
+            }
+          return false;
+        }
+                       
+      /* Set vectype for STMT.  */
+      scalar_type = TREE_TYPE (DR_REF (dr));
+      STMT_VINFO_VECTYPE (stmt_info) =
+                get_vectype_for_scalar_type (scalar_type);
+      if (!STMT_VINFO_VECTYPE (stmt_info)) 
+        {
+          if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
+            {
+              fprintf (vect_dump,
+                       "not vectorized: no vectype for stmt: ");
+              print_generic_expr (vect_dump, stmt, TDF_SLIM);
+              fprintf (vect_dump, " scalar_type: ");
+              print_generic_expr (vect_dump, scalar_type, TDF_DETAILS);
+            }
+          return false;
+        }
     }
-
+      
   return true;
 }
 
index c2a8f0d9dc4e173d6b270d41c228a7460f44a1af..9dab8bcda4bff77455f0fdc6cebf2c31d4668b9e 100644 (file)
@@ -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);
     }
 }
index af5382cd735165b955e9da8a25678f1d7deef092..4a9bbe8f49c1b10d013166141fbab9d7a462b592 100644 (file)
@@ -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
index 87d3138bcaa0efd69ca410843b2c6dc4c341731f..5fdca3d65021dc1f10bb749fd6be8e6a1f78078b 100644 (file)
@@ -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.  */
-#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_INT_NITERS(L) (TREE_INT_CST_LOW ((L)->num_iters))
+  /* 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_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_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
 
index 10472fe839b51aeef9ca81a5c0abb3f3646d6a0e..df730a54af260d78c41b3ebe6886b624578bdc3b 100644 (file)
@@ -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  */
This page took 0.20008 seconds and 5 git commands to generate.