re PR tree-optimization/26197 (ICE in is_old_name with vectorizer)
authorDorit Nuzman <dorit@il.ibm.com>
Thu, 10 Aug 2006 12:07:22 +0000 (12:07 +0000)
committerDorit Nuzman <dorit@gcc.gnu.org>
Thu, 10 Aug 2006 12:07:22 +0000 (12:07 +0000)
        PR tree-optimization/26197
        * tree-ssa-alias.c (new_type_alias): Takes additional argument. Calls
        get_ref_base_and_extent and overlap_subvar to add only relevant
        subvars as may-aliases.
        (add_may_alias_for_new_tag): New function, factored out of
        new_type_alias.
        * tree-vect-transform.c (vect_create_data_ref_ptr): Call new_type_alias
        with additional argument.
        * tree-flow.h (new_type_alias): Takes additional argument.

From-SVN: r116060

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/vect/param-max-aliased-pr26197.cc [new file with mode: 0644]
gcc/testsuite/g++.dg/vect/vect.exp
gcc/tree-flow.h
gcc/tree-ssa-alias.c
gcc/tree-vect-transform.c

index 1497429fbc2dbd9cc87747326ea18dc939c88cf6..ddd2e67edce0b73898c50a31664490b3c534f8d2 100644 (file)
@@ -1,3 +1,15 @@
+2006-08-10  Dorit Nuzman  <dorit@il.ibm.com>
+
+       PR tree-optimization/26197
+       * tree-ssa-alias.c (new_type_alias): Takes additional argument. Calls
+       get_ref_base_and_extent and overlap_subvar to add only relevant
+       subvars as may-aliases.
+       (add_may_alias_for_new_tag): New function, factored out of
+       new_type_alias.
+       * tree-vect-transform.c (vect_create_data_ref_ptr): Call new_type_alias
+       with additional argument.
+       * tree-flow.h (new_type_alias): Takes additional argument.
+
 2006-08-09  Nathan Sidwell  <nathan@codesourcery.com>
 
        * gcov.c (no_data_file): New flag.
index 26af1f4959c910c1783648c55e042b1c141ea88b..55c187cad32af35bf4988e379e234f1bd76aec1f 100644 (file)
@@ -1,3 +1,9 @@
+2006-08-10  Dorit Nuzman  <dorit@il.ibm.com>
+
+       PR tree-optimization/26197
+       * g++.dg/vect/param-max-aliased-pr26197.cc: New test.
+       * g++.dg/vect/vect.exp: Compile the new testxs with --param max-aliased-vops=0.
+
 2006-08-09  Lee Millward  <lee.millward@codesourcery.com>
 
        PR c++/28637
diff --git a/gcc/testsuite/g++.dg/vect/param-max-aliased-pr26197.cc b/gcc/testsuite/g++.dg/vect/param-max-aliased-pr26197.cc
new file mode 100644 (file)
index 0000000..198cd6b
--- /dev/null
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+
+void g(const void*);
+struct B
+{
+  int* x[2];
+  int *p;
+  B()
+  {
+     for (int** p=x; p<x+4; ++p)
+      *p = 0;
+  }
+  ~B()
+   {
+      g(p);
+   }
+};
+void bar()
+{
+  const B &b = B();
+  g(&b);
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
index 1d9e4eb0f84db5361577f14e3daa650fc5d9ed51..ce51c8a4f256b6b332d28fe68ddbcc788c67146a 100644 (file)
@@ -89,6 +89,16 @@ dg-init
 dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{c,cc,S} ]] \
         "" $DEFAULT_VECTCFLAGS
 
+#### Tests with special options
+global SAVED_DEFAULT_VECTCFLAGS
+set SAVED_DEFAULT_VECTCFLAGS $DEFAULT_VECTCFLAGS
+    
+# --param max-aliased-vops=0
+set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS
+lappend DEFAULT_VECTCFLAGS "--param max-aliased-vops=0"
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/param-max-aliased*.\[cS\]]]  \
+        "" $DEFAULT_VECTCFLAGS 
+
 # Clean up.
 set dg-do-what-default ${save-dg-do-what-default} 
 
index d0c81515a26a6845169cb29d116978fd9b98cb11..46966663fe5f0f22ef024fd1290f0837c729b290 100644 (file)
@@ -667,7 +667,7 @@ 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 new_type_alias (tree, tree);
+extern void new_type_alias (tree, tree, tree);
 extern void count_uses_and_derefs (tree, tree, unsigned *, unsigned *, bool *);
 static inline subvar_t get_subvars_for_var (tree);
 static inline tree get_subvar_at (tree, unsigned HOST_WIDE_INT);
index 1607c71257a206e8c9ecc7c5874533a6923c9c6d..6bfa4bb6063d0d07f5ba916e4719422acefc5c82 100644 (file)
@@ -2691,79 +2691,123 @@ is_aliased_with (tree tag, tree sym)
   return false;
 }
 
