OSDN Git Service

* gimple.h (gimplify_body): Remove first argument.
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 11 Jan 2012 18:50:54 +0000 (18:50 +0000)
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 11 Jan 2012 18:50:54 +0000 (18:50 +0000)
* gimplify.c (copy_if_shared): Add DATA argument.  Do not create the
pointer set here, instead just pass DATA to walk_tree.
(unshare_body): Remove BODY_P argument and adjust.  Create the pointer
set here and invoke copy_if_shared on the size trees of DECL_RESULT.
(unvisit_body): Likewise, but with unmark_visited.
(gimplify_body): Remove BODY_P argument and adjust.
(gimplify_function_tree): Adjust call to gimplify_body.
* omp-low.c (finalize_task_copyfn): Likewise.

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

gcc/ChangeLog
gcc/gimple.h
gcc/gimplify.c
gcc/omp-low.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/array19.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/array19.ads [new file with mode: 0644]

index bc8e97a..16bcd96 100644 (file)
@@ -1,5 +1,17 @@
 2012-01-11  Eric Botcazou  <ebotcazou@adacore.com>
 
+       * gimple.h (gimplify_body): Remove first argument.
+       * gimplify.c (copy_if_shared): Add DATA argument.  Do not create the
+       pointer set here, instead just pass DATA to walk_tree.
+       (unshare_body): Remove BODY_P argument and adjust.  Create the pointer
+       set here and invoke copy_if_shared on the size trees of DECL_RESULT.
+       (unvisit_body): Likewise, but with unmark_visited.
+       (gimplify_body): Remove BODY_P argument and adjust.
+       (gimplify_function_tree): Adjust call to gimplify_body.
+       * omp-low.c (finalize_task_copyfn): Likewise.
+
+2012-01-11  Eric Botcazou  <ebotcazou@adacore.com>
+
        * tree.h (build_function_decl_skip_args): Add boolean parameter.
        (build_function_type_skip_args): Delete.
        * tree.c (build_function_type_skip_args): Make static and add
index 5283ca2..ec32f25 100644 (file)
@@ -1097,7 +1097,7 @@ extern enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
 extern void gimplify_type_sizes (tree, gimple_seq *);
 extern void gimplify_one_sizepos (tree *, gimple_seq *);
 extern bool gimplify_stmt (tree *, gimple_seq *);
-extern gimple gimplify_body (tree *, tree, bool);
+extern gimple gimplify_body (tree, bool);
 extern void push_gimplify_context (struct gimplify_ctx *);
 extern void pop_gimplify_context (gimple);
 extern void gimplify_and_add (tree, gimple_seq *);
index b3b047a..94b99a1 100644 (file)
@@ -867,9 +867,10 @@ annotate_all_with_location (gimple_seq stmt_p, location_t location)
   way to go.  */
 
 /* Similar to copy_tree_r but do not copy SAVE_EXPR or TARGET_EXPR nodes.
-   These nodes model computations that should only be done once.  If we
-   were to unshare something like SAVE_EXPR(i++), the gimplification
-   process would create wrong code.  */
+   These nodes model computations that must be done once.  If we were to
+   unshare something like SAVE_EXPR(i++), the gimplification process would
+   create wrong code.  However, if DATA is non-null, it must hold a pointer
+   set that is used to unshare the subtrees of these nodes.  */
 
 static tree
 mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data)
@@ -909,9 +910,9 @@ mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data)
   return NULL_TREE;
 }
 
-/* Callback for walk_tree to unshare most of the shared trees rooted at
-   *TP.  If *TP has been visited already (i.e., TREE_VISITED (*TP) == 1),
-   then *TP is deep copied by calling mostly_copy_tree_r.  */
+/* Callback for walk_tree to unshare most of the shared trees rooted at *TP.
+   If *TP has been visited already, then *TP is deeply copied by calling
+   mostly_copy_tree_r.  DATA is passed to mostly_copy_tree_r unmodified.  */
 
 static tree
 copy_if_shared_r (tree *tp, int *walk_subtrees, void *data)
@@ -948,34 +949,37 @@ copy_if_shared_r (tree *tp, int *walk_subtrees, void *data)
   return NULL_TREE;
 }
 
