This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH to tree-inline.c:copy_body_r
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 19 May 2003 11:54:38 -0400
- Subject: PATCH to tree-inline.c:copy_body_r
Inline substitution can produce &*, which we try to avoid when building a
function in the first place; it also causes problems for tree-ssa, since it
isn't valid GIMPLE.
While I was fixing that, I noticed that the existing special handling of
MODIFY_EXPR was overwriting *tp after copying it, which means we copy
something we're about to throw away and then we don't copy the new value.
Fixed thus.
Booted and tested i686-pc-linux-gnu, applied to trunk and tree-ssa.
2003-05-19 Jason Merrill <jason@redhat.com>
* tree-inline.c (copy_body_r): Avoid generating &* during inline
substitution.
*** gcc/tree-inline.c.~1~ 2003-05-07 11:15:18.000000000 -0400
--- gcc/tree-inline.c 2003-05-16 15:22:03.000000000 -0400
*************** copy_body_r (tp, walk_subtrees, data)
*** 428,446 ****
knows not to copy VAR_DECLs, etc., so this is safe. */
else
{
! copy_tree_r (tp, walk_subtrees, NULL);
!
! /* The copied TARGET_EXPR has never been expanded, even if the
! original node was expanded already. */
! if (TREE_CODE (*tp) == TARGET_EXPR && TREE_OPERAND (*tp, 3))
! {
! TREE_OPERAND (*tp, 1) = TREE_OPERAND (*tp, 3);
! TREE_OPERAND (*tp, 3) = NULL_TREE;
! }
! else if (TREE_CODE (*tp) == MODIFY_EXPR
! && TREE_OPERAND (*tp, 0) == TREE_OPERAND (*tp, 1)
! && ((*lang_hooks.tree_inlining.auto_var_in_fn_p)
! (TREE_OPERAND (*tp, 0), fn)))
{
/* Some assignments VAR = VAR; don't generate any rtl code
and thus don't count as variable modification. Avoid
--- 428,437 ----
knows not to copy VAR_DECLs, etc., so this is safe. */
else
{
! if (TREE_CODE (*tp) == MODIFY_EXPR
! && TREE_OPERAND (*tp, 0) == TREE_OPERAND (*tp, 1)
! && ((*lang_hooks.tree_inlining.auto_var_in_fn_p)
! (TREE_OPERAND (*tp, 0), fn)))
{
/* Some assignments VAR = VAR; don't generate any rtl code
and thus don't count as variable modification. Avoid
*************** copy_body_r (tp, walk_subtrees, data)
*** 454,462 ****
value = (tree) n->value;
STRIP_TYPE_NOPS (value);
if (TREE_CONSTANT (value) || TREE_READONLY_DECL_P (value))
! *tp = value;
}
}
}
/* Keep iterating. */
--- 445,487 ----
value = (tree) n->value;
STRIP_TYPE_NOPS (value);
if (TREE_CONSTANT (value) || TREE_READONLY_DECL_P (value))
! {
! *tp = value;
! return copy_body_r (tp, walk_subtrees, data);
! }
}
}
+ else if (TREE_CODE (*tp) == ADDR_EXPR
+ && ((*lang_hooks.tree_inlining.auto_var_in_fn_p)
+ (TREE_OPERAND (*tp, 0), fn)))
+ {
+ /* Get rid of &* from inline substitutions. It can occur when
+ someone takes the address of a parm or return slot passed by
+ invisible reference. */
+ tree decl = TREE_OPERAND (*tp, 0), value;
+ splay_tree_node n;
+
+ n = splay_tree_lookup (id->decl_map, (splay_tree_key) decl);
+ if (n)
+ {
+ value = (tree) n->value;
+ if (TREE_CODE (value) == INDIRECT_REF)
+ {
+ *tp = convert (TREE_TYPE (*tp), TREE_OPERAND (value, 0));
+ return copy_body_r (tp, walk_subtrees, data);
+ }
+ }
+ }
+
+ copy_tree_r (tp, walk_subtrees, NULL);
+
+ /* The copied TARGET_EXPR has never been expanded, even if the
+ original node was expanded already. */
+ if (TREE_CODE (*tp) == TARGET_EXPR && TREE_OPERAND (*tp, 3))
+ {
+ TREE_OPERAND (*tp, 1) = TREE_OPERAND (*tp, 3);
+ TREE_OPERAND (*tp, 3) = NULL_TREE;
+ }
}
/* Keep iterating. */