public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Simplify and fix restrict handling
@ 2011-10-14 13:57 Richard Guenther
  2011-10-17 14:45 ` Richard Guenther
  0 siblings, 1 reply; 3+ messages in thread
From: Richard Guenther @ 2011-10-14 13:57 UTC (permalink / raw)
  To: gcc-patches


This follows up Michas testcase where we fail to handle the
conservatively propagated restrict tags properly.  The following
patch simplifies handling of restrict in the oracle and thus
only excludes NONLOCAL (as designed), but not ESCAPED from
conflict checking.

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

Richard.

2011-10-14  Richard Guenther  <rguenther@suse.de>

	* tree-ssa-alias.h (pt_solutions_same_restrict_base): Remove.
	* tree-ssa-alias.c (ptr_derefs_may_alias_p): Remove call to
	pt_solutions_same_restrict_base.
	* tree-ssa-structalias.c (pt_solutions_same_restrict_base): Remove.
	(pt_solutions_intersect_1): Integrate restrict handling here.

Index: gcc/tree-ssa-alias.c
===================================================================
--- gcc/tree-ssa-alias.c	(revision 179966)
+++ gcc/tree-ssa-alias.c	(working copy)
@@ -316,11 +316,6 @@ ptr_derefs_may_alias_p (tree ptr1, tree
   if (!pi1 || !pi2)
     return true;
 
-  /* If both pointers are restrict-qualified try to disambiguate
-     with restrict information.  */
-  if (!pt_solutions_same_restrict_base (&pi1->pt, &pi2->pt))
-    return false;
-
   /* ???  This does not use TBAA to prune decls from the intersection
      that not both pointers may access.  */
   return pt_solutions_intersect (&pi1->pt, &pi2->pt);
Index: gcc/tree-ssa-alias.h
===================================================================
--- gcc/tree-ssa-alias.h	(revision 179966)
+++ gcc/tree-ssa-alias.h	(working copy)
@@ -130,8 +130,6 @@ extern bool pt_solution_singleton_p (str
 extern bool pt_solution_includes_global (struct pt_solution *);
 extern bool pt_solution_includes (struct pt_solution *, const_tree);
 extern bool pt_solutions_intersect (struct pt_solution *, struct pt_solution *);
-extern bool pt_solutions_same_restrict_base (struct pt_solution *,
-					     struct pt_solution *);
 extern void pt_solution_reset (struct pt_solution *);
 extern void pt_solution_set (struct pt_solution *, bitmap, bool, bool);
 extern void pt_solution_set_var (struct pt_solution *, tree);
Index: gcc/tree-ssa-structalias.c
===================================================================
--- gcc/tree-ssa-structalias.c	(revision 179966)
+++ gcc/tree-ssa-structalias.c	(working copy)
@@ -6079,12 +6079,15 @@ pt_solutions_intersect_1 (struct pt_solu
     return true;
 
   /* If either points to unknown global memory and the other points to
-     any global memory they alias.  */
-  if ((pt1->nonlocal
-       && (pt2->nonlocal
-	   || pt2->vars_contains_global))
-      || (pt2->nonlocal
-	  && pt1->vars_contains_global))
+     any global memory they alias.  If both points-to sets are based
+     off a restrict qualified pointer ignore any overlaps with NONLOCAL.  */
+  if (!(pt1->vars_contains_restrict
+	&& pt2->vars_contains_restrict)
+      && ((pt1->nonlocal
+	   && (pt2->nonlocal
+	       || pt2->vars_contains_global))
+	  || (pt2->nonlocal
+	      && pt1->vars_contains_global)))
     return true;
 
   /* Check the escaped solution if required.  */
@@ -6141,27 +6144,6 @@ pt_solutions_intersect (struct pt_soluti
   return res;
 }
 
-/* Return true if both points-to solutions PT1 and PT2 for two restrict
-   qualified pointers are possibly based on the same pointer.  */
-
-bool
-pt_solutions_same_restrict_base (struct pt_solution *pt1,
-				 struct pt_solution *pt2)
-{
-  /* If we deal with points-to solutions of two restrict qualified
-     pointers solely rely on the pointed-to variable bitmap intersection.
-     For two pointers that are based on each other the bitmaps will
-     intersect.  */
-  if (pt1->vars_contains_restrict
-      && pt2->vars_contains_restrict)
-    {
-      gcc_assert (pt1->vars && pt2->vars);
-      return bitmap_intersect_p (pt1->vars, pt2->vars);
-    }
-
-  return true;
-}
-
 
 /* Dump points-to information to OUTFILE.  */
 

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] Simplify and fix restrict handling
  2011-10-14 13:57 [PATCH] Simplify and fix restrict handling Richard Guenther
@ 2011-10-17 14:45 ` Richard Guenther
  2011-10-18  9:39   ` Richard Guenther
  0 siblings, 1 reply; 3+ messages in thread
From: Richard Guenther @ 2011-10-17 14:45 UTC (permalink / raw)
  To: gcc-patches

On Fri, 14 Oct 2011, Richard Guenther wrote:

> 
> This follows up Michas testcase where we fail to handle the
> conservatively propagated restrict tags properly.  The following
> patch simplifies handling of restrict in the oracle and thus
> only excludes NONLOCAL (as designed), but not ESCAPED from
> conflict checking.
> 
> Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

So, after some regressions caused by this patch and some more thinking
(about more possible issues) I concluded that we can simplify things
even more by not making restrict vars point to NONLOCAL, but only
to their tag (but marking that as global and able to have a points-to
set).  This way the special-casing of NONLOCAL vs. restrict can go
away, and with it all its possible problems.  Restrict is now
similar to malloc () memory that escapes.

Hopefully this one is without regressions ;)

Bootstrap and regtest running on x86_64-unknown-linux-gnu.

It seems we can remove DECL_IS_RESTRICTED_P again, as well as
the internal is_restrict_var flag.  I'll do that if the patch
tests ok (the is_restrict_var flag removal immediately, the
DECL_IS_RESTRICTED_P removal as followup as it touches Fortran).

Thanks,
Richard.

2011-10-17  Richard Guenther  <rguenther@suse.de>

	* tree-ssa-alias.h (struct pt_solution): Remove
	vars_contains_restrict member.
	(pt_solutions_same_restrict_base): Remove.
	(pt_solution_set): Adjust.
	* tree-ssa-alias.c (ptr_deref_may_alias_decl_p): Remove
	vars_contains_restrict handling.
	(dump_points_to_solution): Likewise.
	(ptr_derefs_may_alias_p): Do not call pt_solutions_same_restrict_base.
	* tree-ssa-structalias.c (make_constraint_from_restrict):
	Make the tag global.
	(create_variable_info_for): Do not make restrict vars point
	to NONLOCAL.
	(intra_create_variable_infos): Likewise.
	(find_what_var_points_to): Remove vars_contains_restrict handling.
	(pt_solution_set): Adjust.
	(pt_solution_ior_into): Likewise.
	(pt_solutions_same_restrict_base): Remove.
	* cfgexpand.c (update_alias_info_with_stack_vars): Adjust.
	* gimple-pretty-print.c (pp_points_to_solution): Likewise.

Index: gcc/tree-ssa-alias.c
===================================================================
--- gcc/tree-ssa-alias.c	(revision 180077)
+++ gcc/tree-ssa-alias.c	(working copy)
@@ -219,13 +219,6 @@ ptr_deref_may_alias_decl_p (tree ptr, tr
   if (!pi)
     return true;
 
-  /* If the decl can be used as a restrict tag and we have a restrict
-     pointer and that pointers points-to set doesn't contain this decl
-     then they can't alias.  */
-  if (DECL_RESTRICTED_P (decl)
-      && pi->pt.vars_contains_restrict)
-    return bitmap_bit_p (pi->pt.vars, DECL_PT_UID (decl));
-
   return pt_solution_includes (&pi->pt, decl);
 }
 
@@ -316,11 +309,6 @@ ptr_derefs_may_alias_p (tree ptr1, tree
   if (!pi1 || !pi2)
     return true;
 
-  /* If both pointers are restrict-qualified try to disambiguate
-     with restrict information.  */
-  if (!pt_solutions_same_restrict_base (&pi1->pt, &pi2->pt))
-    return false;
-
   /* ???  This does not use TBAA to prune decls from the intersection
      that not both pointers may access.  */
   return pt_solutions_intersect (&pi1->pt, &pi2->pt);
@@ -426,8 +414,6 @@ dump_points_to_solution (FILE *file, str
       dump_decl_set (file, pt->vars);
       if (pt->vars_contains_global)
 	fprintf (file, " (includes global vars)");
-      if (pt->vars_contains_restrict)
-	fprintf (file, " (includes restrict tags)");
     }
 }
 
Index: gcc/tree-ssa-alias.h
===================================================================
--- gcc/tree-ssa-alias.h	(revision 180077)
+++ gcc/tree-ssa-alias.h	(working copy)
@@ -54,8 +54,6 @@ struct GTY(()) pt_solution
   /* Nonzero if the pt_vars bitmap includes a global variable.  */
   unsigned int vars_contains_global : 1;
 
-  /* Nonzero if the pt_vars bitmap includes a restrict tag variable.  */
-  unsigned int vars_contains_restrict : 1;
 
   /* Set of variables that this pointer may point to.  */
   bitmap vars;
@@ -130,10 +128,8 @@ extern bool pt_solution_singleton_p (str
 extern bool pt_solution_includes_global (struct pt_solution *);
 extern bool pt_solution_includes (struct pt_solution *, const_tree);
 extern bool pt_solutions_intersect (struct pt_solution *, struct pt_solution *);
-extern bool pt_solutions_same_restrict_base (struct pt_solution *,
-					     struct pt_solution *);
 extern void pt_solution_reset (struct pt_solution *);
-extern void pt_solution_set (struct pt_solution *, bitmap, bool, bool);
+extern void pt_solution_set (struct pt_solution *, bitmap, bool);
 extern void pt_solution_set_var (struct pt_solution *, tree);
 
 extern void dump_pta_stats (FILE *);
Index: gcc/tree-ssa-structalias.c
===================================================================
--- gcc/tree-ssa-structalias.c	(revision 180077)
+++ gcc/tree-ssa-structalias.c	(working copy)
@@ -3661,12 +3661,11 @@ make_constraint_from_heapvar (varinfo_t
 static void
 make_constraint_from_restrict (varinfo_t lhs, const char *name)
 {
-  varinfo_t vi;
-  vi = make_constraint_from_heapvar (lhs, name);
+  varinfo_t vi = make_heapvar (name);
   vi->is_restrict_var = 1;
-  vi->is_global_var = 0;
-  vi->is_special_var = 1;
-  vi->may_have_pointers = 0;
+  vi->is_global_var = 1;
+  vi->may_have_pointers = 1;
+  make_constraint_from (lhs, vi->id);
 }
 
 /* In IPA mode there are varinfos for different aspects of reach
@@ -5504,13 +5503,18 @@ create_variable_info_for (tree decl, con
       if ((POINTER_TYPE_P (TREE_TYPE (decl))
 	   && TYPE_RESTRICT (TREE_TYPE (decl)))
 	  || vi->only_restrict_pointers)
-	make_constraint_from_restrict (vi, "GLOBAL_RESTRICT");
+	{
+	  make_constraint_from_restrict (vi, "GLOBAL_RESTRICT");
+	  continue;
+	}
 
       /* In non-IPA mode the initializer from nonlocal is all we need.  */
       if (!in_ipa_mode
 	  || DECL_HARD_REGISTER (decl))
 	make_copy_constraint (vi, nonlocal_id);
 
+      /* In IPA mode parse the initializer and generate proper constraints
+	 for it.  */
       else
 	{
 	  struct varpool_node *vnode = varpool_get_node (decl);
@@ -5595,7 +5599,7 @@ intra_create_variable_infos (void)
      passed-by-reference argument.  */
   for (t = DECL_ARGUMENTS (current_function_decl); t; t = DECL_CHAIN (t))
     {
-      varinfo_t p;
+      varinfo_t p = get_vi_for_tree (t);
 
       /* For restrict qualified pointers to objects passed by
          reference build a real representative for the pointed-to object.
@@ -5610,7 +5614,7 @@ intra_create_variable_infos (void)
 	  DECL_EXTERNAL (heapvar) = 1;
 	  vi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS");
 	  insert_vi_for_tree (heapvar, vi);
-	  lhsc.var = get_vi_for_tree (t)->id;
+	  lhsc.var = p->id;
 	  lhsc.type = SCALAR;
 	  lhsc.offset = 0;
 	  rhsc.var = vi->id;
@@ -5623,21 +5627,25 @@ intra_create_variable_infos (void)
 	      {
 		if (vi->only_restrict_pointers)
 		  make_constraint_from_restrict (vi, "GLOBAL_RESTRICT");
-		make_copy_constraint (vi, nonlocal_id);
+		else
+		  make_copy_constraint (vi, nonlocal_id);
 	      }
 	  continue;
 	}
 
-      for (p = get_vi_for_tree (t); p; p = p->next)
-	{
-	  if (p->may_have_pointers)
-	    make_constraint_from (p, nonlocal_id);
-	  if (p->only_restrict_pointers)
-	    make_constraint_from_restrict (p, "PARM_RESTRICT");
-	}
       if (POINTER_TYPE_P (TREE_TYPE (t))
 	  && TYPE_RESTRICT (TREE_TYPE (t)))
-	make_constraint_from_restrict (get_vi_for_tree (t), "PARM_RESTRICT");
+	make_constraint_from_restrict (p, "PARM_RESTRICT");
+      else
+	{
+	  for (; p; p = p->next)
+	    {
+	      if (p->only_restrict_pointers)
+		make_constraint_from_restrict (p, "PARM_RESTRICT");
+	      else if (p->may_have_pointers)
+		make_constraint_from (p, nonlocal_id);
+	    }
+	}
     }
 
   /* Add a constraint for a result decl that is passed by reference.  */
@@ -5813,15 +5821,11 @@ find_what_var_points_to (varinfo_t orig_
 		   || vi->id == integer_id)
 	    pt->anything = 1;
 	}
-      if (vi->is_restrict_var)
-	pt->vars_contains_restrict = true;
     }
 
   /* Instead of doing extra work, simply do not create
      elaborate points-to information for pt_anything pointers.  */
-  if (pt->anything
-      && (orig_vi->is_artificial_var
-	  || !pt->vars_contains_restrict))
+  if (pt->anything)
     return;
 
   /* Share the final set of variables when possible.  */
@@ -5912,13 +5916,11 @@ pt_solution_reset (struct pt_solution *p
    it contains restrict tag variables.  */
 
 void
-pt_solution_set (struct pt_solution *pt, bitmap vars,
-		 bool vars_contains_global, bool vars_contains_restrict)
+pt_solution_set (struct pt_solution *pt, bitmap vars, bool vars_contains_global)
 {
   memset (pt, 0, sizeof (struct pt_solution));
   pt->vars = vars;
   pt->vars_contains_global = vars_contains_global;
-  pt->vars_contains_restrict = vars_contains_restrict;
 }
 
 /* Set the points-to solution *PT to point only to the variable VAR.  */
@@ -5953,7 +5955,6 @@ pt_solution_ior_into (struct pt_solution
   dest->ipa_escaped |= src->ipa_escaped;
   dest->null |= src->null;
   dest->vars_contains_global |= src->vars_contains_global;
-  dest->vars_contains_restrict |= src->vars_contains_restrict;
   if (!src->vars)
     return;
 
@@ -6141,27 +6142,6 @@ pt_solutions_intersect (struct pt_soluti
   return res;
 }
 
-/* Return true if both points-to solutions PT1 and PT2 for two restrict
-   qualified pointers are possibly based on the same pointer.  */
-
-bool
-pt_solutions_same_restrict_base (struct pt_solution *pt1,
-				 struct pt_solution *pt2)
-{
-  /* If we deal with points-to solutions of two restrict qualified
-     pointers solely rely on the pointed-to variable bitmap intersection.
-     For two pointers that are based on each other the bitmaps will
-     intersect.  */
-  if (pt1->vars_contains_restrict
-      && pt2->vars_contains_restrict)
-    {
-      gcc_assert (pt1->vars && pt2->vars);
-      return bitmap_intersect_p (pt1->vars, pt2->vars);
-    }
-
-  return true;
-}
-
 
 /* Dump points-to information to OUTFILE.  */
 
Index: gcc/cfgexpand.c
===================================================================
--- gcc/cfgexpand.c	(revision 180077)
+++ gcc/cfgexpand.c	(working copy)
@@ -530,7 +530,7 @@ update_alias_info_with_stack_vars (void)
 
       /* Make the SSA name point to all partition members.  */
       pi = get_ptr_info (name);
-      pt_solution_set (&pi->pt, part, false, false);
+      pt_solution_set (&pi->pt, part, false);
     }
 
   /* Make all points-to sets that contain one member of a partition
Index: gcc/gimple-pretty-print.c
===================================================================
--- gcc/gimple-pretty-print.c	(revision 180077)
+++ gcc/gimple-pretty-print.c	(working copy)
@@ -610,8 +610,6 @@ pp_points_to_solution (pretty_printer *b
       pp_character (buffer, '}');
       if (pt->vars_contains_global)
 	pp_string (buffer, " (glob)");
-      if (pt->vars_contains_restrict)
-	pp_string (buffer, " (restr)");
     }
 }
 

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] Simplify and fix restrict handling
  2011-10-17 14:45 ` Richard Guenther
