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 gimplify_boolean_expr


While testing my patch to always evaluate complex expressions into formal
temps, I ran into a new failure on gcc.dg/tree-ssa/20030728-1.c because the
generated gimple code changed from

  T1 = (foo == bar);
  if (T1)
    ...

to

  T1 = (foo == bar);   // formal temp
  T2 = T1;             // variable temp
  if (T2)
    ...

dom provided constant defs of T2 within the branches, but ccp replaced uses
of T2 with T1, so we didn't see them.

One fix for this is to move the comparison directly into the condition,
i.e.

if (foo == bar)
  T1 = true;
  ...
  
which seems to be roughly what the expander does.  This also dramatically
simplifies gimplify_boolean_expr; now we can just hand off to the code in
shortcut_cond_expr.

Another fix is to teach dom to propagate conditional information back up
the def chain; I'll have a preliminary patch for that shortly.

Another fix would be to delay copy prop until out-of-ssa time, as Morgan
does.

This seems to shave 0.6% off bootstrap time and 0.8% off testrun time.

Tested athlon-pc-linux-gnu, applied to tree-ssa.

2003-08-25  Jason Merrill  <jason@redhat.com>

	* gimplify.c (gimplify_boolean_expr): Just replace with a COND_EXPR.

*** gimplify.c.~1~	2003-08-22 16:33:13.000000000 -0400
--- gimplify.c	2003-08-25 02:05:29.000000000 -0400
*************** static void gimplify_save_expr (tree *, 
*** 53,59 ****
  static void gimplify_addr_expr (tree *, tree *, tree *);
  static void gimplify_self_mod_expr (tree *, tree *, tree *, int);
  static void gimplify_cond_expr (tree *, tree *, tree);
! static void gimplify_boolean_expr (tree *, tree *);
  static void gimplify_return_expr (tree, tree *);
  static tree build_addr_expr (tree);
  static tree build_addr_expr_with_type (tree, tree);
--- 53,59 ----
  static void gimplify_addr_expr (tree *, tree *, tree *);
  static void gimplify_self_mod_expr (tree *, tree *, tree *, int);
  static void gimplify_cond_expr (tree *, tree *, tree);
! static void gimplify_boolean_expr (tree *);
  static void gimplify_return_expr (tree, tree *);
  static tree build_addr_expr (tree);
  static tree build_addr_expr_with_type (tree, tree);
*************** gimplify_expr (tree *expr_p, tree *pre_p
*** 444,450 ****
  
  	case TRUTH_ANDIF_EXPR:
  	case TRUTH_ORIF_EXPR:
! 	  gimplify_boolean_expr (expr_p, pre_p);
  	  break;
  
  	case TRUTH_NOT_EXPR:
--- 444,450 ----
  
  	case TRUTH_ANDIF_EXPR:
  	case TRUTH_ORIF_EXPR:
! 	  gimplify_boolean_expr (expr_p);
  	  break;
  
  	case TRUTH_NOT_EXPR:
*************** gimplify_modify_expr (tree *expr_p, tree
*** 2029,2097 ****
  
      Expressions of the form 'a && b' are gimplified to:
  
! 	T = a;
! 	if (T)
! 	  T = b;
  
!     Expressions of the form 'a || b' are gimplified to:
! 
! 	T = a;
! 	if (!T)
! 	  T = b;
! 
!     In both cases, the expression is re-written as 'T != 0'.
  
      PRE_P points to the list where side effects that must happen before
- 	*EXPR_P should be stored.
- 
-     POST_P points to the list where side effects that must happen after
          *EXPR_P should be stored.  */
  
  static void
! gimplify_boolean_expr (tree *expr_p, tree *pre_p)
  {
!   tree t, lhs, rhs, if_body, if_cond, if_stmt;
! 
!   enum tree_code code = TREE_CODE (*expr_p);
! 
! #if defined ENABLE_CHECKING
!   if (code != TRUTH_ANDIF_EXPR && code != TRUTH_ORIF_EXPR)
!     abort ();
! #endif
! 
!   /* Make this expression right-associative so that gimplification will
!      produce nested ifs.  */
!   *expr_p = right_assocify_expr (*expr_p);
! 
!   /* First, make sure that our operands have boolean type.  */
!   lhs = gimple_boolify (TREE_OPERAND (*expr_p, 0));
!   rhs = gimple_boolify (TREE_OPERAND (*expr_p, 1));
! 
!   /* Build 'T = a'  */
!   t = get_initialized_tmp_var (lhs, pre_p);
! 
!   /* Build the body for the if() statement that conditionally evaluates the
!      RHS of the expression.  */
!   if_body = build (MODIFY_EXPR, TREE_TYPE (t), t, rhs);
! 
!   /* Build the condition.  */
!   if (code == TRUTH_ANDIF_EXPR)
!     if_cond = t;
!   else
!     if_cond = build1 (TRUTH_NOT_EXPR, TREE_TYPE (t), t);
! 
!   if_stmt = build (COND_EXPR, void_type_node, if_cond, if_body,
! 		   build_empty_stmt ());
!   /* Gimplify the IF_STMT and insert it in the PRE_P chain.  */
!   gimplify_stmt (&if_stmt);
!   add_tree (if_stmt, pre_p);
! 
!   /* If we're not actually looking for a boolean result, convert now.  */
!   if (TREE_TYPE (t) != TREE_TYPE (*expr_p))
!     t = convert (TREE_TYPE (*expr_p), t);
! 
!   /* Re-write the original expression to use T.  */
!   *expr_p = t;
  }
  
  
--- 2020,2040 ----
  
      Expressions of the form 'a && b' are gimplified to:
  
!         a && b ? true : false
  
!     gimplify_cond_expr will do the rest.
  
      PRE_P points to the list where side effects that must happen before
          *EXPR_P should be stored.  */
  
  static void
! gimplify_boolean_expr (tree *expr_p)
  {
!   /* Preserve the original type of the expression.  */
!   tree type = TREE_TYPE (*expr_p);
!   *expr_p = build (COND_EXPR, type, *expr_p,
! 		   convert (type, boolean_true_node),
! 		   convert (type, boolean_false_node));
  }
  
  

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