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] PATCH to expand_expr:COND_EXPR


This patch is a simpler way to generate less RTL for the void COND_EXPRs in
GIMPLE.

We still emit unnecessary jumps for something like

if (a)
  goto b;

I tried expanding this as a conditional jump, but that breaks for gotos
that need some sort of fixup (nonlocal gotos, gotos that need to run C++
cleanups or restore the stack position).  Indeed, we don't want to convert
this to a conditional jump in such cases.  Darn implicit semantics...

Tested i686-pc-linux-gnu, applied to tree-ssa branch.

2003-06-01  Jason Merrill  <jason@redhat.com>

	* expr.c (expand_expr) <COND_EXPR>: Use the if-statement code if
	it's void.

*** expr.c.~1~	Tue May 27 18:38:25 2003
--- expr.c	Thu May 29 18:57:48 2003
*************** expand_expr (exp, target, tmode, modifie
*** 8805,8810 ****
--- 8805,8844 ----
  	                  modifier);
  
      case COND_EXPR:
+       /* If it's void, we don't need to worry about computing a value.  */
+       if (VOID_TYPE_P (TREE_TYPE (exp)))
+ 	{
+ 	  tree pred = TREE_OPERAND (exp, 0);
+ 	  tree then_ = TREE_OPERAND (exp, 1);
+ 	  tree else_ = TREE_OPERAND (exp, 2);
+ 
+ 	  /* Just use the 'if' machinery.  */
+ 	  expand_start_cond (pred, 0);
+ 	  start_cleanup_deferral ();
+ 	  expand_expr (then_, const0_rtx, VOIDmode, 0);
+ 
+ 	  exp = else_;
+ 
+ 	  /* Iterate over 'else if's instead of recursing.  */
+ 	  for (; TREE_CODE (exp) == COND_EXPR; exp = TREE_OPERAND (exp, 2))
+ 	    {
+ 	      expand_start_else ();
+ 	      if (TREE_LOCUS (exp))
+ 		emit_line_note (TREE_FILENAME (exp), TREE_LINENO (exp));
+ 	      expand_elseif (TREE_OPERAND (exp, 0));
+ 	      expand_expr (TREE_OPERAND (exp, 1), const0_rtx, VOIDmode, 0);
+ 	    }
+ 	  /* Don't emit the jump and label if there's no 'else' clause.  */
+ 	  if (TREE_SIDE_EFFECTS (exp))
+ 	    {
+ 	      expand_start_else ();
+ 	      expand_expr (exp, const0_rtx, VOIDmode, 0);
+ 	    }
+ 	  end_cleanup_deferral ();
+ 	  expand_end_cond ();
+ 	  return const0_rtx;
+ 	}
+ 
        /* If we would have a "singleton" (see below) were it not for a
  	 conversion in each arm, bring that conversion back out.  */
        if (TREE_CODE (TREE_OPERAND (exp, 1)) == NOP_EXPR
*************** expand_expr (exp, target, tmode, modifie
*** 9061,9144 ****
  	  }
  	else
  	  {
! 	    /* This used heavily by gimplified code, so it's worth
! 	       trying to be semi-intelligent about the code we generate.   */
! 
! 	    /* Expand the condition and jump around THEN clause if the
! 	       condition does not hold.
  
! 	       However, if the THEN clause is empty, then jump around
! 	       the ELSE clause if the condition does hold.
  
! 	       If both the THEN and the ELSE are empty, then just emit
! 	       the condition (in case it had embedded side effects).  */
! 	    if (! IS_EMPTY_STMT (TREE_OPERAND (exp, 1)))
! 	      jumpifnot (TREE_OPERAND (exp, 0), op0);
! 	    else if (! IS_EMPTY_STMT (TREE_OPERAND (exp, 2)))
! 	      {
! 	        op1 = gen_label_rtx ();
! 	        jumpif (TREE_OPERAND (exp, 0), op1);
! 	      }
  	    else
! 	      expand_expr (TREE_OPERAND (exp, 0), 
  			   ignore ? const0_rtx : NULL_RTX, VOIDmode, 0);
- 	      
- 	    /* Generate RTL for the THEN clause if it is not empty.  */
- 	    if (! IS_EMPTY_STMT (TREE_OPERAND (exp, 1)))
- 	      {
- 		start_cleanup_deferral ();
- 
- 		/* One branch of the cond can be void, if it never returns. For
- 		   example A ? throw : E  */
- 		if (temp != 0
- 		    && TREE_TYPE (TREE_OPERAND (exp, 1)) != void_type_node)
- 		  store_expr (TREE_OPERAND (exp, 1), temp,
- 			      modifier == EXPAND_STACK_PARM ? 2 : 0);
- 		else
- 		  expand_expr (TREE_OPERAND (exp, 1),
- 			       ignore ? const0_rtx : NULL_RTX, VOIDmode, 0);
- 		end_cleanup_deferral ();
- 		emit_queue ();
- 
- 		/* If the ELSE clause was not empty, then we need to
- 		   jump around it.  */
- 		if (! IS_EMPTY_STMT (TREE_OPERAND (exp, 2)))
- 		  {
- 		    op1 = gen_label_rtx ();
- 		    emit_jump_insn (gen_jump (op1));
- 		    emit_barrier ();
- 		  }
- 
- 		/* This is the target of the jump around the THEN block.  */
- 		emit_label (op0);
- 	      }
- 
- 	    /* Generate RTL for the ELSE clause if it is not empty.  */
- 	    if (! IS_EMPTY_STMT (TREE_OPERAND (exp, 2)))
- 	      {
- 		start_cleanup_deferral ();
- 
- 		if (temp != 0
- 		    && TREE_TYPE (TREE_OPERAND (exp, 2)) != void_type_node)
- 		  store_expr (TREE_OPERAND (exp, 2), temp,
- 			      modifier == EXPAND_STACK_PARM ? 2 : 0);
- 		else
- 		  expand_expr (TREE_OPERAND (exp, 2),
- 			       ignore ? const0_rtx : NULL_RTX, VOIDmode, 0);
- 
- 		end_cleanup_deferral ();
-  
- 	        emit_queue ();
- 		emit_label (op1);
- 	      }
- 	    OK_DEFER_POP;
- 	    return temp;
  	  }
  
- 	/* We fall into this path from earlier in the COND_EXPR case, so this
- 	   can not be pulled up into the trailing else clause.  */
  	end_cleanup_deferral ();
!  
  	emit_queue ();
  	emit_label (op1);
  	OK_DEFER_POP;
--- 9095,9131 ----
  	  }
  	else
  	  {
! 	    op1 = gen_label_rtx ();
! 	    jumpifnot (TREE_OPERAND (exp, 0), op0);
  
! 	    start_cleanup_deferral ();
  
! 	    /* One branch of the cond can be void, if it never returns. For
! 	       example A ? throw : E  */
! 	    if (temp != 0
! 		&& TREE_TYPE (TREE_OPERAND (exp, 1)) != void_type_node)
! 	      store_expr (TREE_OPERAND (exp, 1), temp,
! 			  modifier == EXPAND_STACK_PARM ? 2 : 0);
  	    else
! 	      expand_expr (TREE_OPERAND (exp, 1),
! 			   ignore ? const0_rtx : NULL_RTX, VOIDmode, 0);
! 	    end_cleanup_deferral ();
! 	    emit_queue ();
! 	    emit_jump_insn (gen_jump (op1));
! 	    emit_barrier ();
! 	    emit_label (op0);
! 	    start_cleanup_deferral ();
! 	    if (temp != 0
! 		&& TREE_TYPE (TREE_OPERAND (exp, 2)) != void_type_node)
! 	      store_expr (TREE_OPERAND (exp, 2), temp,
! 			  modifier == EXPAND_STACK_PARM ? 2 : 0);
! 	    else
! 	      expand_expr (TREE_OPERAND (exp, 2),
  			   ignore ? const0_rtx : NULL_RTX, VOIDmode, 0);
  	  }
  
  	end_cleanup_deferral ();
! 
  	emit_queue ();
  	emit_label (op1);
  	OK_DEFER_POP;

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