+/* The following is based on code in add_stmt_operand to ensure that the
+   same defs/uses/vdefs/vuses will be found after replacing a reference
+   to var (or ARRAY_REF to var) with an INDIRECT_REF to ptr whose value
+   is the address of var.  Return a memtag for the ptr, after adding the 
+   proper may_aliases to it (which are the aliases of var, if it has any,
+   or var itself).  */
+
+static tree
+add_may_alias_for_new_tag (tree tag, tree var)
+{
+  var_ann_t v_ann = var_ann (var);
+  VEC(tree, gc) *aliases = v_ann->may_aliases;
+
+  /* Case 1: |aliases| == 1  */
+  if ((aliases != NULL)
+      && (VEC_length (tree, aliases) == 1))
+    {
+      tree ali = VEC_index (tree, aliases, 0);
+
+      if (TREE_CODE (ali) == SYMBOL_MEMORY_TAG)
+        return ali;
+    }
+
+  /* Case 2: |aliases| == 0  */
+  if (aliases == NULL)
+    add_may_alias (tag, var);
+  else
+    {
+      /* Case 3: |aliases| > 1  */
+      unsigned i;
+      tree al;
+
+      for (i = 0; VEC_iterate (tree, aliases, i, al); i++)
+        add_may_alias (tag, al);
+    }
+
+  return tag;
+}
 
 /* Create a new symbol tag for PTR.  Construct the may-alias list of this type
-   tag so that it has the aliasing of VAR. 
+   tag so that it has the aliasing of VAR, or of the relevant subvars of VAR
+   according to the location accessed by EXPR.
 
    Note, the set of aliases represented by the new symbol tag are not marked
    for renaming.  */
 
 void
-new_type_alias (tree ptr, tree var)
+new_type_alias (tree ptr, tree var, tree expr)
 {
   var_ann_t p_ann = var_ann (ptr);
   tree tag_type = TREE_TYPE (TREE_TYPE (ptr));
-  var_ann_t v_ann = var_ann (var);
   tree tag;
   subvar_t svars;
+  tree ali = NULL_TREE;
+  HOST_WIDE_INT offset, size, maxsize;
+  tree ref;
 
   gcc_assert (p_ann->symbol_mem_tag == NULL_TREE);
   gcc_assert (!MTAG_P (var));
 
+  ref = get_ref_base_and_extent (expr, &offset, &size, &maxsize);
+  gcc_assert (ref);
+
+  tag = create_memory_tag (tag_type, true);
+  p_ann->symbol_mem_tag = tag;
+
   /* Add VAR to the may-alias set of PTR's new symbol tag.  If VAR has
      subvars, add the subvars to the tag instead of the actual var.  */
   if (var_can_have_subvars (var)
       && (svars = get_subvars_for_var (var)))
     {
       subvar_t sv;
-
-      tag = create_memory_tag (tag_type, true);
-      p_ann->symbol_mem_tag = tag;
+      VEC (tree, heap) *overlaps = NULL;
+      unsigned int len;
 
       for (sv = svars; sv; sv = sv->next)
-        add_may_alias (tag, sv->var);
-    }
-  else
-    {
-      /* The following is based on code in add_stmt_operand to ensure that the
-        same defs/uses/vdefs/vuses will be found after replacing a reference
-        to var (or ARRAY_REF to var) with an INDIRECT_REF to ptr whose value
-        is the address of var.  */
-      VEC(tree, gc) *aliases = v_ann->may_aliases;
-
-      if ((aliases != NULL)
-         && (VEC_length (tree, aliases) == 1))
        {
-         tree ali = VEC_index (tree, aliases, 0);
+          bool exact;
 
-         if (TREE_CODE (ali) == SYMBOL_MEMORY_TAG)
+          if (overlap_subvar (offset, maxsize, sv->var, &exact))
+            VEC_safe_push (tree, heap, overlaps, sv->var);
+        }
+      len = VEC_length (tree, overlaps);
+      if (dump_file && (dump_flags & TDF_DETAILS))
+        fprintf (dump_file, "\nnumber of overlapping subvars = %u\n", len);
+      gcc_assert (len);
+
+      if (len == 1)
+        ali = add_may_alias_for_new_tag (tag, VEC_index (tree, overlaps, 0));
+      else if (len > 1)
+        {
+         unsigned int k;
+         tree sv_var;
+
+         for (k = 0; VEC_iterate (tree, overlaps, k, sv_var); k++)
            {
-             p_ann->symbol_mem_tag = ali;
-             return;
-           }
-       }
-
-      tag = create_memory_tag (tag_type, true);
-      p_ann->symbol_mem_tag = tag;
-
-      if (aliases == NULL)
-       add_may_alias (tag, var);
-      else
-       {
-         unsigned i;
-         tree al;
+             ali = add_may_alias_for_new_tag (tag, sv_var);
 
-         for (i = 0; VEC_iterate (tree, aliases, i, al); i++)
-           add_may_alias (tag, al);
+             if (ali != tag)
+               {
+                 /* Can happen only if 'Case 1' of add_may_alias_for_new_tag
+                    took place.  Since more than one svar was found, we add 
+                    'ali' as one of the may_aliases of the new tag.  */ 
+                 add_may_alias (tag, ali);
+                 ali = tag;
+               }
+           }
        }
-    }    
+    }
+  else
+    ali = add_may_alias_for_new_tag (tag, var);
 
+  p_ann->symbol_mem_tag = ali;
   TREE_READONLY (tag) = TREE_READONLY (var);
   MTAG_GLOBAL (tag) = is_global_var (var);
 }
 
-
-
 /* This represents the used range of a variable.  */
 
 typedef struct used_part
index 746e9067e4760076e2c1e954b99e8cee51c82703..5f1b2069cebf1d8647abd84da5c00f6dfb6fbae9 100644 (file)
@@ -303,7 +303,7 @@ vect_create_data_ref_ptr (tree stmt,
   /* If tag is a variable (and NOT_A_TAG) than a new symbol memory
      tag must be created with tag added to its may alias list.  */
   if (!MTAG_P (tag))
-    new_type_alias (vect_ptr, tag);
+    new_type_alias (vect_ptr, tag, DR_REF (dr));
   else
     var_ann (vect_ptr)->symbol_mem_tag = tag;