[3.5/3.4] Fix bug in tree-inline.c
Josef Zlomek
zlomj9am@artax.karlin.mff.cuni.cz
Sat Feb 21 13:45:00 GMT 2004
> > * tree-inline.c (copy_body_r): Do not replace ret_label.
>
> A better fix is to copy the insert_decl_map function
> from tree-ssa. This inserts identity mapings for all
> decls that we have already remapped.
Attached patch merges insert_decl_map from tree-ssa branch and
fixes the bug by inserting a mapping from id->ret_label to id->ret_label.
Bootstrapped/regtested x86-64.
OK?
Josef
2004-02-20 Josef Zlomek <zlomekj@suse.cz>
Merge from tree-ssa:
2003-11-20 Richard Henderson <rth@redhat.com>
* tree-inline.c (insert_decl_map): New.
(remap_decl, remap_type, remap_block, copy_body_r,
initialize_inlined_parameters, declare_return_variable,
remap_save_expr): Use it.
* function.c (copy_body_r): Add mapping from id->ret_label to
id->ret_label. Revert test for ret_label.
Index: tree-inline.c
===================================================================
RCS file: /cvs/gcc-cvs/gcc/gcc/tree-inline.c,v
retrieving revision 1.94
diff -c -p -c -3 -p -r1.94 tree-inline.c
*** tree-inline.c 19 Feb 2004 22:39:45 -0000 1.94
--- tree-inline.c 20 Feb 2004 09:36:56 -0000
*************** static void remap_block (tree *, tree, i
*** 128,133 ****
--- 128,149 ----
static tree add_stmt_to_compound (tree, tree, tree);
#endif /* INLINER_FOR_JAVA */
+ /* Insert a tree->tree mapping for ID. Despite the name suggests
+ that the trees should be variables, it is used for more than that. */
+
+ static void
+ insert_decl_map (inline_data *id, tree key, tree value)
+ {
+ splay_tree_insert (id->decl_map, (splay_tree_key) key,
+ (splay_tree_value) value);
+
+ /* Always insert an identity map as well. If we see this same new
+ node again, we won't want to duplicate it a second time. */
+ if (key != value)
+ splay_tree_insert (id->decl_map, (splay_tree_key) value,
+ (splay_tree_value) value);
+ }
+
/* Remap DECL during the copying of the BLOCK tree for the function. */
static tree
*************** remap_decl (tree decl, inline_data *id)
*** 189,197 ****
/* Remember it, so that if we encounter this local entity
again we can reuse this copy. */
! n = splay_tree_insert (id->decl_map,
! (splay_tree_key) decl,
! (splay_tree_value) t);
}
return (tree) n->value;
--- 205,212 ----
/* Remember it, so that if we encounter this local entity
again we can reuse this copy. */
! insert_decl_map (id, decl, t);
! return t;
}
return (tree) n->value;
*************** remap_type (tree type, inline_data *id)
*** 214,228 ****
/* The type only needs remapping if it's variably modified. */
if (! variably_modified_type_p (type))
{
! splay_tree_insert (id->decl_map, (splay_tree_key) type,
! (splay_tree_value) type);
return type;
}
/* We do need a copy. build and register it now. */
new = copy_node (type);
! splay_tree_insert (id->decl_map, (splay_tree_key) type,
! (splay_tree_value) new);
/* This is a new type, not a copy of an old type. Need to reassociate
variants. We can handle everything except the main variant lazily. */
--- 229,241 ----
/* The type only needs remapping if it's variably modified. */
if (! variably_modified_type_p (type))
{
! insert_decl_map (id, type, type);
return type;
}
/* We do need a copy. build and register it now. */
new = copy_node (type);
! insert_decl_map (id, type, new);
/* This is a new type, not a copy of an old type. Need to reassociate
variants. We can handle everything except the main variant lazily. */
*************** remap_block (tree *block, tree decls, in
*** 392,400 ****
*first_block = new_block;
}
/* Remember the remapped block. */
! splay_tree_insert (id->decl_map,
! (splay_tree_key) old_block,
! (splay_tree_value) new_block);
}
/* If this is the end of a scope, set the SCOPE_STMT_BLOCK to be the
remapped block. */
--- 405,411 ----
*first_block = new_block;
}
/* Remember the remapped block. */
! insert_decl_map (id, old_block, new_block);
}
/* If this is the end of a scope, set the SCOPE_STMT_BLOCK to be the
remapped block. */
*************** copy_body_r (tree *tp, int *walk_subtree
*** 568,582 ****
/* If we're not returning anything just do the jump. */
else
*tp = goto_stmt;
}
/* Local variables and labels need to be replaced by equivalent
variables. We don't want to copy static variables; there's only
one of those, no matter how many times we inline the containing
! function.
! We do not also want to copy the label which we put into
! GOTO_STMT which replaced RETURN_STMT. */
! else if (*tp != id->ret_label
! && (*lang_hooks.tree_inlining.auto_var_in_fn_p) (*tp, fn))
{
tree new_decl;
--- 579,594 ----
/* If we're not returning anything just do the jump. */
else
*tp = goto_stmt;
+
+ /* We can't replace return label while inlining function
+ because it is in the outer function. */
+ insert_decl_map (id, id->ret_label, id->ret_label);
}
/* Local variables and labels need to be replaced by equivalent
variables. We don't want to copy static variables; there's only
one of those, no matter how many times we inline the containing
! function. */
! else if ((*lang_hooks.tree_inlining.auto_var_in_fn_p) (*tp, fn))
{
tree new_decl;
*************** copy_body_r (tree *tp, int *walk_subtree
*** 611,619 ****
will refer to it, so save a copy ready for remapping. We
save it in the decl_map, although it isn't a decl. */
tree new_block = copy_node (*tp);
! splay_tree_insert (id->decl_map,
! (splay_tree_key) *tp,
! (splay_tree_value) new_block);
*tp = new_block;
}
else if (TREE_CODE (*tp) == EXIT_BLOCK_EXPR)
--- 623,629 ----
will refer to it, so save a copy ready for remapping. We
save it in the decl_map, although it isn't a decl. */
tree new_block = copy_node (*tp);
! insert_decl_map (id, *tp, new_block);
*tp = new_block;
}
else if (TREE_CODE (*tp) == EXIT_BLOCK_EXPR)
*************** DECL_ARGUMENTS (fn);
*** 784,792 ****
else if (TREE_TYPE (value) != TREE_TYPE (p))
value = fold (build1 (NOP_EXPR, TREE_TYPE (p), value));
! splay_tree_insert (id->decl_map,
! (splay_tree_key) p,
! (splay_tree_value) value);
continue;
}
}
--- 794,800 ----
else if (TREE_TYPE (value) != TREE_TYPE (p))
value = fold (build1 (NOP_EXPR, TREE_TYPE (p), value));
! insert_decl_map (id, p, value);
continue;
}
}
*************** DECL_ARGUMENTS (fn);
*** 807,815 ****
/* Register the VAR_DECL as the equivalent for the PARM_DECL;
that way, when the PARM_DECL is encountered, it will be
automatically replaced by the VAR_DECL. */
! splay_tree_insert (id->decl_map,
! (splay_tree_key) p,
! (splay_tree_value) var_sub);
/* Declare this new variable. */
#ifndef INLINER_FOR_JAVA
--- 815,821 ----
/* Register the VAR_DECL as the equivalent for the PARM_DECL;
that way, when the PARM_DECL is encountered, it will be
automatically replaced by the VAR_DECL. */
! insert_decl_map (id, p, var_sub);
/* Declare this new variable. */
#ifndef INLINER_FOR_JAVA
*************** declare_return_variable (struct inline_d
*** 947,955 ****
/* Register the VAR_DECL as the equivalent for the RESULT_DECL; that
way, when the RESULT_DECL is encountered, it will be
automatically replaced by the VAR_DECL. */
! splay_tree_insert (id->decl_map,
! (splay_tree_key) result,
! (splay_tree_value) var);
/* Build the USE_STMT. If the return type of the function was
promoted, convert it back to the expected type. */
--- 953,959 ----
/* Register the VAR_DECL as the equivalent for the RESULT_DECL; that
way, when the RESULT_DECL is encountered, it will be
automatically replaced by the VAR_DECL. */
! insert_decl_map (id, result, var);
/* Build the USE_STMT. If the return type of the function was
promoted, convert it back to the expected type. */
*************** remap_save_expr (tree *tp, void *st_, tr
*** 2005,2010 ****
--- 2009,2015 ----
{
splay_tree st = (splay_tree) st_;
splay_tree_node n;
+ tree t;
/* See if we already encountered this SAVE_EXPR. */
n = splay_tree_lookup (st, (splay_tree_key) *tp);
*************** remap_save_expr (tree *tp, void *st_, tr
*** 2012,2018 ****
/* If we didn't already remap this SAVE_EXPR, do so now. */
if (!n)
{
! tree t = copy_node (*tp);
/* The SAVE_EXPR is now part of the function into which we
are inlining this body. */
--- 2017,2023 ----
/* If we didn't already remap this SAVE_EXPR, do so now. */
if (!n)
{
! t = copy_node (*tp);
/* The SAVE_EXPR is now part of the function into which we
are inlining this body. */
*************** remap_save_expr (tree *tp, void *st_, tr
*** 2020,2038 ****
/* And we haven't evaluated it yet. */
SAVE_EXPR_RTL (t) = NULL_RTX;
/* Remember this SAVE_EXPR. */
! n = splay_tree_insert (st,
! (splay_tree_key) *tp,
! (splay_tree_value) t);
/* Make sure we don't remap an already-remapped SAVE_EXPR. */
splay_tree_insert (st, (splay_tree_key) t, (splay_tree_value) t);
}
else
! /* We've already walked into this SAVE_EXPR, so we needn't do it
! again. */
! *walk_subtrees = 0;
/* Replace this SAVE_EXPR with the copy. */
! *tp = (tree) n->value;
}
#ifdef INLINER_FOR_JAVA
--- 2025,2043 ----
/* And we haven't evaluated it yet. */
SAVE_EXPR_RTL (t) = NULL_RTX;
/* Remember this SAVE_EXPR. */
! splay_tree_insert (st, (splay_tree_key) *tp, (splay_tree_value) t);
/* Make sure we don't remap an already-remapped SAVE_EXPR. */
splay_tree_insert (st, (splay_tree_key) t, (splay_tree_value) t);
}
else
! {
! /* We've already walked into this SAVE_EXPR; don't do it again. */
! *walk_subtrees = 0;
! t = (tree) n->value;
! }
/* Replace this SAVE_EXPR with the copy. */
! *tp = t;
}
#ifdef INLINER_FOR_JAVA
More information about the Gcc-patches
mailing list