gimple.h (gimplify_body): Remove first argument.

* 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.

From-SVN: r183104
This commit is contained in:
Eric Botcazou 2012-01-11 18:50:54 +00:00 committed by Eric Botcazou
parent 2cd8b32cb9
commit 3ad065efe1
7 changed files with 100 additions and 40 deletions

View File

@ -1,3 +1,15 @@
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.

View 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 *);

View 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)
{
walk_tree (tp, copy_if_shared_r, data, NULL);
}
/* Unshare all the trees in the body of FNDECL, as well as in the bodies of
any nested functions. */
static void
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;
walk_tree (tp, copy_if_shared_r, visited, NULL);
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 (visited)
pointer_set_destroy (visited);
}
/* 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. */
static void
unshare_body (tree *body_p, tree fndecl)
{
struct cgraph_node *cgn = cgraph_get_node (fndecl);
copy_if_shared (body_p);
if (cgn && body_p == &DECL_SAVED_TREE (fndecl))
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. */

View 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);

View File

@ -1,3 +1,7 @@
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.

View File

@ -0,0 +1,34 @@
-- { dg-do compile }
package body Array19 is
function N return Integer is
begin
return 1;
end;
type Array_Type is array (1 .. N) of Float;
type Enum is (One, Two);
type Rec (D : Enum := Enum'First) is record
case D is
when One => null;
when Two => A : Array_Type;
end case;
end record;
procedure Proc is
R : Rec;
function F return Array_Type is
begin
return (others => 0.0);
end F;
begin
R.A := F;
end;
end Array19;

View File

@ -0,0 +1,5 @@
package Array19 is
procedure Proc;
end Array19;