@ 2011-10-18  9:39   ` Richard Guenther
  0 siblings, 0 replies; 3+ messages in thread
From: Richard Guenther @ 2011-10-18  9:39 UTC (permalink / raw)
  To: gcc-patches

On Mon, 17 Oct 2011, Richard Guenther wrote:

> On Fri, 14 Oct 2011, Richard Guenther wrote:
> 
> > 
> > This follows up Michas testcase where we fail to handle the
> > conservatively propagated restrict tags properly.  The following
> > patch simplifies handling of restrict in the oracle and thus
> > only excludes NONLOCAL (as designed), but not ESCAPED from
> > conflict checking.
> > 
> > Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.
> 
> So, after some regressions caused by this patch and some more thinking
> (about more possible issues) I concluded that we can simplify things
> even more by not making restrict vars point to NONLOCAL, but only
> to their tag (but marking that as global and able to have a points-to
> set).  This way the special-casing of NONLOCAL vs. restrict can go
> away, and with it all its possible problems.  Restrict is now
> similar to malloc () memory that escapes.
> 
> Hopefully this one is without regressions ;)
> 
> Bootstrap and regtest running on x86_64-unknown-linux-gnu.

And this is what I ended up applying after fixing constraints
again.  For restrict qualified global (or parameter) pointers
we now generate

p = &RESTRICT_TAG
RESTRICT_TAG = NONLOCAL

if we implmenent the proposed RESTRICT_CAST expression from

p = RESTRICT_CAST <q, TAG>;

we'd need to generate

p = &TAG;
TAG = *q;

With this in place we can now disambiguate restrict qualified
pointers against global decls which wasn't possible before
(we invented the DECL_IS_RESTRICTED_P flag for this).

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2011-10-17  Richard Guenther  <rguenther@suse.de>

	* tree-ssa-alias.h (struct pt_solution): Remove
	vars_contains_restrict member.
	(pt_solutions_same_restrict_base): Remove.
	(pt_solution_set): Adjust.
	* tree-ssa-alias.c (ptr_deref_may_alias_decl_p): Remove
	vars_contains_restrict handling.
	(dump_points_to_solution): Likewise.
	(ptr_derefs_may_alias_p): Do not call pt_solutions_same_restrict_base.
	* tree-ssa-structalias.c (struct variable_info): Remove is_restrict_var
	field.
	(new_var_info): Do not initialize it.
	(ipa_escaped_pt): Adjust.
	(make_constraint_from_restrict): Make the tag global.
	(make_constraint_from_global_restrict): New function.
	(make_constraint_from_heapvar): Remove.
	(create_variable_info_for): Do not make restrict vars point
	to NONLOCAL.
	(intra_create_variable_infos): Likewise.
	(find_what_var_points_to): Remove vars_contains_restrict handling.
	(pt_solution_set): Adjust.
	(pt_solution_ior_into): Likewise.
	(pt_solutions_same_restrict_base): Remove.
	(compute_points_to_sets): Do not test is_restrict_var.
	* cfgexpand.c (update_alias_info_with_stack_vars): Adjust.
	* gimple-pretty-print.c (pp_points_to_solution): Likewise.

	* gcc.dg/torture/restrict-1.c: New testcase.

Index: gcc/tree-ssa-alias.c
===================================================================
*** gcc/tree-ssa-alias.c.orig	2011-10-17 16:56:54.000000000 +0200
--- gcc/tree-ssa-alias.c	2011-10-17 16:57:21.000000000 +0200
*************** ptr_deref_may_alias_decl_p (tree ptr, tr
*** 219,231 ****
    if (!pi)
      return true;
  
-   /* If the decl can be used as a restrict tag and we have a restrict
-      pointer and that pointers points-to set doesn't contain this decl
-      then they can't alias.  */
-   if (DECL_RESTRICTED_P (decl)
-       && pi->pt.vars_contains_restrict)
-     return bitmap_bit_p (pi->pt.vars, DECL_PT_UID (decl));
- 
    return pt_solution_includes (&pi->pt, decl);
  }
  
--- 219,224 ----
*************** ptr_derefs_may_alias_p (tree ptr1, tree
*** 316,326 ****
    if (!pi1 || !pi2)
      return true;
  
-   /* If both pointers are restrict-qualified try to disambiguate
-      with restrict information.  */
-   if (!pt_solutions_same_restrict_base (&pi1->pt, &pi2->pt))
-     return false;
- 
    /* ???  This does not use TBAA to prune decls from the intersection
       that not both pointers may access.  */
    return pt_solutions_intersect (&pi1->pt, &pi2->pt);
--- 309,314 ----
*************** dump_points_to_solution (FILE *file, str
*** 426,433 ****
        dump_decl_set (file, pt->vars);
        if (pt->vars_contains_global)
  	fprintf (file, " (includes global vars)");
-       if (pt->vars_contains_restrict)
- 	fprintf (file, " (includes restrict tags)");
      }
  }
  
--- 414,419 ----
Index: gcc/tree-ssa-alias.h
===================================================================
*** gcc/tree-ssa-alias.h.orig	2011-10-17 16:56:54.000000000 +0200
--- gcc/tree-ssa-alias.h	2011-10-17 16:57:21.000000000 +0200
*************** struct GTY(()) pt_solution
*** 54,61 ****
    /* Nonzero if the pt_vars bitmap includes a global variable.  */
    unsigned int vars_contains_global : 1;
  
-   /* Nonzero if the pt_vars bitmap includes a restrict tag variable.  */
-   unsigned int vars_contains_restrict : 1;
  
    /* Set of variables that this pointer may point to.  */
    bitmap vars;
--- 54,59 ----
*************** extern bool pt_solution_singleton_p (str
*** 130,139 ****
  extern bool pt_solution_includes_global (struct pt_solution *);
  extern bool pt_solution_includes (struct pt_solution *, const_tree);
  extern bool pt_solutions_intersect (struct pt_solution *, struct pt_solution *);
- extern bool pt_solutions_same_restrict_base (struct pt_solution *,
- 					     struct pt_solution *);
  extern void pt_solution_reset (struct pt_solution *);
! extern void pt_solution_set (struct pt_solution *, bitmap, bool, bool);
  extern void pt_solution_set_var (struct pt_solution *, tree);
  
  extern void dump_pta_stats (FILE *);
--- 128,135 ----
  extern bool pt_solution_includes_global (struct pt_solution *);
  extern bool pt_solution_includes (struct pt_solution *, const_tree);
  extern bool pt_solutions_intersect (struct pt_solution *, struct pt_solution *);
  extern void pt_solution_reset (struct pt_solution *);
! extern void pt_solution_set (struct pt_solution *, bitmap, bool);
  extern void pt_solution_set_var (struct pt_solution *, tree);
  
  extern void dump_pta_stats (FILE *);
Index: gcc/tree-ssa-structalias.c
===================================================================
*** gcc/tree-ssa-structalias.c.orig	2011-10-17 16:56:54.000000000 +0200
--- gcc/tree-ssa-structalias.c	2011-10-17 17:08:28.000000000 +0200
*************** struct variable_info
*** 261,269 ****
    /* True if this is a heap variable.  */
    unsigned int is_heap_var : 1;
  
-   /* True if this is a variable tracking a restrict pointer source.  */
-   unsigned int is_restrict_var : 1;
- 
    /* True if this field may contain pointers.  */
    unsigned int may_have_pointers : 1;
  
--- 261,266 ----
*************** new_var_info (tree t, const char *name)
*** 350,356 ****
    ret->is_unknown_size_var = false;
    ret->is_full_var = (t == NULL_TREE);
    ret->is_heap_var = false;
-   ret->is_restrict_var = false;
    ret->may_have_pointers = true;
    ret->only_restrict_pointers = false;
    ret->is_global_var = (t == NULL_TREE);
--- 347,352 ----
*************** make_heapvar (const char *name)
*** 3643,3672 ****
  }
  
  /* Create a new artificial heap variable with NAME and make a
!    constraint from it to LHS.  Return the created variable.  */
  
  static varinfo_t
! make_constraint_from_heapvar (varinfo_t lhs, const char *name)
  {
    varinfo_t vi = make_heapvar (name);
    make_constraint_from (lhs, vi->id);
- 
    return vi;
  }
  
  /* Create a new artificial heap variable with NAME and make a
     constraint from it to LHS.  Set flags according to a tag used
!    for tracking restrict pointers.  */
  
! static void
! make_constraint_from_restrict (varinfo_t lhs, const char *name)
  {
!   varinfo_t vi;
!   vi = make_constraint_from_heapvar (lhs, name);
!   vi->is_restrict_var = 1;
!   vi->is_global_var = 0;
!   vi->is_special_var = 1;
!   vi->may_have_pointers = 0;
  }
  
  /* In IPA mode there are varinfos for different aspects of reach
--- 3639,3668 ----
  }
  
  /* Create a new artificial heap variable with NAME and make a
!    constraint from it to LHS.  Set flags according to a tag used
!    for tracking restrict pointers.  */
  
  static varinfo_t
! make_constraint_from_restrict (varinfo_t lhs, const char *name)
  {
    varinfo_t vi = make_heapvar (name);
+   vi->is_global_var = 1;
+   vi->may_have_pointers = 1;
    make_constraint_from (lhs, vi->id);
    return vi;
  }
  
  /* Create a new artificial heap variable with NAME and make a
     constraint from it to LHS.  Set flags according to a tag used
!    for tracking restrict pointers and make the artificial heap
!    point to global memory.  */
  
! static varinfo_t
! make_constraint_from_global_restrict (varinfo_t lhs, const char *name)
  {
!   varinfo_t vi = make_constraint_from_restrict (lhs, name);
!   make_copy_constraint (vi, nonlocal_id);
!   return vi;
  }
  
  /* In IPA mode there are varinfos for different aspects of reach
*************** create_variable_info_for (tree decl, con
*** 5504,5516 ****
        if ((POINTER_TYPE_P (TREE_TYPE (decl))
  	   && TYPE_RESTRICT (TREE_TYPE (decl)))
  	  || vi->only_restrict_pointers)
! 	make_constraint_from_restrict (vi, "GLOBAL_RESTRICT");
  
        /* In non-IPA mode the initializer from nonlocal is all we need.  */
        if (!in_ipa_mode
  	  || DECL_HARD_REGISTER (decl))
  	make_copy_constraint (vi, nonlocal_id);
  
        else
  	{
  	  struct varpool_node *vnode = varpool_get_node (decl);
--- 5500,5517 ----
        if ((POINTER_TYPE_P (TREE_TYPE (decl))
  	   && TYPE_RESTRICT (TREE_TYPE (decl)))
  	  || vi->only_restrict_pointers)
! 	{
! 	  make_constraint_from_global_restrict (vi, "GLOBAL_RESTRICT");
! 	  continue;
! 	}
  
        /* In non-IPA mode the initializer from nonlocal is all we need.  */
        if (!in_ipa_mode
  	  || DECL_HARD_REGISTER (decl))
  	make_copy_constraint (vi, nonlocal_id);
  
+       /* In IPA mode parse the initializer and generate proper constraints
+ 	 for it.  */
        else
  	{
  	  struct varpool_node *vnode = varpool_get_node (decl);
*************** intra_create_variable_infos (void)
*** 5595,5601 ****
       passed-by-reference argument.  */
    for (t = DECL_ARGUMENTS (current_function_decl); t; t = DECL_CHAIN (t))
      {
!       varinfo_t p;
  
        /* For restrict qualified pointers to objects passed by
           reference build a real representative for the pointed-to object.
--- 5596,5602 ----
       passed-by-reference argument.  */
    for (t = DECL_ARGUMENTS (current_function_decl); t; t = DECL_CHAIN (t))
      {
!       varinfo_t p = get_vi_for_tree (t);
  
        /* For restrict qualified pointers to objects passed by
           reference build a real representative for the pointed-to object.
*************** intra_create_variable_infos (void)
*** 5610,5643 ****
  	  DECL_EXTERNAL (heapvar) = 1;
  	  vi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS");
  	  insert_vi_for_tree (heapvar, vi);
! 	  lhsc.var = get_vi_for_tree (t)->id;
  	  lhsc.type = SCALAR;
  	  lhsc.offset = 0;
  	  rhsc.var = vi->id;
  	  rhsc.type = ADDRESSOF;
  	  rhsc.offset = 0;
  	  process_constraint (new_constraint (lhsc, rhsc));
- 	  vi->is_restrict_var = 1;
  	  for (; vi; vi = vi->next)
  	    if (vi->may_have_pointers)
  	      {
  		if (vi->only_restrict_pointers)
! 		  make_constraint_from_restrict (vi, "GLOBAL_RESTRICT");
! 		make_copy_constraint (vi, nonlocal_id);
  	      }
  	  continue;
  	}
  
-       for (p = get_vi_for_tree (t); p; p = p->next)
- 	{
- 	  if (p->may_have_pointers)
- 	    make_constraint_from (p, nonlocal_id);
- 	  if (p->only_restrict_pointers)
- 	    make_constraint_from_restrict (p, "PARM_RESTRICT");
- 	}
        if (POINTER_TYPE_P (TREE_TYPE (t))
  	  && TYPE_RESTRICT (TREE_TYPE (t)))
! 	make_constraint_from_restrict (get_vi_for_tree (t), "PARM_RESTRICT");
      }
  
    /* Add a constraint for a result decl that is passed by reference.  */
--- 5611,5647 ----
  	  DECL_EXTERNAL (heapvar) = 1;
  	  vi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS");
  	  insert_vi_for_tree (heapvar, vi);
! 	  lhsc.var = p->id;
  	  lhsc.type = SCALAR;
  	  lhsc.offset = 0;
  	  rhsc.var = vi->id;
  	  rhsc.type = ADDRESSOF;
  	  rhsc.offset = 0;
  	  process_constraint (new_constraint (lhsc, rhsc));
  	  for (; vi; vi = vi->next)
  	    if (vi->may_have_pointers)
  	      {
  		if (vi->only_restrict_pointers)
! 		  make_constraint_from_global_restrict (vi, "GLOBAL_RESTRICT");
! 		else
! 		  make_copy_constraint (vi, nonlocal_id);
  	      }
  	  continue;
  	}
  
        if (POINTER_TYPE_P (TREE_TYPE (t))
  	  && TYPE_RESTRICT (TREE_TYPE (t)))
! 	make_constraint_from_global_restrict (p, "PARM_RESTRICT");
!       else
! 	{
! 	  for (; p; p = p->next)
! 	    {
! 	      if (p->only_restrict_pointers)
! 		make_constraint_from_global_restrict (p, "PARM_RESTRICT");
! 	      else if (p->may_have_pointers)
! 		make_constraint_from (p, nonlocal_id);
! 	    }
! 	}
      }
  
    /* Add a constraint for a result decl that is passed by reference.  */
*************** find_what_var_points_to (varinfo_t orig_
*** 5813,5827 ****
  		   || vi->id == integer_id)
  	    pt->anything = 1;
  	}
-       if (vi->is_restrict_var)
- 	pt->vars_contains_restrict = true;
      }
  
    /* Instead of doing extra work, simply do not create
       elaborate points-to information for pt_anything pointers.  */
!   if (pt->anything
!       && (orig_vi->is_artificial_var
! 	  || !pt->vars_contains_restrict))
      return;
  
    /* Share the final set of variables when possible.  */
--- 5817,5827 ----
  		   || vi->id == integer_id)
  	    pt->anything = 1;
  	}
      }
  
    /* Instead of doing extra work, simply do not create
       elaborate points-to information for pt_anything pointers.  */
!   if (pt->anything)
      return;
  
    /* Share the final set of variables when possible.  */
*************** pt_solution_reset (struct pt_solution *p
*** 5912,5924 ****
     it contains restrict tag variables.  */
  
  void
! pt_solution_set (struct pt_solution *pt, bitmap vars,
! 		 bool vars_contains_global, bool vars_contains_restrict)
  {
    memset (pt, 0, sizeof (struct pt_solution));
    pt->vars = vars;
    pt->vars_contains_global = vars_contains_global;
-   pt->vars_contains_restrict = vars_contains_restrict;
  }
  
  /* Set the points-to solution *PT to point only to the variable VAR.  */
--- 5912,5922 ----
     it contains restrict tag variables.  */
  
  void
! pt_solution_set (struct pt_solution *pt, bitmap vars, bool vars_contains_global)
  {
    memset (pt, 0, sizeof (struct pt_solution));
    pt->vars = vars;
    pt->vars_contains_global = vars_contains_global;
  }
  
  /* Set the points-to solution *PT to point only to the variable VAR.  */
*************** pt_solution_ior_into (struct pt_solution
*** 5953,5959 ****
    dest->ipa_escaped |= src->ipa_escaped;
    dest->null |= src->null;
    dest->vars_contains_global |= src->vars_contains_global;
-   dest->vars_contains_restrict |= src->vars_contains_restrict;
    if (!src->vars)
      return;
  
--- 5951,5956 ----
*************** pt_solutions_intersect (struct pt_soluti
*** 6141,6167 ****
    return res;
  }
  
- /* Return true if both points-to solutions PT1 and PT2 for two restrict
-    qualified pointers are possibly based on the same pointer.  */
- 
- bool
- pt_solutions_same_restrict_base (struct pt_solution *pt1,
- 				 struct pt_solution *pt2)
- {
-   /* If we deal with points-to solutions of two restrict qualified
-      pointers solely rely on the pointed-to variable bitmap intersection.
-      For two pointers that are based on each other the bitmaps will
-      intersect.  */
-   if (pt1->vars_contains_restrict
-       && pt2->vars_contains_restrict)
-     {
-       gcc_assert (pt1->vars && pt2->vars);
-       return bitmap_intersect_p (pt1->vars, pt2->vars);
-     }
- 
-   return true;
- }
- 
  
  /* Dump points-to information to OUTFILE.  */
  
--- 6138,6143 ----
*************** compute_points_to_sets (void)
*** 6574,6580 ****
    /* Mark escaped HEAP variables as global.  */
    FOR_EACH_VEC_ELT (varinfo_t, varmap, i, vi)
      if (vi->is_heap_var
- 	&& !vi->is_restrict_var
  	&& !vi->is_global_var)
        DECL_EXTERNAL (vi->decl) = vi->is_global_var
  	= pt_solution_includes (&cfun->gimple_df->escaped, vi->decl);
--- 6550,6555 ----
*************** gate_ipa_pta (void)
*** 6794,6800 ****
  
  /* IPA PTA solutions for ESCAPED.  */
  struct pt_solution ipa_escaped_pt
!   = { true, false, false, false, false, false, false, NULL };
  
  /* Associate node with varinfo DATA. Worker for
     cgraph_for_node_and_aliases.  */
--- 6769,6775 ----
  
  /* IPA PTA solutions for ESCAPED.  */
  struct pt_solution ipa_escaped_pt
!   = { true, false, false, false, false, false, NULL };
  
  /* Associate node with varinfo DATA. Worker for
     cgraph_for_node_and_aliases.  */
Index: gcc/cfgexpand.c
===================================================================
*** gcc/cfgexpand.c.orig	2011-10-17 16:56:54.000000000 +0200
--- gcc/cfgexpand.c	2011-10-17 16:57:21.000000000 +0200
*************** update_alias_info_with_stack_vars (void)
*** 530,536 ****
  
        /* Make the SSA name point to all partition members.  */
        pi = get_ptr_info (name);
!       pt_solution_set (&pi->pt, part, false, false);
      }
  
    /* Make all points-to sets that contain one member of a partition
--- 530,536 ----
  
        /* Make the SSA name point to all partition members.  */
        pi = get_ptr_info (name);
!       pt_solution_set (&pi->pt, part, false);
      }
  
    /* Make all points-to sets that contain one member of a partition
Index: gcc/gimple-pretty-print.c
===================================================================
*** gcc/gimple-pretty-print.c.orig	2011-10-17 16:56:54.000000000 +0200
--- gcc/gimple-pretty-print.c	2011-10-17 16:57:21.000000000 +0200
*************** pp_points_to_solution (pretty_printer *b
*** 610,617 ****
        pp_character (buffer, '}');
        if (pt->vars_contains_global)
  	pp_string (buffer, " (glob)");
-       if (pt->vars_contains_restrict)
- 	pp_string (buffer, " (restr)");
      }
  }
  
--- 610,615 ----
Index: gcc/testsuite/gcc.dg/torture/restrict-1.c
===================================================================
*** /dev/null	1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/gcc.dg/torture/restrict-1.c	2011-10-17 17:07:17.000000000 +0200
***************
*** 0 ****
--- 1,16 ----
+ /* { dg-do run } */
+ 
+ extern void abort (void);
+ void __attribute__((noinline,noclone))
+ foo (int ** __restrict__ p, int ** __restrict__ q)
+ {
+   **p = **q;
+ }
+ int main()
+ {
+   int x = 0, y = 1, *i = &x, *j = &y;
+   foo (&i, &j);
+   if (x != 1)
+     abort ();
+   return 0;
+ }

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2011-10-18  9:03 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-10-14 13:57 [PATCH] Simplify and fix restrict handling Richard Guenther
2011-10-17 14:45 ` Richard Guenther
2011-10-18  9:39   ` Richard Guenther

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).