Richard Guenther wrote:

>> I fully concede that my trick isn't a general solution to making full
>> use of restrict.  But, given that I think it'll take about 20-50 lines
>> of code, and that it will get a lot of the common cases, I think it's
>> worth it.  Do you agree?
> 
> Yes, I agree.  I just was curious on the status of Dannys work and if it
> would obsolete what you propose.

OK, great.  Here's a draft patch for the trick; this works on the test
case I had, and I'll be testing it now.  If it passes testing, and I add
testcases, does this look OK to you?

Thanks,

-- 
Mark Mitchell
CodeSourcery
[EMAIL PROTECTED]
(650) 331-3385 x713
2007-09-01  Mark Mitchell  <[EMAIL PROTECTED]>

        * function.h (struct function): Add argument_noalias.
        * alias.h (argument_noalias): Declare it.
        * alias.c (argument_noalias): New function.
        (base_alias_check): Use it.
        * tree-ssa-structalias.c (intra_create_variable_infos): Use
        argument_noalias.

Index: function.h
===================================================================
--- function.h  (revision 127950)
+++ function.h  (working copy)
@@ -473,6 +473,12 @@ struct function GTY(())
      function has been gimplified, so we can make sure we're not
      creating non GIMPLE tuples after gimplification.  */
   unsigned gimplified : 1;
+  
+  /* 0 if we have not yet determined whether arguments to this
+     function might alias each other.  1 if we have determined they
+     may alias each other.  2 if we have determined they cannot alias
+     each other.  */
+  unsigned argument_noalias : 2;
 };
 
 /* If va_list_[gf]pr_size is set to this, it means we don't know how
Index: alias.c
===================================================================
--- alias.c     (revision 127950)
+++ alias.c     (working copy)
@@ -1452,6 +1452,56 @@ find_base_term (rtx x)
     }
 }
 
+/* Returns an integer indicating to what extent arguments to the
+   current function may alias one-another or global variables.  In
+   particular, the return value is:
+
+   0 if pointer arguments may alias each other.
+   1 if pointer arguments may not alias each other but may alias
+     global variables.
+   2 if pointer arguments may not alias each other and may not
+     alias global variables.
+   3 if pointer arguments may not alias anything.
+
+   Unlike FLAG_ARGUMENT_NOALIAS, the value returned may differ
+   depending on the function presently being processed.  */
+
+int
+argument_noalias (void)
+{
+  tree t;
+
+  /* If FLAG_ARGUMENT_NOALIAS tells us that arguments cannot alias, we
+     do not have to try to prove that ourselves.  And, if we're
+     outside of a function, there's nothing we can prove.  */
+  if (flag_argument_noalias || !cfun)
+    return flag_argument_noalias;
+
+  /* If we have not already determined whether this function's
+     arguments can alias each other, figure that out now.  */
+  if (!cfun->argument_noalias)
+    {
+      /* If all the arguments to the current function are pointers with
+        the "restrict" qualifier, then none of them can point to one
+        another.  Assume that's the case.  */
+      cfun->argument_noalias = 2;
+      for (t = DECL_ARGUMENTS (current_function_decl); t; t = TREE_CHAIN (t))
+       {
+         tree type = TREE_TYPE (t);
+         /* If we find a pointer argument that does not have the
+            "restrict" qualifier, then some of the arguments to this
+            function might alias other arguments.  */
+         if (POINTER_TYPE_P (type) && !TYPE_RESTRICT (type))
+           {
+             cfun->argument_noalias = 1;
+             break;
+           }
+       }
+    }
+
+  return cfun->argument_noalias - 1;
+}
+
 /* Return 0 if the addresses X and Y are known to point to different
    objects, 1 if they might be pointers to the same object.  */
 
@@ -1461,6 +1511,7 @@ base_alias_check (rtx x, rtx y, enum mac
 {
   rtx x_base = find_base_term (x);
   rtx y_base = find_base_term (y);
+  int noalias;
 
   /* If the address itself has no known base see if a known equivalent
      value has one.  If either address still has no known base, nothing
@@ -1521,10 +1572,11 @@ base_alias_check (rtx x, rtx y, enum mac
       || (GET_CODE (y_base) == ADDRESS && GET_MODE (y_base) == Pmode))
     return 0;
 
-  if (! flag_argument_noalias)
+  noalias = argument_noalias ();
+  if (! noalias)
     return 1;
 
-  if (flag_argument_noalias > 1)
+  if (noalias > 1)
     return 0;
 
   /* Weak noalias assertion (arguments are distinct, but may match globals).  
*/
Index: alias.h
===================================================================
--- alias.h     (revision 127950)
+++ alias.h     (working copy)
@@ -28,6 +28,7 @@ extern alias_set_type get_varargs_alias_
 extern alias_set_type get_frame_alias_set (void);
 extern bool component_uses_parent_alias_set (const_tree);
 extern bool alias_set_subset_of (alias_set_type, alias_set_type);
+extern int argument_noalias (void);
 
 /* This alias set can be used to force a memory to conflict with all
    other memories, creating a barrier across which no memory reference
Index: tree-ssa-structalias.c
===================================================================
--- tree-ssa-structalias.c      (revision 127950)
+++ tree-ssa-structalias.c      (working copy)
@@ -4544,7 +4544,12 @@ intra_create_variable_infos (void)
 {
   tree t;
   struct constraint_expr lhs, rhs;
+  bool noalias;
 
+  noalias = argument_noalias ();
+
+  /* For each incoming pointer argument arg, ARG = ESCAPED_VARS or a
+     dummy variable if flag_argument_noalias > 2. */
   /* For each incoming pointer argument arg, create the constraint ARG
      = ANYTHING or a dummy variable if flag_argument_noalias is set.  */
   for (t = DECL_ARGUMENTS (current_function_decl); t; t = TREE_CHAIN (t))
@@ -4554,11 +4559,10 @@ intra_create_variable_infos (void)
       if (!could_have_pointers (t))
        continue;
 
-      /* If flag_argument_noalias is set, then function pointer
-        arguments are guaranteed not to point to each other.  In that
-        case, create an artificial variable PARM_NOALIAS and the
-        constraint ARG = &PARM_NOALIAS.  */
-      if (POINTER_TYPE_P (TREE_TYPE (t)) && flag_argument_noalias > 0)
+      /* If the arguments are guaranteed not to point to each other,
+        create an artificial variable PARM_NOALIAS and the constraint
+        ARG = &PARM_NOALIAS.  */
+      if (POINTER_TYPE_P (TREE_TYPE (t)) && noalias)
        {
          varinfo_t vi;
          tree heapvar = heapvar_lookup (t);
@@ -4579,7 +4583,7 @@ intra_create_variable_infos (void)
              heapvar_insert (t, heapvar);
 
              ann = get_var_ann (heapvar);
-             if (flag_argument_noalias == 1)
+             if (flag_argument_noalias <= 1)
                ann->noalias_state = NO_ALIAS;
              else if (flag_argument_noalias == 2)
                ann->noalias_state = NO_ALIAS_GLOBAL;

Reply via email to