OSDN Git Service

* tree-ssanames.c (duplicate_ssa_name_ptr_info): New function.
authordorit <dorit@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 29 Mar 2005 16:10:22 +0000 (16:10 +0000)
committerdorit <dorit@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 29 Mar 2005 16:10:22 +0000 (16:10 +0000)
        (duplicate_ssa_name): Call duplicate_ssa_name_ptr_info.
        * tree-vect-analyze.c (vect_object_analysis): additional parm
        pass back a "struct ptr_info_def *" with the points-to info.
        (vect_analyze_data_refs): set the STMT_VINFO_PTR_INFO for the
        statement using info returned from vect_object_analysis.
        * tree-vect-transform.c (update_vuses_to_preheader): New function.
        (vect_create_data_ref_ptr): Remove updates to vars_to_rename
        for virtual uses and defs when creating a replacement vector
        reference.  Call duplicate_ssa_name_ptr_info to define points-to
        info for vector pointer replacement using STMT_VINFO_PTR_INFO.
        (vectorizable_store): copy_virtual_operands and update
        definition statements.
        (vectorizable_load): copy_virtual_operands.  Remove call to
        mark_call_clobbered_vars_to_rename for call to "const" builtin.
        * tree-vectorizer.c (vectorize_loops): Remove calls to
        rewrite_into_ssa and bitmap_clear (vars_to_rename).
        (new_stmt_vec_info): initialize STMT_VINFO_PTR_INFO for stmt.
        * tree-vectorizer.h (_stmt_vec_info): add field ptr_info and
        define macro STMT_VINFO_PTR_INFO for use in accessing.
        * tree.h add export of duplicate_ssa_name_ptr_info.
        * rs6000.c (altivec_init_builtins): Declare builtin function
        __builtin_altivec_mask_for_load to be "const".

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@97164 138bc75d-0d04-0410-961f-82ee72b054a4

17 files changed:
gcc/ChangeLog
gcc/config/rs6000/rs6000.c
gcc/fortran/ChangeLog
gcc/fortran/f95-lang.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/vect/vect-1.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/vect/vect-2.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/vect/vect-3.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/vect/vect-4.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/vect/vect-5.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/vect/vect.exp [new file with mode: 0644]
gcc/tree-ssanames.c
gcc/tree-vect-analyze.c
gcc/tree-vect-transform.c
gcc/tree-vectorizer.c
gcc/tree-vectorizer.h
gcc/tree.h

index 9922f7e..0d5849a 100644 (file)
@@ -1,3 +1,29 @@
+2005-03-29  Keith Besaw  <kbesaw@us.ibm.com>
+
+       * tree-ssanames.c (duplicate_ssa_name_ptr_info): New function.
+       (duplicate_ssa_name): Call duplicate_ssa_name_ptr_info.
+       * tree-vect-analyze.c (vect_object_analysis): additional parm
+       pass back a "struct ptr_info_def *" with the points-to info.
+       (vect_analyze_data_refs): set the STMT_VINFO_PTR_INFO for the
+       statement using info returned from vect_object_analysis.
+       * tree-vect-transform.c (update_vuses_to_preheader): New function.
+       (vect_create_data_ref_ptr): Remove updates to vars_to_rename
+       for virtual uses and defs when creating a replacement vector
+       reference.  Call duplicate_ssa_name_ptr_info to define points-to
+       info for vector pointer replacement using STMT_VINFO_PTR_INFO.
+       (vectorizable_store): copy_virtual_operands and update
+       definition statements.
+       (vectorizable_load): copy_virtual_operands.  Remove call to
+       mark_call_clobbered_vars_to_rename for call to "const" builtin.
+       * tree-vectorizer.c (vectorize_loops): Remove calls to
+       rewrite_into_ssa and bitmap_clear (vars_to_rename).
+       (new_stmt_vec_info): initialize STMT_VINFO_PTR_INFO for stmt.
+       * tree-vectorizer.h (_stmt_vec_info): add field ptr_info and
+       define macro STMT_VINFO_PTR_INFO for use in accessing.
+       * tree.h add export of duplicate_ssa_name_ptr_info.
+       * rs6000.c (altivec_init_builtins): Declare builtin function
+       __builtin_altivec_mask_for_load to be "const".
+
 2005-03-29  Jakub Jelinek  <jakub@redhat.com>
 
        PR middle-end/20622
index 3fc857a..3ac7c83 100644 (file)
@@ -7665,9 +7665,11 @@ altivec_init_builtins (void)
          targetm.vectorize.builtin_mask_for_load.  */
 
       decl = lang_hooks.builtin_function ("__builtin_altivec_mask_for_load",
-                                         v16qi_ftype_long_pcvoid,
-                                         ALTIVEC_BUILTIN_MASK_FOR_LOAD,
-                                         BUILT_IN_MD, NULL, NULL_TREE);
+                               v16qi_ftype_long_pcvoid,
+                               ALTIVEC_BUILTIN_MASK_FOR_LOAD,
+                               BUILT_IN_MD, NULL,
+                               tree_cons (get_identifier ("const"),
+                                          NULL_TREE, NULL_TREE));
       /* Record the decl. Will be used by rs6000_builtin_mask_for_load.  */
       altivec_builtin_mask_for_load = decl;
     }
index 9967174..ccbd3cb 100644 (file)
@@ -1,3 +1,8 @@
+2005-03-29  Keith Besaw  <kbesaw@us.ibm.com>
+
+       * f95-lang.c (builtin_function): Process the attrs parameter
+       and apply the "const" attribute to the builtin if found.
+
 2005-03-27  Steven G. Kargl  <kargls@comcast.net>
 
        * intrinsic.texi: Document AIMAG, AINT, ALL
