[tree-ssa] More COND_EXPR improvements

law@redhat.com law@redhat.com
Tue Jul 1 19:48:00 GMT 2003


This integrates Jason's work to improve COND_EXPR expansion.  It picks
up a couple hundred more optimizable cases in my tests.  It also attempts
to deal with saved stack positions.

This has gone through the usual tests.

	* expr.c (expand_expr, case COND_EXPR): Correctly (?) handle
	cases where a containing block has a stack level.  Handle
	cases where one arm is a GOTO_EXPR and the other arm has
	side effects.

	* stmt.c (containing_blocks_have_cleanups_or_stack_level): New
	function.
	(any_pending_cleanups): Further simplification.
	* tree.h (containing_blocks_have_cleanups_or_stack_level): Prototype.

Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.467.2.36
diff -c -3 -p -r1.467.2.36 expr.c
*** expr.c	1 Jul 2003 02:04:50 -0000	1.467.2.36
--- expr.c	1 Jul 2003 17:52:17 -0000
*************** expand_expr (exp, target, tmode, modifie
*** 8814,8842 ****
  	  tree then_ = TREE_OPERAND (exp, 1);
  	  tree else_ = TREE_OPERAND (exp, 2);
  
! 	  /* If the conditional has only one useful arm and that arm is an
! 	     unconditional jump to a local label and we have no pending
! 	     cleanups, then we can simplify the resulting INSN stream
! 	     by using jumpif/jumpifnot.  */
! 	  if (optimize > 0
! 	      && TREE_CODE (then_) == GOTO_EXPR
! 	      && TREE_CODE (GOTO_DESTINATION (then_)) == LABEL_DECL
! 	      && ! NONLOCAL_LABEL (GOTO_DESTINATION (then_))
! 	      && ! TREE_SIDE_EFFECTS (else_)
! 	      && ! any_pending_cleanups ())
  	    {
  	      jumpif (pred, label_rtx (GOTO_DESTINATION (then_)));
! 	      return const0_rtx;
  	    }
! 	  else if (optimize > 0
! 		   && TREE_CODE (else_) == GOTO_EXPR
  		   && TREE_CODE (GOTO_DESTINATION (else_)) == LABEL_DECL
! 		   && ! NONLOCAL_LABEL (GOTO_DESTINATION (else_))
! 		   && ! TREE_SIDE_EFFECTS (then_)
! 		   && ! any_pending_cleanups ())
  	    {
  	      jumpifnot (pred, label_rtx (GOTO_DESTINATION (else_)));
! 	      return const0_rtx;
  	    }
  
  	  /* Just use the 'if' machinery.  */
--- 8814,8839 ----
  	  tree then_ = TREE_OPERAND (exp, 1);
  	  tree else_ = TREE_OPERAND (exp, 2);
  
! 	  /* If we do not have any pending cleanups or stack_levels
! 	     to restore, and at least one arm of the COND_EXPR is a
! 	     GOTO_EXPR to a local label, then we can emit more efficient
! 	     code by using jumpif/jumpifnot instead of the 'if' machinery.  */
! 	  if (! optimize
! 	      || containing_blocks_have_cleanups_or_stack_level ())
! 	    ;
! 	  else if (TREE_CODE (then_) == GOTO_EXPR
! 		   && TREE_CODE (GOTO_DESTINATION (then_)) == LABEL_DECL
! 		   && ! NONLOCAL_LABEL (GOTO_DESTINATION (then_)))
  	    {
  	      jumpif (pred, label_rtx (GOTO_DESTINATION (then_)));
! 	      return expand_expr (else_, const0_rtx, VOIDmode, 0);
  	    }
! 	  else if (TREE_CODE (else_) == GOTO_EXPR
  		   && TREE_CODE (GOTO_DESTINATION (else_)) == LABEL_DECL
! 		   && ! NONLOCAL_LABEL (GOTO_DESTINATION (else_)))
  	    {
  	      jumpifnot (pred, label_rtx (GOTO_DESTINATION (else_)));
! 	      return expand_expr (then_, const0_rtx, VOIDmode, 0);
  	    }
  
  	  /* Just use the 'if' machinery.  */
Index: stmt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/stmt.c,v
retrieving revision 1.267.2.21
diff -c -3 -p -r1.267.2.21 stmt.c
*** stmt.c	1 Jul 2003 02:04:51 -0000	1.267.2.21
--- stmt.c	1 Jul 2003 17:52:41 -0000
*************** last_cleanup_this_contour ()
*** 4448,4453 ****
--- 4448,4470 ----
    return block_stack->data.block.cleanups;
  }
  
+ 
+ /* Return nonzero if any containing block has a stack level or
+    cleanups.  */
+ 
+ int
+ containing_blocks_have_cleanups_or_stack_level ()
+ {
+   struct nesting *block;
+ 
+   for (block = block_stack; block; block = block->next)
+     if (block->data.block.stack_level != 0
+         || block->data.block.cleanups != 0)
+       return 1;
+ 
+   return 0;
+ }
+ 
  /* Return 1 if there are any pending cleanups at this point.
     Check the current contour as well as contours that enclose
     the current contour.  */
*************** any_pending_cleanups ()
*** 4462,4469 ****
  
    if (block_stack->data.block.cleanups != NULL)
      return 1;
!   if (block_stack->data.block.cleanups == 0
!       && block_stack->data.block.outer_cleanups == 0)
      return 0;
  
    for (block = block_stack->next; block; block = block->next)
--- 4479,4486 ----
  
    if (block_stack->data.block.cleanups != NULL)
      return 1;
! 
!   if (block_stack->data.block.outer_cleanups == 0)
      return 0;
  
    for (block = block_stack->next; block; block = block->next)
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.342.2.72
diff -c -3 -p -r1.342.2.72 tree.h
*** tree.h	1 Jul 2003 04:04:32 -0000	1.342.2.72
--- tree.h	1 Jul 2003 17:53:42 -0000
*************** extern void expand_asm_expr		PARAMS ((tr
*** 3274,3279 ****
--- 3274,3280 ----
  extern bool asm_op_is_mem_input (tree, tree);
  extern tree resolve_asm_operand_names (tree, tree, tree);
  extern int any_pending_cleanups		PARAMS ((void));
+ extern int containing_blocks_have_cleanups_or_stack_level PARAMS ((void));
  extern void init_stmt_for_function	PARAMS ((void));
  extern void expand_start_target_temps	PARAMS ((void));
  extern void expand_end_target_temps	PARAMS ((void));




More information about the Gcc-patches mailing list