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]

Re: PATCH to avoid copying tail padding (was: GCC 3.2)


On Fri, 23 Aug 2002 12:42:48 +0100, Jason Merrill <jason@redhat.com> wrote:

> On Fri, 02 Aug 2002 12:57:19 +0100, Jason Merrill <jason@redhat.com> wrote:
>
>> Here's the patch I'm applying to the trunk.  The patch for 3.2.1 will be a
>> bit different.
>
> Here's the patch for 3.2.1.  It also includes an earlier deferred patch for
> PR 5607.

This patch turns out also to be necessary to avoid bitwise copy of an
inappropriate class on ia64, which now causes a compiler abort.

Tested the fix on an ia64 cross-compiler, regression tested on
i686-pc-linux-gnu.  Applied to 3.2 branch.

2002-08-06  Jason Merrill  <jason@redhat.com>

	* c-common.c (c_expand_expr) [STMT_EXPR]: If the last expression is
	a VAR_DECL with RTL that matches the target, just return that RTL.

2002-06-01  Daniel Berlin  <dberlin@dberlin.org>

	* tree-inline.c (expand_call_inline): Make the statement
	expression we generate have a COMPOUND_STMT.

*** c-common.c.~1~	Wed Jul  3 18:30:26 2002
--- c-common.c	Wed Aug 28 20:06:31 2002
*************** c_expand_expr (exp, target, tmode, modif
*** 3564,3569 ****
--- 3564,3570 ----
  	tree rtl_expr;
  	rtx result;
  	bool preserve_result = false;
+ 	bool return_target = false;
  
  	/* Since expand_expr_stmt calls free_temp_slots after every
  	   expression statement, we must call push_temp_slots here.
*************** c_expand_expr (exp, target, tmode, modif
*** 3591,3598 ****
  	    if (TREE_CODE (last) == SCOPE_STMT
  		&& TREE_CODE (expr) == EXPR_STMT)
  	      {
! 	        TREE_ADDRESSABLE (expr) = 1;
! 		preserve_result = true;
  	      }
  	  }
  
--- 3592,3611 ----
  	    if (TREE_CODE (last) == SCOPE_STMT
  		&& TREE_CODE (expr) == EXPR_STMT)
  	      {
! 		if (target && TREE_CODE (EXPR_STMT_EXPR (expr)) == VAR_DECL
! 		    && DECL_RTL_IF_SET (EXPR_STMT_EXPR (expr)) == target)
! 		  /* If the last expression is a variable whose RTL is the
! 		     same as our target, just return the target; if it
! 		     isn't valid expanding the decl would produce different
! 		     RTL, and store_expr would try to do a copy.  */
! 		  return_target = true;
! 		else
! 		  {
! 		    /* Otherwise, note that we want the value from the last
! 		       expression.  */
! 		    TREE_ADDRESSABLE (expr) = 1;
! 		    preserve_result = true;
! 		  }
  	      }
  	  }
  
