On 03/11/15 14:58, Tom de Vries wrote:
This patch adds handling of all the restrict qualifiers in the type of a
function parameter.

And committed to gomp-4_0-branch.

I've reverted this patch, and backported the version from trunk.

Committed as attached.

Thanks,
- Tom
[PATCH 1/2] Revert "Handle recursive restrict in function parameter"

2015-11-04  Tom de Vries  <t...@codesourcery.com>

	revert:
	2015-10-03  Tom de Vries  <t...@codesourcery.com>

	* tree-ssa-structalias.c (struct fieldoff): Add restrict_var field.
	(push_fields_onto_fieldstack): Add and handle handle_param parameter.
	(create_variable_info_for_1): Add and handle
	handle_param parameter.  Add extra arg to call to
	push_fields_onto_fieldstack.  Handle restrict pointer fields.
	(create_variable_info_for): Call create_variable_info_for_1 with extra
	arg.
	(make_param_constraints): Drop restrict_name parameter.  Ignore
	vi->only_restrict_pointers.
	(intra_create_variable_infos): Call create_variable_info_for_1 with
	extra arg.  Remove restrict handling.  Call make_param_constraints with
	one less arg.

	* gcc.dg/tree-ssa/restrict-7.c: New test.
	* gcc.dg/tree-ssa/restrict-8.c: New test.
---
 gcc/testsuite/gcc.dg/tree-ssa/restrict-7.c | 12 ----
 gcc/testsuite/gcc.dg/tree-ssa/restrict-8.c | 17 ------
 gcc/tree-ssa-structalias.c                 | 90 ++++++++++++------------------
 3 files changed, 36 insertions(+), 83 deletions(-)
 delete mode 100644 gcc/testsuite/gcc.dg/tree-ssa/restrict-7.c
 delete mode 100644 gcc/testsuite/gcc.dg/tree-ssa/restrict-8.c

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/restrict-7.c b/gcc/testsuite/gcc.dg/tree-ssa/restrict-7.c
deleted file mode 100644
index f7a68c7..0000000
--- a/gcc/testsuite/gcc.dg/tree-ssa/restrict-7.c
+++ /dev/null
@@ -1,12 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-fre1" } */
-
-int
-f (int *__restrict__ *__restrict__ *__restrict__ a, int *b)
-{
-  *b = 1;
-  ***a  = 2;
-  return *b;
-}
-
-/* { dg-final { scan-tree-dump-times "return 1" 1 "fre1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/restrict-8.c b/gcc/testsuite/gcc.dg/tree-ssa/restrict-8.c
deleted file mode 100644
index b0ab164..0000000
--- a/gcc/testsuite/gcc.dg/tree-ssa/restrict-8.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-fre1" } */
-
-struct s
-{
-  int *__restrict__ *__restrict__ pp;
-};
-
-int
-f (struct s s, int *b)
-{
-  *b = 1;
-  **s.pp = 2;
-  return *b;
-}
-
-/* { dg-final { scan-tree-dump-times "return 1" 1 "fre1" } } */
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index 074285c..f4c875f 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -320,7 +320,6 @@ static varinfo_t first_or_preceding_vi_for_offset (varinfo_t,
 						   unsigned HOST_WIDE_INT);
 static varinfo_t lookup_vi_for_tree (tree);
 static inline bool type_can_have_subvars (const_tree);
-static void make_param_constraints (varinfo_t);
 
 /* Pool of variable info structures.  */
 static object_allocator<variable_info> variable_info_pool
@@ -407,7 +406,6 @@ new_var_info (tree t, const char *name, bool add_id)
   return ret;
 }
 
-static varinfo_t create_variable_info_for_1 (tree, const char *, bool, bool);
 
 /* A map mapping call statements to per-stmt variables for uses
    and clobbers specific to the call.  */
@@ -5210,8 +5208,6 @@ struct fieldoff
   unsigned may_have_pointers : 1;
 
   unsigned only_restrict_pointers : 1;
-
-  varinfo_t restrict_var;
 };
 typedef struct fieldoff fieldoff_s;
 
@@ -5306,12 +5302,11 @@ field_must_have_pointers (tree t)
    OFFSET is used to keep track of the offset in this entire
    structure, rather than just the immediately containing structure.
    Returns false if the caller is supposed to handle the field we
