[PATCH]: Make tree-inlining generate a valid statement expression
Daniel Berlin
dberlin@dberlin.org
Wed May 29 20:55:00 GMT 2002
I posted this patch before, but it was right around the 3.1 release, so
it probably got lost in the noise.
The statement expressions tree-inlining makes when doing it's thang are
invalid.
They aren't wrapped in a compound statement, as they should be (according
to the manual, and code that seems to depend on this).
I'm actually surprised this doesn't cause us pessimizations, since there
is code that depends on STMT_EXPR_STMT being a COMPOUND_STMT when trying
to preserve the result that it returns (see c_expand_expr).
This patch has been bootstrapped and regtested on i686, and is already
existing and bootstrapping/regtesting fine on the ast-optimizer-branch.
(The patch does less than it looks like, it moves the code around
slightly so we close the scope in the right place for the compound stmt).
2002-05-29 Daniel Berlin <dberlin@dberlin.org>
* tree-inline.c (expand_call_inline): Make the statement
expression we generate have a COMPOUND_STMT.
Index: tree-inline.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-inline.c,v
retrieving revision 1.23
diff -c -3 -p -w -B -b -r1.23 tree-inline.c
*** tree-inline.c 18 May 2002 15:16:25 -0000 1.23
--- tree-inline.c 30 May 2002 02:30:06 -0000
*************** expand_call_inline (tp, walk_subtrees, d
*** 782,787 ****
--- 782,788 ----
inline_data *id;
tree t;
tree expr;
+ tree stmt;
tree chain;
tree fn;
tree scope_stmt;
*************** expand_call_inline (tp, walk_subtrees, d
*** 873,882 ****
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;
--- 874,883 ----
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
*** 891,897 ****
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. */
--- 892,898 ----
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
*** 926,933 ****
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. */
--- 927,934 ----
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
*** 935,968 ****
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);
--- 936,969 ----
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);
More information about the Gcc-patches
mailing list