*************** c_expand_expr (exp, target, tmode, modif
*** 3600,3606 ****
  	expand_end_stmt_expr (rtl_expr);
  
  	result = expand_expr (rtl_expr, target, tmode, modifier);
! 	if (preserve_result && GET_CODE (result) == MEM)
  	  {
  	    if (GET_MODE (result) != BLKmode)
  	      result = copy_to_reg (result);
--- 3613,3621 ----
  	expand_end_stmt_expr (rtl_expr);
  
  	result = expand_expr (rtl_expr, target, tmode, modifier);
! 	if (return_target)
! 	  result = target;
! 	else if (preserve_result && GET_CODE (result) == MEM)
  	  {
  	    if (GET_MODE (result) != BLKmode)
  	      result = copy_to_reg (result);
*** tree-inline.c.~1~	Tue Apr 23 14:14:56 2002
--- tree-inline.c	Wed Aug 28 20:03:52 2002
*************** expand_call_inline (tp, walk_subtrees, d
*** 762,767 ****
--- 762,768 ----
    inline_data *id;
    tree t;
    tree expr;
+   tree stmt;
    tree chain;
    tree fn;
    tree scope_stmt;
*************** expand_call_inline (tp, walk_subtrees, d
*** 853,862 ****
       for the return statements within the function to jump to.  The
       type of the statement expression is the return type of the
       function call.  */
!   expr = build1 (STMT_EXPR, TREE_TYPE (TREE_TYPE (fn)), NULL_TREE);
    /* There is no scope associated with the statement-expression.  */
    STMT_EXPR_NO_SCOPE (expr) = 1;
! 
    /* Local declarations will be replaced by their equivalents in this
       map.  */
    st = id->decl_map;
--- 854,863 ----
       for the return statements within the function to jump to.  The
       type of the statement expression is the return type of the
       function call.  */
!   expr = build1 (STMT_EXPR, TREE_TYPE (TREE_TYPE (fn)), make_node (COMPOUND_STMT));
    /* There is no scope associated with the statement-expression.  */
    STMT_EXPR_NO_SCOPE (expr) = 1;
!   stmt = STMT_EXPR_STMT (expr);
    /* Local declarations will be replaced by their equivalents in this
       map.  */
    st = id->decl_map;
*************** expand_call_inline (tp, walk_subtrees, d
*** 871,877 ****
       parameters.  */
    expand_calls_inline (&arg_inits, id);
    /* And add them to the tree.  */
!   STMT_EXPR_STMT (expr) = chainon (STMT_EXPR_STMT (expr), arg_inits);
  
    /* Record the function we are about to inline so that we can avoid
       recursing into it.  */
--- 872,878 ----
       parameters.  */
    expand_calls_inline (&arg_inits, id);
    /* And add them to the tree.  */
!   COMPOUND_BODY (stmt) = chainon (COMPOUND_BODY (stmt), arg_inits);
  
    /* Record the function we are about to inline so that we can avoid
       recursing into it.  */
*************** expand_call_inline (tp, walk_subtrees, d
*** 906,913 ****
    SCOPE_BEGIN_P (scope_stmt) = 1;
    SCOPE_NO_CLEANUPS_P (scope_stmt) = 1;
    remap_block (scope_stmt, DECL_ARGUMENTS (fn), id);
!   TREE_CHAIN (scope_stmt) = STMT_EXPR_STMT (expr);
!   STMT_EXPR_STMT (expr) = scope_stmt;
  
    /* Tell the debugging backends that this block represents the
       outermost scope of the inlined function.  */
--- 907,914 ----
    SCOPE_BEGIN_P (scope_stmt) = 1;
    SCOPE_NO_CLEANUPS_P (scope_stmt) = 1;
    remap_block (scope_stmt, DECL_ARGUMENTS (fn), id);
!   TREE_CHAIN (scope_stmt) = COMPOUND_BODY (stmt);
!   COMPOUND_BODY (stmt) = scope_stmt;
  
    /* Tell the debugging backends that this block represents the
       outermost scope of the inlined function.  */
*************** expand_call_inline (tp, walk_subtrees, d
*** 915,948 ****
      BLOCK_ABSTRACT_ORIGIN (SCOPE_STMT_BLOCK (scope_stmt)) = DECL_ORIGIN (fn);
  
    /* Declare the return variable for the function.  */
!   STMT_EXPR_STMT (expr)
!     = chainon (STMT_EXPR_STMT (expr),
  	       declare_return_variable (id, &use_stmt));
  
    /* After we've initialized the parameters, we insert the body of the
       function itself.  */
!   inlined_body = &STMT_EXPR_STMT (expr);
    while (*inlined_body)
      inlined_body = &TREE_CHAIN (*inlined_body);
    *inlined_body = copy_body (id);
  
-   /* Close the block for the parameters.  */
-   scope_stmt = build_stmt (SCOPE_STMT, DECL_INITIAL (fn));
-   SCOPE_NO_CLEANUPS_P (scope_stmt) = 1;
-   remap_block (scope_stmt, NULL_TREE, id);
-   STMT_EXPR_STMT (expr)
-     = chainon (STMT_EXPR_STMT (expr), scope_stmt);
- 
    /* After the body of the function comes the RET_LABEL.  This must come
       before we evaluate the returned value below, because that evalulation
       may cause RTL to be generated.  */
!   STMT_EXPR_STMT (expr)
!     = chainon (STMT_EXPR_STMT (expr),
  	       build_stmt (LABEL_STMT, id->ret_label));
  
    /* Finally, mention the returned value so that the value of the
       statement-expression is the returned value of the function.  */
!   STMT_EXPR_STMT (expr) = chainon (STMT_EXPR_STMT (expr), use_stmt);
  
    /* Clean up.  */
    splay_tree_delete (id->decl_map);
--- 916,949 ----
      BLOCK_ABSTRACT_ORIGIN (SCOPE_STMT_BLOCK (scope_stmt)) = DECL_ORIGIN (fn);
  
    /* Declare the return variable for the function.  */
!   COMPOUND_BODY (stmt)
!     = chainon (COMPOUND_BODY (stmt),
  	       declare_return_variable (id, &use_stmt));
  
    /* After we've initialized the parameters, we insert the body of the
       function itself.  */
!   inlined_body = &COMPOUND_BODY (stmt);
    while (*inlined_body)
      inlined_body = &TREE_CHAIN (*inlined_body);
    *inlined_body = copy_body (id);
  
    /* After the body of the function comes the RET_LABEL.  This must come
       before we evaluate the returned value below, because that evalulation
       may cause RTL to be generated.  */
!   COMPOUND_BODY (stmt)
!     = chainon (COMPOUND_BODY (stmt),
  	       build_stmt (LABEL_STMT, id->ret_label));
  
    /* Finally, mention the returned value so that the value of the
       statement-expression is the returned value of the function.  */
!   COMPOUND_BODY (stmt) = chainon (COMPOUND_BODY (stmt), use_stmt);
!   
!   /* Close the block for the parameters.  */
!   scope_stmt = build_stmt (SCOPE_STMT, DECL_INITIAL (fn));
!   SCOPE_NO_CLEANUPS_P (scope_stmt) = 1;
!   remap_block (scope_stmt, NULL_TREE, id);
!   COMPOUND_BODY (stmt)
!     = chainon (COMPOUND_BODY (stmt), scope_stmt);
  
    /* Clean up.  */
    splay_tree_delete (id->decl_map);

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