-   recursed for.  If HANDLE_PARAM is set, we're handling part of a function
-   parameter.  */
+   recursed for.  */
 
 static bool
 push_fields_onto_fieldstack (tree type, vec<fieldoff_s> *fieldstack,
-			     HOST_WIDE_INT offset, bool handle_param)
+			     HOST_WIDE_INT offset)
 {
   tree field;
   bool empty_p = true;
@@ -5337,7 +5332,7 @@ push_fields_onto_fieldstack (tree type, vec<fieldoff_s> *fieldstack,
 	    || TREE_CODE (field_type) == UNION_TYPE)
 	  push = true;
 	else if (!push_fields_onto_fieldstack
-		    (field_type, fieldstack, offset + foff, handle_param)
+		    (field_type, fieldstack, offset + foff)
 		 && (DECL_SIZE (field)
 		     && !integer_zerop (DECL_SIZE (field))))
 	  /* Empty structures may have actual size, like in C++.  So
@@ -5358,8 +5353,7 @@ push_fields_onto_fieldstack (tree type, vec<fieldoff_s> *fieldstack,
 	    if (!pair
 		&& offset + foff != 0)
 	      {
-		fieldoff_s e = {0, offset + foff, false, false, false, false,
-				NULL};
+		fieldoff_s e = {0, offset + foff, false, false, false, false};
 		pair = fieldstack->safe_push (e);
 	      }
 
@@ -5393,19 +5387,6 @@ push_fields_onto_fieldstack (tree type, vec<fieldoff_s> *fieldstack,
 		  = (!has_unknown_size
 		     && POINTER_TYPE_P (field_type)
 		     && TYPE_RESTRICT (field_type));
-		if (handle_param
-		    && e.only_restrict_pointers
-		    && !type_contains_placeholder_p (TREE_TYPE (field_type)))
-		  {
-		    varinfo_t rvi;
-		    tree heapvar = build_fake_var_decl (TREE_TYPE (field_type));
-		    DECL_EXTERNAL (heapvar) = 1;
-		    rvi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS",
-						      true, true);
-		    rvi->is_restrict_var = 1;
-		    insert_vi_for_tree (heapvar, rvi);
-		    e.restrict_var = rvi;
-		  }
 		fieldstack->safe_push (e);
 	      }
 	  }
@@ -5674,11 +5655,10 @@ check_for_overlaps (vec<fieldoff_s> fieldstack)
 
 /* Create a varinfo structure for NAME and DECL, and add it to VARMAP.
    This will also create any varinfo structures necessary for fields
-   of DECL.  DECL is a function parameter if HANDLE_PARAM is set.  */
+   of DECL.  */
 
 static varinfo_t
-create_variable_info_for_1 (tree decl, const char *name, bool add_id,
-			    bool handle_param)
+create_variable_info_for_1 (tree decl, const char *name, bool add_id)
 {
   varinfo_t vi, newvi;
   tree decl_type = TREE_TYPE (decl);
@@ -5712,7 +5692,7 @@ create_variable_info_for_1 (tree decl, const char *name, bool add_id,
       bool notokay = false;
       unsigned int i;
 
-      push_fields_onto_fieldstack (decl_type, &fieldstack, 0, handle_param);
+      push_fields_onto_fieldstack (decl_type, &fieldstack, 0);
 
       for (i = 0; !notokay && fieldstack.iterate (i, &fo); i++)
 	if (fo->has_unknown_size
@@ -5754,19 +5734,6 @@ create_variable_info_for_1 (tree decl, const char *name, bool add_id,
       if (POINTER_TYPE_P (TREE_TYPE (decl))
 	  && TYPE_RESTRICT (TREE_TYPE (decl)))
 	vi->only_restrict_pointers = 1;
-      if (vi->only_restrict_pointers
-	  && !type_contains_placeholder_p (TREE_TYPE (TREE_TYPE (decl)))
-	  && handle_param)
-	{
-	  varinfo_t rvi;
-	  tree heapvar = build_fake_var_decl (TREE_TYPE (decl_type));
-	  DECL_EXTERNAL (heapvar) = 1;
-	  rvi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS", true, true);
-	  rvi->is_restrict_var = 1;
-	  insert_vi_for_tree (heapvar, rvi);
-	  make_constraint_from (vi, rvi->id);
-	  make_param_constraints (rvi);
-	}
       fieldstack.release ();
       return vi;
     }
@@ -5804,13 +5771,6 @@ create_variable_info_for_1 (tree decl, const char *name, bool add_id,
       newvi->fullsize = vi->fullsize;
       newvi->may_have_pointers = fo->may_have_pointers;
       newvi->only_restrict_pointers = fo->only_restrict_pointers;
-      if (handle_param
-	  && newvi->only_restrict_pointers
-	  && fo->restrict_var != NULL)
-	{
-	  make_constraint_from (newvi, fo->restrict_var->id);
-	  make_param_constraints (fo->restrict_var);
-	}
       if (i + 1 < fieldstack.length ())
 	{
 	  varinfo_t tem = new_var_info (decl, name, false);
@@ -5825,7 +5785,7 @@ create_variable_info_for_1 (tree decl, const char *name, bool add_id,
 static unsigned int
 create_variable_info_for (tree decl, const char *name, bool add_id)
 {
-  varinfo_t vi = create_variable_info_for_1 (decl, name, add_id, false);
+  varinfo_t vi = create_variable_info_for_1 (decl, name, add_id);
   unsigned int id = vi->id;
 
   insert_vi_for_tree (decl, vi);
@@ -5932,15 +5892,16 @@ debug_solution_for_var (unsigned int var)
   dump_solution_for_var (stderr, var);
 }
 
-/* Register the constraints for function parameter related VI.  */
+/* Register the constraints for function parameter related VI.  Use RESTRICT_NAME
+   as the base name of created restrict vars.  */
 
 static void
-make_param_constraints (varinfo_t vi)
+make_param_constraints (varinfo_t vi, const char *restrict_name)
 {
   for (; vi; vi = vi_next (vi))
     {
       if (vi->only_restrict_pointers)
-	;
+	make_constraint_from_global_restrict (vi, restrict_name, true);
       else if (vi->may_have_pointers)
 	make_constraint_from (vi, nonlocal_id);
 
@@ -5962,11 +5923,32 @@ intra_create_variable_infos (struct function *fn)
      passed-by-reference argument.  */
   for (t = DECL_ARGUMENTS (fn->decl); t; t = DECL_CHAIN (t))
     {
-      varinfo_t p
-	= create_variable_info_for_1 (t, alias_get_name (t), false, true);
+      bool restrict_pointer_p = (POINTER_TYPE_P (TREE_TYPE (t))
+				 && TYPE_RESTRICT (TREE_TYPE (t)));
+      bool recursive_restrict_p
+	= (restrict_pointer_p
+	   && !type_contains_placeholder_p (TREE_TYPE (TREE_TYPE (t))));
+      varinfo_t p = create_variable_info_for_1 (t, alias_get_name (t), false);
       insert_vi_for_tree (t, p);
 
-      make_param_constraints (p);
+      /* For restrict qualified pointers build a representative for
+	 the pointed-to object.  Note that this ends up handling
+	 out-of-bound references conservatively by aggregating them
+	 in the first/last subfield of the object.  */
+      if (recursive_restrict_p)
+	{
+	  varinfo_t vi;
+	  tree heapvar = build_fake_var_decl (TREE_TYPE (TREE_TYPE (t)));
+	  DECL_EXTERNAL (heapvar) = 1;
+	  vi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS", true);
+	  vi->is_restrict_var = 1;
+	  insert_vi_for_tree (heapvar, vi);
+	  make_constraint_from (p, vi->id);
+	  make_param_constraints (vi, "GLOBAL_RESTRICT");
+	  continue;
+	}
+
+      make_param_constraints (p, "PARM_RESTRICT");
     }
 
   /* Add a constraint for a result decl that is passed by reference.  */
-- 
1.9.1

[PATCH 2/2] Backport "Handle recursive restrict in function parameter"

2015-11-04  Tom de Vries  <t...@codesourcery.com>

	backport from trunk:
	2015-11-04  Tom de Vries  <t...@codesourcery.com>

	PR tree-optimization/67742
	* tree-ssa-structalias.c (struct fieldoff): Add restrict_pointed_type
	field.
	(push_fields_onto_fieldstack): Handle restrict_pointed_type field.
	(create_variable_info_for_1): Add and handle handle_param parameter.
	Add restrict handling.
	(create_variable_info_for): Call create_variable_info_for_1 with extra
	arg.
	(make_param_constraints): Drop restrict_name parameter.  Ignore
	vi->only_restrict_pointers.
	(intra_create_variable_infos): Call create_variable_info_for_1 with
	extra arg.  Remove restrict handling.  Call make_param_constraints with
	one less arg.

	* gcc.dg/tree-ssa/restrict-7.c: New test.
	* gcc.dg/tree-ssa/restrict-8.c: New test.

	* tree-ssa-structalias.c (create_variable_info_for_1): Use decl_type
	variable.
---
 gcc/testsuite/gcc.dg/tree-ssa/restrict-7.c | 12 +++++
 gcc/testsuite/gcc.dg/tree-ssa/restrict-8.c | 17 +++++++
 gcc/tree-ssa-structalias.c                 | 82 +++++++++++++++++-------------
 3 files changed, 76 insertions(+), 35 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/restrict-7.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/restrict-8.c

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/restrict-7.c b/gcc/testsuite/gcc.dg/tree-ssa/restrict-7.c
new file mode 100644
index 0000000..f7a68c7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/restrict-7.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-fre1" } */
+
+int
+f (int *__restrict__ *__restrict__ *__restrict__ a, int *b)
+{
+  *b = 1;
+  ***a  = 2;
+  return *b;
+}
+
+/* { dg-final { scan-tree-dump-times "return 1" 1 "fre1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/restrict-8.c b/gcc/testsuite/gcc.dg/tree-ssa/restrict-8.c
new file mode 100644
index 0000000..b0ab164
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/restrict-8.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-fre1" } */
+
+struct s
+{
+  int *__restrict__ *__restrict__ pp;
+};
+
+int
+f (struct s s, int *b)
+{
+  *b = 1;
+  **s.pp = 2;
+  return *b;
+}
+
+/* { dg-final { scan-tree-dump-times "return 1" 1 "fre1" } } */
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index f4c875f..f681b17 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -320,6 +320,7 @@ static varinfo_t first_or_preceding_vi_for_offset (varinfo_t,
 						   unsigned HOST_WIDE_INT);
 static varinfo_t lookup_vi_for_tree (tree);
 static inline bool type_can_have_subvars (const_tree);
+static void make_param_constraints (varinfo_t);
 
 /* Pool of variable info structures.  */
 static object_allocator<variable_info> variable_info_pool
@@ -406,7 +407,6 @@ new_var_info (tree t, const char *name, bool add_id)
   return ret;
 }
 
-
 /* A map mapping call statements to per-stmt variables for uses
    and clobbers specific to the call.  */
 static hash_map<gimple *, varinfo_t> *call_stmt_vars;
@@ -5208,6 +5208,8 @@ struct fieldoff
   unsigned may_have_pointers : 1;
 
   unsigned only_restrict_pointers : 1;
+
+  tree restrict_pointed_type;
 };
 typedef struct fieldoff fieldoff_s;
 
@@ -5353,7 +5355,8 @@ push_fields_onto_fieldstack (tree type, vec<fieldoff_s> *fieldstack,
 	    if (!pair
 		&& offset + foff != 0)
 	      {
-		fieldoff_s e = {0, offset + foff, false, false, false, false};
+		fieldoff_s e
+		  = {0, offset + foff, false, false, false, false, NULL_TREE};
 		pair = fieldstack->safe_push (e);
 	      }
 
@@ -5387,6 +5390,8 @@ push_fields_onto_fieldstack (tree type, vec<fieldoff_s> *fieldstack,
 		  = (!has_unknown_size
 		     && POINTER_TYPE_P (field_type)
 		     && TYPE_RESTRICT (field_type));
+		if (e.only_restrict_pointers)
+		  e.restrict_pointed_type = TREE_TYPE (field_type);
 		fieldstack->safe_push (e);
 	      }
 	  }
@@ -5655,10 +5660,11 @@ check_for_overlaps (vec<fieldoff_s> fieldstack)
 
 /* Create a varinfo structure for NAME and DECL, and add it to VARMAP.
    This will also create any varinfo structures necessary for fields
-   of DECL.  */
+   of DECL.  DECL is a function parameter if HANDLE_PARAM is set.  */
 
 static varinfo_t
-create_variable_info_for_1 (tree decl, const char *name, bool add_id)
+create_variable_info_for_1 (tree decl, const char *name, bool add_id,
+			    bool handle_param)
 {
   varinfo_t vi, newvi;
   tree decl_type = TREE_TYPE (decl);
@@ -5731,9 +5737,23 @@ create_variable_info_for_1 (tree decl, const char *name, bool add_id)
       vi->fullsize = tree_to_uhwi (declsize);
       vi->size = vi->fullsize;
       vi->is_full_var = true;
-      if (POINTER_TYPE_P (TREE_TYPE (decl))
-	  && TYPE_RESTRICT (TREE_TYPE (decl)))
+      if (POINTER_TYPE_P (decl_type)
+	  && TYPE_RESTRICT (decl_type))
 	vi->only_restrict_pointers = 1;
+      if (vi->only_restrict_pointers
+	  && !type_contains_placeholder_p (TREE_TYPE (decl_type))
+	  && handle_param)
+	{
+	  varinfo_t rvi;
+	  tree heapvar = build_fake_var_decl (TREE_TYPE (decl_type));
+	  DECL_EXTERNAL (heapvar) = 1;
+	  rvi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS", true,
+					    true);
+	  rvi->is_restrict_var = 1;
+	  insert_vi_for_tree (heapvar, rvi);
+	  make_constraint_from (vi, rvi->id);
+	  make_param_constraints (rvi);
+	}
       fieldstack.release ();
       return vi;
     }
@@ -5771,6 +5791,20 @@ create_variable_info_for_1 (tree decl, const char *name, bool add_id)
       newvi->fullsize = vi->fullsize;
       newvi->may_have_pointers = fo->may_have_pointers;
       newvi->only_restrict_pointers = fo->only_restrict_pointers;
+      if (handle_param
+	  && newvi->only_restrict_pointers
+	  && !type_contains_placeholder_p (fo->restrict_pointed_type))
+	{
+	  varinfo_t rvi;
+	  tree heapvar = build_fake_var_decl (fo->restrict_pointed_type);
+	  DECL_EXTERNAL (heapvar) = 1;
+	  rvi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS", true,
+					    true);
+	  rvi->is_restrict_var = 1;
+	  insert_vi_for_tree (heapvar, rvi);
+	  make_constraint_from (newvi, rvi->id);
+	  make_param_constraints (rvi);
+	}
       if (i + 1 < fieldstack.length ())
 	{
 	  varinfo_t tem = new_var_info (decl, name, false);
@@ -5785,7 +5819,7 @@ create_variable_info_for_1 (tree decl, const char *name, bool add_id)
 static unsigned int
 create_variable_info_for (tree decl, const char *name, bool add_id)
 {
-  varinfo_t vi = create_variable_info_for_1 (decl, name, add_id);
+  varinfo_t vi = create_variable_info_for_1 (decl, name, add_id, false);
   unsigned int id = vi->id;
 
   insert_vi_for_tree (decl, vi);
@@ -5892,16 +5926,15 @@ debug_solution_for_var (unsigned int var)
   dump_solution_for_var (stderr, var);
 }
 
-/* Register the constraints for function parameter related VI.  Use RESTRICT_NAME
-   as the base name of created restrict vars.  */
+/* Register the constraints for function parameter related VI.  */
 
 static void
-make_param_constraints (varinfo_t vi, const char *restrict_name)
+make_param_constraints (varinfo_t vi)
 {
   for (; vi; vi = vi_next (vi))
     {
       if (vi->only_restrict_pointers)
-	make_constraint_from_global_restrict (vi, restrict_name, true);
+	;
       else if (vi->may_have_pointers)
 	make_constraint_from (vi, nonlocal_id);
 
@@ -5923,32 +5956,11 @@ intra_create_variable_infos (struct function *fn)
      passed-by-reference argument.  */
   for (t = DECL_ARGUMENTS (fn->decl); t; t = DECL_CHAIN (t))
     {
-      bool restrict_pointer_p = (POINTER_TYPE_P (TREE_TYPE (t))
-				 && TYPE_RESTRICT (TREE_TYPE (t)));
-      bool recursive_restrict_p
-	= (restrict_pointer_p
-	   && !type_contains_placeholder_p (TREE_TYPE (TREE_TYPE (t))));
-      varinfo_t p = create_variable_info_for_1 (t, alias_get_name (t), false);
+      varinfo_t p
+	= create_variable_info_for_1 (t, alias_get_name (t), false, true);
       insert_vi_for_tree (t, p);
 
-      /* For restrict qualified pointers build a representative for
-	 the pointed-to object.  Note that this ends up handling
-	 out-of-bound references conservatively by aggregating them
-	 in the first/last subfield of the object.  */
-      if (recursive_restrict_p)
-	{
-	  varinfo_t vi;
-	  tree heapvar = build_fake_var_decl (TREE_TYPE (TREE_TYPE (t)));
-	  DECL_EXTERNAL (heapvar) = 1;
-	  vi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS", true);
-	  vi->is_restrict_var = 1;
-	  insert_vi_for_tree (heapvar, vi);
-	  make_constraint_from (p, vi->id);
-	  make_param_constraints (vi, "GLOBAL_RESTRICT");
-	  continue;
-	}
-
-      make_param_constraints (p, "PARM_RESTRICT");
+      make_param_constraints (p);
     }
 
   /* Add a constraint for a result decl that is passed by reference.  */
-- 
1.9.1

Reply via email to