-/* Unshare most of the shared trees rooted at *TP. */
+/* Unshare most of the shared trees rooted at *TP.  DATA is passed to the
+   copy_if_shared_r callback unmodified.  */
 
 static inline void
-copy_if_shared (tree *tp)
+copy_if_shared (tree *tp, void *data)
 {
-  /* If the language requires deep unsharing, we need a pointer set to make
-     sure we don't repeatedly unshare subtrees of unshareable nodes.  */
-  struct pointer_set_t *visited
-    = lang_hooks.deep_unsharing ? pointer_set_create () : NULL;
-  walk_tree (tp, copy_if_shared_r, visited, NULL);
-  if (visited)
-    pointer_set_destroy (visited);
+  walk_tree (tp, copy_if_shared_r, data, NULL);
 }
 
-/* Unshare all the trees in BODY_P, a pointer into the body of FNDECL, and the
-   bodies of any nested functions if we are unsharing the entire body of
-   FNDECL.  */
+/* Unshare all the trees in the body of FNDECL, as well as in the bodies of
+   any nested functions.  */
 
 static void
-unshare_body (tree *body_p, tree fndecl)
+unshare_body (tree fndecl)
 {
   struct cgraph_node *cgn = cgraph_get_node (fndecl);
+  /* If the language requires deep unsharing, we need a pointer set to make
+     sure we don't repeatedly unshare subtrees of unshareable nodes.  */
+  struct pointer_set_t *visited
+    = lang_hooks.deep_unsharing ? pointer_set_create () : NULL;
 
-  copy_if_shared (body_p);
+  copy_if_shared (&DECL_SAVED_TREE (fndecl), visited);
+  copy_if_shared (&DECL_SIZE (DECL_RESULT (fndecl)), visited);
+  copy_if_shared (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)), visited);
 
-  if (cgn && body_p == &DECL_SAVED_TREE (fndecl))
+  if (visited)
+    pointer_set_destroy (visited);
+
+  if (cgn)
     for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
-      unshare_body (&DECL_SAVED_TREE (cgn->decl), cgn->decl);
+      unshare_body (cgn->decl);
 }
 
 /* Callback for walk_tree to unmark the visited trees rooted at *TP.
@@ -1008,15 +1012,17 @@ unmark_visited (tree *tp)
 /* Likewise, but mark all trees as not visited.  */
 
 static void
-unvisit_body (tree *body_p, tree fndecl)
+unvisit_body (tree fndecl)
 {
   struct cgraph_node *cgn = cgraph_get_node (fndecl);
 
-  unmark_visited (body_p);
+  unmark_visited (&DECL_SAVED_TREE (fndecl));
+  unmark_visited (&DECL_SIZE (DECL_RESULT (fndecl)));
+  unmark_visited (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)));
 
-  if (cgn && body_p == &DECL_SAVED_TREE (fndecl))
+  if (cgn)
     for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
-      unvisit_body (&DECL_SAVED_TREE (cgn->decl), cgn->decl);
+      unvisit_body (cgn->decl);
 }
 
 /* Unconditionally make an unshared copy of EXPR.  This is used when using
@@ -7938,13 +7944,12 @@ gimplify_one_sizepos (tree *expr_p, gimple_seq *stmt_p)
     }
 }
 
-/* Gimplify the body of statements pointed to by BODY_P and return a
-   GIMPLE_BIND containing the sequence of GIMPLE statements
-   corresponding to BODY_P.  FNDECL is the function decl containing
-   *BODY_P.  */
+/* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
+   containing the sequence of corresponding GIMPLE statements.  If DO_PARMS
+   is true, also gimplify the parameters.  */
 
 gimple
