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:
parent
2cd8b32cb9
commit
3ad065efe1
@ -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.
|
||||
|
@ -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 *);
|
||||
|
@ -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. */
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
34
gcc/testsuite/gnat.dg/array19.adb
Normal file
34
gcc/testsuite/gnat.dg/array19.adb
Normal 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;
|
5
gcc/testsuite/gnat.dg/array19.ads
Normal file
5
gcc/testsuite/gnat.dg/array19.ads
Normal file
@ -0,0 +1,5 @@
|
||||
package Array19 is
|
||||
|
||||
procedure Proc;
|
||||
|
||||
end Array19;
|
Loading…
x
Reference in New Issue
Block a user