index e0c22da..2fb06a9 100644 (file)
@@ -680,7 +680,7 @@ builtin_function (const char *name,
                  int function_code,
                  enum built_in_class class,
                  const char *library_name,
-                 tree attrs ATTRIBUTE_UNUSED)
+                 tree attrs)
 {
   tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
   DECL_EXTERNAL (decl) = 1;
@@ -691,6 +691,17 @@ builtin_function (const char *name,
   pushdecl (decl);
   DECL_BUILT_IN_CLASS (decl) = class;
   DECL_FUNCTION_CODE (decl) = function_code;
+
+  /* Possibly apply some default attributes to this built-in function.  */
+  if (attrs)
+    {
+      /* FORNOW the only supported attribute is "const".  If others need
+         to be supported then see the more general solution in procedure
+         builtin_function in c-decl.c  */
+      if (lookup_attribute ( "const", attrs ))
+        TREE_READONLY (decl) = 1;
+    }
+
   return decl;
 }
 
index 2cc2451..dba8cc6 100644 (file)
@@ -1,3 +1,13 @@
+2005-03-29  Dorit Naishlos  <dorit@il.ibm.com>
+
+       * gfortran.dg/vect: New directory.
+       * gfortran.dg/vect/vect.exp: New.
+       * gfortran.dg/vect/vect-1.f90: New test.
+       * gfortran.dg/vect/vect-2.f90: New test.
+       * gfortran.dg/vect/vect-3.f90: New test.
+       * gfortran.dg/vect/vect-4.f90: New test.
+       * gfortran.dg/vect/vect-5.f90: New test.
+
 2005-03-29  Jakub Jelinek  <jakub@redhat.com>
 
        PR middle-end/20622
diff --git a/gcc/testsuite/gfortran.dg/vect/vect-1.f90 b/gcc/testsuite/gfortran.dg/vect/vect-1.f90
new file mode 100644 (file)
index 0000000..90b37e4
--- /dev/null
@@ -0,0 +1,10 @@
+! { dg-do compile }
+! { dg-require-effective-target vect_float }
+
+DIMENSION A(1000000), B(1000000), C(1000000)
+READ*, X, Y
+A = LOG(X); B = LOG(Y); C = A + B
+PRINT*, C(500000)
+END
+
+! { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" } }
diff --git a/gcc/testsuite/gfortran.dg/vect/vect-2.f90 b/gcc/testsuite/gfortran.dg/vect/vect-2.f90
new file mode 100644 (file)
index 0000000..f9cc35e
--- /dev/null
@@ -0,0 +1,13 @@
+! { dg-do compile }
+! { dg-require-effective-target vect_float }
+
+SUBROUTINE FOO(A, B, C)
+DIMENSION A(1000000), B(1000000), C(1000000)
+READ*, X, Y
+A = LOG(X); B = LOG(Y); C = A + B
+PRINT*, C(500000)
+END
+
+! { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { xfail vect_no_align } } }
+! { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 3 "vect" { xfail vect_no_align } } }
+! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail vect_no_align } } }
diff --git a/gcc/testsuite/gfortran.dg/vect/vect-3.f90 b/gcc/testsuite/gfortran.dg/vect/vect-3.f90
new file mode 100644 (file)
index 0000000..26b9c79
--- /dev/null
@@ -0,0 +1,12 @@
+! { dg-do compile }
+! { dg-require-effective-target vect_float }
+
+SUBROUTINE SAXPY(X, Y, A, N)
+DIMENSION X(N), Y(N)
+Y = Y + A * X
+END
+
+! fail to vectorize due to failure to compute number of iterations (PR tree-optimization/18527)
+! { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } 
+! { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail *-*-* } } } 
+! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail *-*-* } } } 
diff --git a/gcc/testsuite/gfortran.dg/vect/vect-4.f90 b/gcc/testsuite/gfortran.dg/vect/vect-4.f90
new file mode 100644 (file)
index 0000000..7659438
--- /dev/null
@@ -0,0 +1,13 @@
+! { dg-do compile }
+! { dg-require-effective-target vect_float }
+
+SUBROUTINE SAXPY(X, Y, A)
+DIMENSION X(64), Y(64)
+Y = Y + A * X
+END
+
+! fail to vectorize until the patch that ignores dependence-distance 0 is 
+! brought from autovect. 
+! { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } 
+! { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail *-*-* } } }
+! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail *-*-* } } }
diff --git a/gcc/testsuite/gfortran.dg/vect/vect-5.f90 b/gcc/testsuite/gfortran.dg/vect/vect-5.f90
new file mode 100644 (file)
index 0000000..44d8b62
--- /dev/null
@@ -0,0 +1,40 @@
+! { dg-require-effective-target vect_int }
+
+        Subroutine foo (N, M)
+        Integer N
+        Integer M
+        integer A(8,16)
+        integer B(8)
+
+        B = (/ 2, 3, 5, 7, 11, 13, 17, 23 /)
+
+        ! Unknown loop bound. J depends on I.
+
+        do I = 1, N
+          do J = I, M
+            A(J,2) = B(J)
+          end do
+        end do
+
+        do I = 1, N
+          do J = I, M
+            if (A(J,2) /= B(J)) then
+              call abort ()
+              endif
+          end do
+        end do
+
+        Return
+        end
+
+
+        program main
+
+        Call foo (16, 8)
+
+        stop
+        end
+
+! { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { xfail vect_no_align } } }
+! { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail vect_no_align } } }
+! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail vect_no_align } } }
diff --git a/gcc/testsuite/gfortran.dg/vect/vect.exp b/gcc/testsuite/gfortran.dg/vect/vect.exp
new file mode 100644 (file)
index 0000000..2b84fe4
--- /dev/null
@@ -0,0 +1,99 @@
+# Copyright (C) 1997, 2004 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Load support procs.
+load_lib gfortran-dg.exp
+load_lib target-supports.exp
+
+# Set up flags used for tests that don't specify options.
+set DEFAULT_VECTCFLAGS ""
+
+# These flags are used for all targets.
+lappend DEFAULT_VECTCFLAGS "-O2" "-ftree-vectorize" \
+  "-ftree-vectorizer-verbose=3" "-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.
+# Executing vector instructions on a system without hardware vector support
+# is also disabled by a call to check_vect, but disabling execution here is
+# more efficient.
+global dg-do-what-default
+set save-dg-do-what-default ${dg-do-what-default}
+
+# Skip these tests for targets that do not support generating vector
+# code.  Set additional target-dependent vector flags, which can be
+# overridden by using dg-options in individual tests.
+if [istarget "powerpc*-*-*"] {
+    # If there are powerpc targets to skip, do it here.
+
+    lappend DEFAULT_VECTCFLAGS "-maltivec"
+    if [check_vmx_hw_available] {
+       set dg-do-what-default run
+    } else {
+       if [is-effective-target ilp32] {
+           # Specify a cpu that supports VMX for compile-only tests.
+           lappend DEFAULT_VECTCFLAGS "-mcpu=7400"
+       }
+       set dg-do-what-default compile
+    }
+} elseif { [istarget "i?86-*-*"] || [istarget "x86_64-*-*"] } {
+    lappend DEFAULT_VECTCFLAGS "-msse2"
+    set dg-do-what-default run
+} elseif [istarget "mipsisa64*-*-*"] {
+    lappend DEFAULT_VECTCFLAGS "-mpaired-single"
+    set dg-do-what-default run
+} elseif [istarget "sparc*-*-*"] {
+    lappend DEFAULT_VECTCFLAGS "-mcpu=ultrasparc" "-mvis"
+    set dg-do-what-default run
+} elseif [istarget "alpha*-*-*"] {
+    lappend DEFAULT_VECTCFLAGS "-mmax"
+    if [check_alpha_max_hw_available] {
+       set dg-do-what-default run
+    } else {
+       set dg-do-what-default compile
+    }
+} elseif [istarget "ia64-*-*"] {
+    set dg-do-what-default run
+} else {
+    return
+}
+
+# Return 1 if the effective target is LP64 or if the effective target
+# does not support a vector alignment mechanism.
+
+proc check_effective_target_lp64_or_vect_no_align { } {
+    if { [is-effective-target lp64]
+          || [is-effective-target vect_no_align] } {
+        set answer 1
+    } else {
+        set answer 0
+    }
+    return $answer
+}
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+gfortran-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[fF\]{,90,95} ]] $DEFAULT_VECTCFLAGS
+
+# Clean up.
+set dg-do-what-default ${save-dg-do-what-default}
+
+# All done.
+dg-finish
index 38aab0b..a89d608 100644 (file)
@@ -279,22 +279,38 @@ duplicate_ssa_name (tree name, tree stmt)
 {
   tree new_name = make_ssa_name (SSA_NAME_VAR (name), stmt);
   struct ptr_info_def *old_ptr_info = SSA_NAME_PTR_INFO (name);
+
+  if (old_ptr_info)
+    duplicate_ssa_name_ptr_info (new_name, old_ptr_info);
+
+  return new_name;
+}
+
+
+/* Creates a duplicate of the ptr_info_def at PTR_INFO for use by
+   the ssa name NAME.  */
+
+void
+duplicate_ssa_name_ptr_info (tree name, struct ptr_info_def *ptr_info)
+{
   struct ptr_info_def *new_ptr_info;
 
-  if (!old_ptr_info)
-    return new_name;
+  gcc_assert (POINTER_TYPE_P (TREE_TYPE (name)));
+  gcc_assert (!SSA_NAME_PTR_INFO (name));
+
+  if (!ptr_info)
+    return;
 
   new_ptr_info = ggc_alloc (sizeof (struct ptr_info_def));
-  *new_ptr_info = *old_ptr_info;
+  *new_ptr_info = *ptr_info;
 
-  if (old_ptr_info->pt_vars)
+  if (ptr_info->pt_vars)
     {
       new_ptr_info->pt_vars = BITMAP_GGC_ALLOC ();
-      bitmap_copy (new_ptr_info->pt_vars, old_ptr_info->pt_vars);
+      bitmap_copy (new_ptr_info->pt_vars, ptr_info->pt_vars);
     }
 
-  SSA_NAME_PTR_INFO (new_name) = new_ptr_info;
-  return new_name;
+  SSA_NAME_PTR_INFO (name) = new_ptr_info;
 }
 
 
index f3144e1..97ad231 100644 (file)
@@ -71,7 +71,8 @@ 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 *, subvar_t *);
+                                 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 *);
@@ -1476,6 +1477,7 @@ vect_address_analysis (tree expr, tree stmt, bool is_read, tree vectype,
   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))
@@ -1529,7 +1531,7 @@ vect_address_analysis (tree expr, tree stmt, bool is_read, tree vectype,
       base_address = vect_object_analysis (TREE_OPERAND (expr, 0), stmt,
                                           is_read, vectype, &dr, offset, 
                                           misalign, step, base_aligned, 
-                                          &dummy, &dummy2);
+                                          &dummy, &dummy1, &dummy2);
       return base_address;
 
     case SSA_NAME:
@@ -1608,6 +1610,7 @@ vect_address_analysis (tree expr, tree stmt, bool is_read, tree vectype,
    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),
@@ -1618,7 +1621,7 @@ 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,
-                     subvar_t *subvars)
+                     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);
@@ -1635,6 +1638,8 @@ vect_object_analysis (tree memref, tree stmt, bool is_read,
   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.  */
@@ -1722,9 +1727,13 @@ vect_object_analysis (tree memref, tree stmt, bool is_read,
 
   /* 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, TREE_OPERAND (memref, 0));
+      access_fn = analyze_scalar_evolution (loop, ptr_ref);
       if (!access_fn)
        {
          if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
@@ -1849,7 +1858,7 @@ vect_object_analysis (tree memref, tree stmt, bool is_read,
            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 and ref_stmt.step accordingly. 
+      ref_stmt.memtag, ref_stmt.ptr_info and ref_stmt.step accordingly. 
    2- vect_analyze_dependences(): apply dependence testing using ref_stmt.DR
    3- vect_analyze_drs_alignment(): check that ref_stmt.alignment is ok.
    4- vect_analyze_drs_access(): check that ref_stmt.step is ok.
@@ -1887,6 +1896,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo)
          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;
 
@@ -1952,7 +1962,8 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo)
          dr = NULL; 
          base = vect_object_analysis (memref, stmt, is_read, vectype, &dr, 
                                       &offset, &misalign, &step, 
-                                      &base_aligned, &tag, &subvars);
+                                      &base_aligned, &tag, &ptr_info,
+                                      &subvars);
          if (!base)
            {
              if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
@@ -1969,6 +1980,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo)
          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);
index 5dd9efe..4940f2d 100644 (file)
@@ -57,6 +57,7 @@ static tree vect_get_vec_def_for_operand (tree, tree);
 static tree vect_init_vector (tree, tree);
 static void vect_finish_stmt_generation 
   (tree stmt, tree vec_stmt, block_stmt_iterator *bsi);
+static void update_vuses_to_preheader (tree, struct loop*);
 
 /* Utility function dealing with loop peeling (not peeling itself).  */
 static void vect_generate_tmps_on_preheader 
@@ -304,11 +305,6 @@ vect_create_data_ref_ptr (tree stmt, block_stmt_iterator *bsi, tree offset,
   tree vect_ptr_type;
   tree vect_ptr;
   tree tag;
-  v_may_def_optype v_may_defs = STMT_V_MAY_DEF_OPS (stmt);
-  v_must_def_optype v_must_defs = STMT_V_MUST_DEF_OPS (stmt);
-  vuse_optype vuses = STMT_VUSE_OPS (stmt);
-  int nvuses, nv_may_defs, nv_must_defs;
-  int i;
   tree new_temp;
   tree vec_stmt;
   tree new_stmt_list = NULL_TREE;
@@ -348,38 +344,14 @@ vect_create_data_ref_ptr (tree stmt, block_stmt_iterator *bsi, tree offset,
   add_referenced_tmp_var (vect_ptr);
   
   
-  /** (2) Handle aliasing information of the new vector-pointer:  **/
+  /** (2) Add aliasing information to the new vector-pointer:
+          (The points-to info (SSA_NAME_PTR_INFO) may be defined later.)  **/
   
   tag = STMT_VINFO_MEMTAG (stmt_info);
   gcc_assert (tag);
   get_var_ann (vect_ptr)->type_mem_tag = tag;
   get_var_ann (vect_ptr)->subvars = STMT_VINFO_SUBVARS (stmt_info);
 
-  /* Mark for renaming all aliased variables
-     (i.e, the may-aliases of the type-mem-tag).  */
-  nvuses = NUM_VUSES (vuses);
-  nv_may_defs = NUM_V_MAY_DEFS (v_may_defs);
-  nv_must_defs = NUM_V_MUST_DEFS (v_must_defs);
-
-  for (i = 0; i < nvuses; i++)
-    {
-      tree use = VUSE_OP (vuses, i);
-      if (TREE_CODE (use) == SSA_NAME)
-        bitmap_set_bit (vars_to_rename, var_ann (SSA_NAME_VAR (use))->uid);
-    }
-  for (i = 0; i < nv_may_defs; i++)
-    {
-      tree def = V_MAY_DEF_RESULT (v_may_defs, i);
-      if (TREE_CODE (def) == SSA_NAME)
-        bitmap_set_bit (vars_to_rename, var_ann (SSA_NAME_VAR (def))->uid);
-    }
-  for (i = 0; i < nv_must_defs; i++)
-    {
-      tree def = V_MUST_DEF_RESULT (v_must_defs, i);
-      if (TREE_CODE (def) == SSA_NAME)
-        bitmap_set_bit (vars_to_rename, var_ann (SSA_NAME_VAR (def))->uid);
-    }
-
 
   /** (3) Calculate the initial address the vector-pointer, and set
           the vector-pointer to point to it before the loop:  **/
@@ -405,7 +377,13 @@ vect_create_data_ref_ptr (tree stmt, block_stmt_iterator *bsi, tree offset,
   /** (4) Handle the updating of the vector-pointer inside the loop: **/
 
   if (only_init) /* No update in loop is required.  */
-    return vect_ptr_init;
+    {
+      /* 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));
+      return vect_ptr_init;
+    }
 
   idx = vect_create_index_for_vector_ref (loop_vinfo);
 
@@ -436,6 +414,9 @@ vect_create_data_ref_ptr (tree stmt, block_stmt_iterator *bsi, tree offset,
   bsi_insert_before (bsi, vec_stmt, BSI_SAME_STMT);
   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));
   return data_ref_ptr;
 }
 
@@ -865,6 +846,8 @@ vectorizable_store (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
   enum machine_mode vec_mode;
   tree dummy;
   enum dr_alignment_support alignment_support_cheme;
+  v_may_def_optype v_may_defs;
+  int nv_may_defs, i;
 
   /* Is vectorizable store? */
 
@@ -922,6 +905,20 @@ vectorizable_store (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
   *vec_stmt = build2 (MODIFY_EXPR, vectype, data_ref, vec_oprnd1);
   vect_finish_stmt_generation (stmt, *vec_stmt, bsi);
 
+  /* Copy the V_MAY_DEFS representing the aliasing of the original array
+     element's definition to the vector's definition then update the
+     defining statement.  The original is being deleted so the same
+     SSA_NAMEs can be used.  */
+  copy_virtual_operands (*vec_stmt, stmt);
+  v_may_defs = STMT_V_MAY_DEF_OPS (*vec_stmt);
+  nv_may_defs = NUM_V_MAY_DEFS (v_may_defs);
+           
+  for (i = 0; i < nv_may_defs; i++)
+    {
+      tree ssa_name = V_MAY_DEF_RESULT (v_may_defs, i);
+      SSA_NAME_DEF_STMT (ssa_name) = *vec_stmt;
+    }
+
   return true;
 }
 
@@ -1023,6 +1020,7 @@ vectorizable_load (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
       new_temp = make_ssa_name (vec_dest, new_stmt);
       TREE_OPERAND (new_stmt, 0) = new_temp;
       vect_finish_stmt_generation (stmt, new_stmt, bsi);
+      copy_virtual_operands (new_stmt, stmt);
     }
   else if (alignment_support_cheme == dr_unaligned_software_pipeline)
     {
@@ -1060,6 +1058,8 @@ vectorizable_load (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
       new_bb = bsi_insert_on_edge_immediate (pe, new_stmt);
       gcc_assert (!new_bb);
       msq_init = TREE_OPERAND (new_stmt, 0);
+      copy_virtual_operands (new_stmt, stmt);
+      update_vuses_to_preheader (new_stmt, loop);
 
 
       /* <2> Create lsq = *(floor(p2')) in the loop  */ 
@@ -1074,6 +1074,7 @@ vectorizable_load (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
       TREE_OPERAND (new_stmt, 0) = new_temp;
       vect_finish_stmt_generation (stmt, new_stmt, bsi);
       lsq = TREE_OPERAND (new_stmt, 0);
+      copy_virtual_operands (new_stmt, stmt);
 
 
       /* <3> */
@@ -1092,9 +1093,12 @@ vectorizable_load (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
          gcc_assert (!new_bb);
          magic = TREE_OPERAND (new_stmt, 0);
 
-         /* Since we have just created a CALL_EXPR, we may need to
-            rename call-clobbered variables.  */
-         mark_call_clobbered_vars_to_rename ();
+         /* The result of the CALL_EXPR to this builtin is determined from
+            the value of the parameter and no global variables are touched
+            which makes the builtin a "const" function.  Requiring the
+            builtin to have the "const" attribute makes it unnecessary
+            to call mark_call_clobbered_vars_to_rename.  */
+         gcc_assert (TREE_READONLY (builtin_decl));
        }
       else
        {
@@ -1268,6 +1272,84 @@ vect_generate_tmps_on_preheader (loop_vec_info loop_vinfo,
 }
 
 
+/* Function update_vuses_to_preheader.
+
+   Input:
+   STMT - a statement with potential VUSEs.
+   LOOP - the loop whose preheader will contain STMT.
+
+   It's possible to vectorize a loop even though an SSA_NAME from a VUSE
+   appears to be defined in a V_MAY_DEF in another statement in a loop.
+   One such case is when the VUSE is at the dereference of a __restricted__
+   pointer in a load and the V_MAY_DEF is at the dereference of a different
+   __restricted__ pointer in a store.  Vectorization may result in
+   copy_virtual_uses being called to copy the problematic VUSE to a new
+   statement that is being inserted in the loop preheader.  This procedure
+   is called to change the SSA_NAME in the new statement's VUSE from the
+   SSA_NAME updated in the loop to the related SSA_NAME available on the
+   path entering the loop.
+
+   When this function is called, we have the following situation:
+
+        # vuse <name1>
+        S1: vload
+    do {
+        # name1 = phi < name0 , name2>
+
+        # vuse <name1>
+        S2: vload
+
+        # name2 = vdef <name1>
+        S3: vstore
+
+    }while...
+
+   Stmt S1 was created in the loop preheader block as part of misaligned-load
+   handling. This function fixes the name of the vuse of S1 from 'name1' to
+   'name0'.  */
+
+static void
+update_vuses_to_preheader (tree stmt, struct loop *loop)
+{
+  basic_block header_bb = loop->header;
+  edge preheader_e = loop_preheader_edge (loop);
+  vuse_optype vuses = STMT_VUSE_OPS (stmt);
+  int nvuses = NUM_VUSES (vuses);
+  int i;
+
+  for (i = 0; i < nvuses; i++)
+    {
+      tree ssa_name = VUSE_OP (vuses, i);
+      tree def_stmt = SSA_NAME_DEF_STMT (ssa_name);
+      tree name_var = SSA_NAME_VAR (ssa_name);
+      basic_block bb = bb_for_stmt (def_stmt);
+
+      /* For a use before any definitions, def_stmt is a NOP_EXPR.  */
+      if (!IS_EMPTY_STMT (def_stmt)
+         && flow_bb_inside_loop_p (loop, bb))
+        {
+          /* If the block containing the statement defining the SSA_NAME
+             is in the loop then it's necessary to find the definition
+             outside the loop using the PHI nodes of the header.  */
+         tree phi;
+         bool updated = false;
+
+         for (phi = phi_nodes (header_bb); phi; phi = TREE_CHAIN (phi))
+           {
+             if (SSA_NAME_VAR (PHI_RESULT (phi)) == name_var)
+               {
+                 SET_VUSE_OP (vuses, i, 
+                              PHI_ARG_DEF (phi, preheader_e->dest_idx));
+                 updated = true;
+                 break;
+               }
+           }
+         gcc_assert (updated);
+       }
+    }
+}
+
+
 /*   Function vect_update_ivs_after_vectorizer.
 
      "Advance" the induction variables of LOOP to the value they should take
index 5859880..9df3a68 100644 (file)
@@ -1167,6 +1167,7 @@ new_stmt_vec_info (tree stmt, loop_vec_info loop_vinfo)
   STMT_VINFO_VEC_STMT (res) = NULL;
   STMT_VINFO_DATA_REF (res) = NULL;
   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;
@@ -1618,7 +1619,5 @@ vectorize_loops (struct loops *loops)
       loop->aux = NULL;
     }
 
-  rewrite_into_ssa (false);
   rewrite_into_loop_closed_ssa (NULL); /* FORNOW */
-  bitmap_clear (vars_to_rename);
 }
index e32eed2..dee7a4e 100644 (file)
@@ -178,6 +178,7 @@ typedef struct _stmt_vec_info {
 
   /* Aliasing information.  */
   tree memtag;
+  struct ptr_info_def *ptr_info;
   subvar_t subvars;
 
   /** The following fields are used to store the information about 
@@ -220,7 +221,8 @@ typedef struct _stmt_vec_info {
 #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_SUBVARS(S)              (S)->subvars
+#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
index bb4f453..d09034c 100644 (file)
@@ -2801,6 +2801,7 @@ extern void init_ssanames (void);
 extern void fini_ssanames (void);
 extern tree make_ssa_name (tree, tree);
 extern tree duplicate_ssa_name (tree, tree);
+extern void duplicate_ssa_name_ptr_info (tree, struct ptr_info_def *);
 extern void release_ssa_name (tree);
 extern void release_defs (tree);
 extern void replace_ssa_name_symbol (tree, tree);