This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]