This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
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);