Commit 3ad065ef by Eric Botcazou Committed by Eric Botcazou

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
parent 2cd8b32c
2012-01-11 Eric Botcazou <ebotcazou@adacore.com> 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. * tree.h (build_function_decl_skip_args): Add boolean parameter.
(build_function_type_skip_args): Delete. (build_function_type_skip_args): Delete.
* tree.c (build_function_type_skip_args): Make static and add * tree.c (build_function_type_skip_args): Make static and add
......
...@@ -1097,7 +1097,7 @@ extern enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *, ...@@ -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_type_sizes (tree, gimple_seq *);
extern void gimplify_one_sizepos (tree *, gimple_seq *); extern void gimplify_one_sizepos (tree *, gimple_seq *);
extern bool gimplify_stmt (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 push_gimplify_context (struct gimplify_ctx *);
extern void pop_gimplify_context (gimple); extern void pop_gimplify_context (gimple);
extern void gimplify_and_add (tree, gimple_seq *); extern void gimplify_and_add (tree, gimple_seq *);
......
...@@ -867,9 +867,10 @@ annotate_all_with_location (gimple_seq stmt_p, location_t location) ...@@ -867,9 +867,10 @@ annotate_all_with_location (gimple_seq stmt_p, location_t location)
way to go. */ way to go. */
/* Similar to copy_tree_r but do not copy SAVE_EXPR or TARGET_EXPR nodes. /* 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 These nodes model computations that must be done once. If we were to
were to unshare something like SAVE_EXPR(i++), the gimplification unshare something like SAVE_EXPR(i++), the gimplification process would
process would create wrong code. */ 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 static tree
mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data) 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) ...@@ -909,9 +910,9 @@ mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data)
return NULL_TREE; return NULL_TREE;
} }
/* Callback for walk_tree to unshare most of the shared trees rooted at /* Callback for walk_tree to unshare most of the shared trees rooted at *TP.
*TP. If *TP has been visited already (i.e., TREE_VISITED (*TP) == 1), If *TP has been visited already, then *TP is deeply copied by calling
then *TP is deep copied by calling mostly_copy_tree_r. */ mostly_copy_tree_r. DATA is passed to mostly_copy_tree_r unmodified. */
static tree static tree
copy_if_shared_r (tree *tp, int *walk_subtrees, void *data) 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) ...@@ -948,34 +949,37 @@ copy_if_shared_r (tree *tp, int *walk_subtrees, void *data)
return NULL_TREE; 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 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 walk_tree (tp, copy_if_shared_r, data, NULL);
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);
} }
/* Unshare all the trees in BODY_P, a pointer into the body of FNDECL, and the /* Unshare all the trees in the body of FNDECL, as well as in the bodies of
bodies of any nested functions if we are unsharing the entire body of any nested functions. */
FNDECL. */
static void static void
unshare_body (tree *body_p, tree fndecl) unshare_body (tree fndecl)
{ {
struct cgraph_node *cgn = cgraph_get_node (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) 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. /* Callback for walk_tree to unmark the visited trees rooted at *TP.
...@@ -1008,15 +1012,17 @@ unmark_visited (tree *tp) ...@@ -1008,15 +1012,17 @@ unmark_visited (tree *tp)
/* Likewise, but mark all trees as not visited. */ /* Likewise, but mark all trees as not visited. */
static void static void
unvisit_body (tree *body_p, tree fndecl) unvisit_body (tree fndecl)
{ {
struct cgraph_node *cgn = cgraph_get_node (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) 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 /* 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) ...@@ -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 /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
GIMPLE_BIND containing the sequence of GIMPLE statements containing the sequence of corresponding GIMPLE statements. If DO_PARMS
corresponding to BODY_P. FNDECL is the function decl containing is true, also gimplify the parameters. */
*BODY_P. */
gimple gimple
gimplify_body (tree *body_p, tree fndecl, bool do_parms) gimplify_body (tree fndecl, bool do_parms)
{ {
location_t saved_location = input_location; location_t saved_location = input_location;
gimple_seq parm_stmts, seq; gimple_seq parm_stmts, seq;
...@@ -7965,8 +7970,8 @@ gimplify_body (tree *body_p, tree fndecl, bool do_parms) ...@@ -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 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 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. */ first, but the g++ front end doesn't always do it that way. */
unshare_body (body_p, fndecl); unshare_body (fndecl);
unvisit_body (body_p, fndecl); unvisit_body (fndecl);
cgn = cgraph_get_node (fndecl); cgn = cgraph_get_node (fndecl);
if (cgn && cgn->origin) if (cgn && cgn->origin)
...@@ -7977,11 +7982,11 @@ gimplify_body (tree *body_p, tree fndecl, bool do_parms) ...@@ -7977,11 +7982,11 @@ gimplify_body (tree *body_p, tree fndecl, bool do_parms)
/* Resolve callee-copies. This has to be done before processing /* Resolve callee-copies. This has to be done before processing
the body so that DECL_VALUE_EXPR gets processed correctly. */ 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. */ /* Gimplify the function's body. */
seq = NULL; seq = NULL;
gimplify_stmt (body_p, &seq); gimplify_stmt (&DECL_SAVED_TREE (fndecl), &seq);
outer_bind = gimple_seq_first_stmt (seq); outer_bind = gimple_seq_first_stmt (seq);
if (!outer_bind) if (!outer_bind)
{ {
...@@ -7997,7 +8002,7 @@ gimplify_body (tree *body_p, tree fndecl, bool do_parms) ...@@ -7997,7 +8002,7 @@ gimplify_body (tree *body_p, tree fndecl, bool do_parms)
else else
outer_bind = gimple_build_bind (NULL_TREE, seq, NULL); 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 /* If we had callee-copies statements, insert them at the beginning
of the function and clear DECL_VALUE_EXPR_P on the parameters. */ of the function and clear DECL_VALUE_EXPR_P on the parameters. */
...@@ -8115,7 +8120,7 @@ gimplify_function_tree (tree fndecl) ...@@ -8115,7 +8120,7 @@ gimplify_function_tree (tree fndecl)
&& !needs_to_live_in_memory (ret)) && !needs_to_live_in_memory (ret))
DECL_GIMPLE_REG_P (ret) = 1; 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 /* The tree body of the function is no longer needed, replace it
with the new GIMPLE body. */ with the new GIMPLE body. */
......
...@@ -1248,7 +1248,7 @@ finalize_task_copyfn (gimple task_stmt) ...@@ -1248,7 +1248,7 @@ finalize_task_copyfn (gimple task_stmt)
old_fn = current_function_decl; old_fn = current_function_decl;
push_cfun (child_cfun); push_cfun (child_cfun);
current_function_decl = child_fn; 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 (); seq = gimple_seq_alloc ();
gimple_seq_add_stmt (&seq, bind); gimple_seq_add_stmt (&seq, bind);
new_seq = maybe_catch_exception (seq); new_seq = maybe_catch_exception (seq);
......
2012-01-11 Eric Botcazou <ebotcazou@adacore.com> 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.ad[sb]: New test.
* gnat.dg/opt23_pkg.ad[sb]: New helper. * gnat.dg/opt23_pkg.ad[sb]: New helper.
* gnat.dg/opt24.ad[sb]: New test. * gnat.dg/opt24.ad[sb]: New test.
......
-- { 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;
package Array19 is
procedure Proc;
end Array19;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment