[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