-gimplify_body (tree *body_p, tree fndecl, bool do_parms)
+gimplify_body (tree fndecl, bool do_parms)
 {
   location_t saved_location = input_location;
   gimple_seq parm_stmts, seq;
@@ -7965,8 +7970,8 @@ gimplify_body (tree *body_p, tree fndecl, bool do_parms)
      It would seem we don't have to do this for nested functions because
      they are supposed to be output and then the outer function gimplified
      first, but the g++ front end doesn't always do it that way.  */
-  unshare_body (body_p, fndecl);
-  unvisit_body (body_p, fndecl);
+  unshare_body (fndecl);
+  unvisit_body (fndecl);
 
   cgn = cgraph_get_node (fndecl);
   if (cgn && cgn->origin)
@@ -7977,11 +7982,11 @@ gimplify_body (tree *body_p, tree fndecl, bool do_parms)
 
   /* Resolve callee-copies.  This has to be done before processing
      the body so that DECL_VALUE_EXPR gets processed correctly.  */
-  parm_stmts = (do_parms) ? gimplify_parameters () : NULL;
+  parm_stmts = do_parms ? gimplify_parameters () : NULL;
 
   /* Gimplify the function's body.  */
   seq = NULL;
-  gimplify_stmt (body_p, &seq);
+  gimplify_stmt (&DECL_SAVED_TREE (fndecl), &seq);
   outer_bind = gimple_seq_first_stmt (seq);
   if (!outer_bind)
     {
@@ -7997,7 +8002,7 @@ gimplify_body (tree *body_p, tree fndecl, bool do_parms)
   else
     outer_bind = gimple_build_bind (NULL_TREE, seq, NULL);
 
-  *body_p = NULL_TREE;
+  DECL_SAVED_TREE (fndecl) = NULL_TREE;
 
   /* If we had callee-copies statements, insert them at the beginning
      of the function and clear DECL_VALUE_EXPR_P on the parameters.  */
@@ -8115,7 +8120,7 @@ gimplify_function_tree (tree fndecl)
       && !needs_to_live_in_memory (ret))
     DECL_GIMPLE_REG_P (ret) = 1;
 
-  bind = gimplify_body (&DECL_SAVED_TREE (fndecl), fndecl, true);
+  bind = gimplify_body (fndecl, true);
 
   /* The tree body of the function is no longer needed, replace it
      with the new GIMPLE body.  */
index 4e1c2ba..8ab689d 100644 (file)
@@ -1248,7 +1248,7 @@ finalize_task_copyfn (gimple task_stmt)
   old_fn = current_function_decl;
   push_cfun (child_cfun);
   current_function_decl = child_fn;
-  bind = gimplify_body (&DECL_SAVED_TREE (child_fn), child_fn, false);
+  bind = gimplify_body (child_fn, false);
   seq = gimple_seq_alloc ();
   gimple_seq_add_stmt (&seq, bind);
   new_seq = maybe_catch_exception (seq);
index 9724f75..f49cdd9 100644 (file)
@@ -1,5 +1,9 @@
 2012-01-11  Eric Botcazou  <ebotcazou@adacore.com>
 
+       * gnat.dg/array19.ad[sb]: New test.
+
+2012-01-11  Eric Botcazou  <ebotcazou@adacore.com>
+
        * gnat.dg/opt23.ad[sb]: New test.
        * gnat.dg/opt23_pkg.ad[sb]: New helper.
        * gnat.dg/opt24.ad[sb]: New test.
diff --git a/gcc/testsuite/gnat.dg/array19.adb b/gcc/testsuite/gnat.dg/array19.adb
new file mode 100644 (file)
index 0000000..56b05d6
--- /dev/null
@@ -0,0 +1,34 @@
+-- { dg-do compile }\r
+\r
+package body Array19 is\r
+\r
+   function N return Integer is\r
+   begin\r
+      return 1;\r
+   end;\r
+\r
+   type Array_Type is array (1 .. N) of Float;\r
+\r
+   type Enum is (One, Two);\r
+\r
+   type Rec (D : Enum := Enum'First) is record\r
+      case D is\r
+         when One => null;\r
+         when Two => A : Array_Type;\r
+      end case;\r
+   end record;\r
+\r
+   procedure Proc is\r
+\r
+      R : Rec;\r
+\r
+      function F return Array_Type is\r
+      begin\r
+         return (others => 0.0);\r
+      end F;\r
+\r
+   begin\r
+      R.A := F;\r
+   end;\r
+\r
+end Array19;\r
diff --git a/gcc/testsuite/gnat.dg/array19.ads b/gcc/testsuite/gnat.dg/array19.ads
new file mode 100644 (file)
index 0000000..48947f5
--- /dev/null
@@ -0,0 +1,5 @@
+package Array19 is\r
+\r
+   procedure Proc;\r
+\r
+end Array19;\r