From: Jason Merrill Date: Wed, 28 Aug 2002 21:17:12 +0000 (-0400) Subject: c-common.c (c_expand_expr): If the last expression is a VAR_DECL with RTL that matche... X-Git-Tag: releases/gcc-3.2.1~347 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3abbc7e74bf54e187bd143ce2457262140df4b71;p=thirdparty%2Fgcc.git c-common.c (c_expand_expr): If the last expression is a VAR_DECL with RTL that matches the target... * 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. * tree-inline.c (expand_call_inline): Make the statement expression we generate have a COMPOUND_STMT. From-SVN: r56645 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4bd213dc7cc8..9736f4da9f69 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2002-08-28 Jason Merrill + + * 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-08-28 Daniel Berlin + + * tree-inline.c (expand_call_inline): Make the statement + expression we generate have a COMPOUND_STMT. + 2002-08-27 Mark Mitchell * doc/invoke.texi: Document -Wabi. diff --git a/gcc/c-common.c b/gcc/c-common.c index f9e593057a9b..066cb7c04c8e 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -3564,6 +3564,7 @@ c_expand_expr (exp, target, tmode, modifier) 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. @@ -3591,8 +3592,20 @@ c_expand_expr (exp, target, tmode, modifier) if (TREE_CODE (last) == SCOPE_STMT && TREE_CODE (expr) == EXPR_STMT) { - TREE_ADDRESSABLE (expr) = 1; - preserve_result = true; + 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; + } } } @@ -3600,7 +3613,9 @@ c_expand_expr (exp, target, tmode, modifier) expand_end_stmt_expr (rtl_expr); result = expand_expr (rtl_expr, target, tmode, modifier); - if (preserve_result && GET_CODE (result) == MEM) + if (return_target) + result = target; + else if (preserve_result && GET_CODE (result) == MEM) { if (GET_MODE (result) != BLKmode) result = copy_to_reg (result); diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 5aa141ad4f91..79f4c52f0b40 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -762,6 +762,7 @@ expand_call_inline (tp, walk_subtrees, data) inline_data *id; tree t; tree expr; + tree stmt; tree chain; tree fn; tree scope_stmt; @@ -853,10 +854,10 @@ expand_call_inline (tp, walk_subtrees, data) 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); + 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; @@ -871,7 +872,7 @@ expand_call_inline (tp, walk_subtrees, data) parameters. */ expand_calls_inline (&arg_inits, id); /* And add them to the tree. */ - STMT_EXPR_STMT (expr) = chainon (STMT_EXPR_STMT (expr), arg_inits); + 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. */ @@ -906,8 +907,8 @@ expand_call_inline (tp, walk_subtrees, data) 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; + 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. */ @@ -915,34 +916,34 @@ expand_call_inline (tp, walk_subtrees, data) 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), + 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 = &STMT_EXPR_STMT (expr); + inlined_body = &COMPOUND_BODY (stmt); 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), + 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. */ - STMT_EXPR_STMT (expr) = chainon (STMT_EXPR_STMT (expr), use_stmt); + 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);