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]

[tree-ssa] notice alloca/setjmp calls early enough


Hi,
this patch makes current_function_calls_alloca and
current_function_calls_setjmp to be computed before CFG construction and to be
updated by dead code removal pass.  I am using in by tail call marking pass I
would like to send next and I also plan to modify CFG builder to create edge
from function call to instruction after setjmp so we don't have it special case
all the time.

In my tree this needs to be in sync with RTL scheme and thus needs some work I
would like to delay a bit to avoid too many dependencies.

BTW the calls.c ECF_MAY_BE_ALLOCA seem to be overly aggressive.  I think all it
needs is to check for BUILTIN_ALLOCA, as library alloca implementation must use
malloc+garbatge collecting anyway...  Is this right?

Honza

	* tree-cfg.c (notice_special_calls, clear_special_calls): New.
	(remove_useless_stmts_and_vars_1): Use notice_special_calls.
	(remove_useless_stmts_and_vars): clear_special_calls.
	* tree-flow.h (notice_special_calls, clear_special_calls): New.
	* tree-ssa-dce.c (remove_dead_stmts): Recompute flags.

Index: tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-cfg.c,v
retrieving revision 1.1.4.199
diff -c -3 -p -r1.1.4.199 tree-cfg.c
*** tree-cfg.c	8 Nov 2003 09:49:19 -0000	1.1.4.199
--- tree-cfg.c	8 Nov 2003 17:02:13 -0000
*************** clear_blocks_annotations (void)
*** 385,390 ****
--- 386,414 ----
      bb->tree_annotations = NULL;
  }
  
+ /* t is CALL_EXPR.  Set current_function_calls_* flags.  */
+ void
+ notice_special_calls (tree t)
+ {
+   int flags;
+   if (TREE_CODE (t) != CALL_EXPR)
+     abort ();
+   flags = call_expr_flags (t);
+   if (flags & ECF_MAY_BE_ALLOCA)
+     current_function_calls_alloca = true;
+   if (flags & ECF_RETURNS_TWICE)
+     current_function_calls_setjmp = true;
+ }
+ 
+ /* Clear flags set by notice_special_calls.  Used by dead code removal
+    to update the flags.  */
+ void
+ clear_special_calls (void)
+ {
+   current_function_calls_alloca = false;
+   current_function_calls_setjmp = false;
+ }
+ 
  /* Build a flowgraph for the statements starting at the statement pointed
     by FIRST_P.
  
*************** remove_useless_stmts_and_vars_1 (tree *f
*** 1233,1240 ****
  	case RETURN_EXPR:
  	  data->may_branch = true;
  	  break;
- 	case MODIFY_EXPR:
  	case CALL_EXPR:
  	  if (tree_could_throw_p (*stmt_p))
  	    data->may_throw = true;
  	  break;
--- 1258,1271 ----
  	case RETURN_EXPR:
  	  data->may_branch = true;
  	  break;
  	case CALL_EXPR:
+ 	  notice_special_calls (*stmt_p);
+ 	  if (tree_could_throw_p (*stmt_p))
+ 	    data->may_throw = true;
+ 	  break;
+ 	case MODIFY_EXPR:
+ 	  if (TREE_CODE (TREE_OPERAND (*stmt_p, 1)) == CALL_EXPR)
+ 	    notice_special_calls (TREE_OPERAND (*stmt_p, 1));
  	  if (tree_could_throw_p (*stmt_p))
  	    data->may_throw = true;
  	  break;
*************** void
*** 1254,1259 ****
--- 1285,1293 ----
  remove_useless_stmts_and_vars (tree *first_p, bool remove_unused_vars)
  {
    struct rusv_data data;
+ 
+   clear_special_calls ();
+ 
    do
      {
        memset (&data, 0, sizeof (data));
Index: tree-flow.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow.h,v
retrieving revision 1.1.4.142
diff -c -3 -p -r1.1.4.142 tree-flow.h
*** tree-flow.h	8 Nov 2003 09:49:19 -0000	1.1.4.142
--- tree-flow.h	8 Nov 2003 17:02:27 -0000
*************** extern edge thread_edge (edge, basic_blo
*** 459,467 ****
  extern basic_block label_to_block (tree);
  extern bool cleanup_cond_expr_graph (basic_block, block_stmt_iterator);
  extern bool cleanup_switch_expr_graph (basic_block, block_stmt_iterator);
  extern void tree_optimize_tail_calls (void);
  extern basic_block tree_block_forwards_to (basic_block bb);
  extern void dump_cfg_function_to_file (tree, FILE *, int);
  
  /* In tree-dfa.c  */
  void find_referenced_vars (tree);
--- 459,470 ----
  extern basic_block label_to_block (tree);
  extern bool cleanup_cond_expr_graph (basic_block, block_stmt_iterator);
  extern bool cleanup_switch_expr_graph (basic_block, block_stmt_iterator);
  extern void tree_optimize_tail_calls (void);
  extern basic_block tree_block_forwards_to (basic_block bb);
  extern void dump_cfg_function_to_file (tree, FILE *, int);
+ extern void tree_expand_cfg (void);
+ extern void notice_special_calls (tree);
+ extern void clear_special_calls (void);
  
  /* In tree-dfa.c  */
  void find_referenced_vars (tree);
Index: tree-ssa-dce.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-dce.c,v
retrieving revision 1.1.2.64
diff -c -3 -p -r1.1.2.64 tree-ssa-dce.c
*** tree-ssa-dce.c	5 Nov 2003 13:39:23 -0000	1.1.2.64
--- tree-ssa-dce.c	8 Nov 2003 17:02:53 -0000
*************** remove_dead_stmts (void)
*** 395,400 ****
--- 413,419 ----
    tree t;
    block_stmt_iterator i;
  
+   clear_special_calls ();
    FOR_EACH_BB_REVERSE (bb)
      {
        bsi_list_p stack;
*************** remove_dead_stmts (void)
*** 410,415 ****
--- 429,439 ----
  	  /* If `i' is not in `necessary' then remove from B.  */
  	  if (!necessary_p (t))
  	    remove_dead_stmt (&i);
+ 	  else if (TREE_CODE (t) == CALL_EXPR)
+ 	    notice_special_calls (t);
+ 	  else if (TREE_CODE (t) == MODIFY_EXPR
+ 		   && TREE_CODE (TREE_OPERAND (t, 1)) == CALL_EXPR)
+ 	    notice_special_calls (TREE_OPERAND (t, 1));
  	}
      }
  }


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