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 shortcut_cond_expr


This patch turns

if (a || b)
  goto c;

into

if (a)
  goto c;
if (b)
  goto c;

rather than

if (a)
  goto d;
if (b)
  goto d;
goto e;
d: goto c;
e:

This doesn't get rid of all the jumps to jumps, but it's a definite
improvement.

Booted and tested athlon-pc-linux-gnu, applied to tree-ssa.

2003-05-27  Jason Merrill  <jason@redhat.com>

	* gimplify.c (shortcut_cond_expr): Avoid jumps to jumps.

*** gimplify.c.~1~	Sat May 24 03:35:19 2003
--- gimplify.c	Tue May 27 10:14:13 2003
*************** shortcut_cond_expr (tree expr)
*** 1522,1529 ****
    tree pred = TREE_OPERAND (expr, 0);
    tree then_ = TREE_OPERAND (expr, 1);
    tree else_ = TREE_OPERAND (expr, 2);
!   tree false_label, end_label;
!   bool emit_end;
  
    /* First do simple transformations.  */
    if (!TREE_SIDE_EFFECTS (else_))
--- 1522,1532 ----
    tree pred = TREE_OPERAND (expr, 0);
    tree then_ = TREE_OPERAND (expr, 1);
    tree else_ = TREE_OPERAND (expr, 2);
!   tree true_label, false_label, end_label;
!   tree *true_label_p;
!   tree *false_label_p;
!   bool emit_end, emit_false;
!   tree_stmt_iterator si;
  
    /* First do simple transformations.  */
    if (!TREE_SIDE_EFFECTS (else_))
*************** shortcut_cond_expr (tree expr)
*** 1567,1601 ****
         no: d; end:
       and recursively simplify the condition.  */
  
!   false_label = end_label = NULL_TREE;
!   emit_end = true;  
  
!   /* If our subexpression already has a terminal label, reuse it.  */
    if (TREE_SIDE_EFFECTS (else_))
      expr = expr_last (else_);
    else
      expr = expr_last (then_);
    if (TREE_CODE (expr) == LABEL_EXPR)
!     {
!       emit_end = false;
!       end_label = LABEL_EXPR_LABEL (expr);
!       if (!TREE_SIDE_EFFECTS (else_))
! 	false_label = end_label;
!     }
  
!   expr = shortcut_cond_r (pred, NULL, &false_label);
  
    add_tree (then_, &expr);
    if (TREE_SIDE_EFFECTS (else_))
      {
        add_tree (build_and_jump (&end_label), &expr);
!       add_tree (build1 (LABEL_EXPR, void_type_node, false_label), &expr);
        add_tree (else_, &expr);
      }
!   else
!     end_label = false_label;
! 
!   if (emit_end)
      add_tree (build1 (LABEL_EXPR, void_type_node, end_label), &expr);
  
    return expr;
--- 1570,1640 ----
         no: d; end:
       and recursively simplify the condition.  */
  
!   true_label = false_label = end_label = NULL_TREE;
  
!   /* If our arms just jump somewhere, hijack those labels so we don't
!      generate jumps to jumps.  */
!   si = tsi_start (&then_);
!   expr = tsi_stmt (si);
!   if (TREE_CODE (expr) == GOTO_EXPR
!       && TREE_CODE (GOTO_DESTINATION (expr)) == LABEL_DECL)
!     {
!       true_label = GOTO_DESTINATION (expr);
!       tsi_delink (&si);
!     }
!   si = tsi_start (&else_);
!   expr = tsi_stmt (si);
!   if (TREE_CODE (expr) == GOTO_EXPR
!       && TREE_CODE (GOTO_DESTINATION (expr)) == LABEL_DECL)
!     {
!       false_label = GOTO_DESTINATION (expr);
!       tsi_delink (&si);
!     }
! 
!   /* If we aren't hijacking a label for the 'then' branch, it falls through. */
!   if (true_label)
!     true_label_p = &true_label;
!   else
!     true_label_p = NULL;
! 
!   /* The 'else' branch also needs a label if it contains interesting code.  */
!   if (false_label || TREE_SIDE_EFFECTS (else_))
!     false_label_p = &false_label;
!   else
!     false_label_p = NULL;
! 
!   /* If there was nothing else in our arms, just forward the label(s).  */
!   if (!TREE_SIDE_EFFECTS (then_) && !TREE_SIDE_EFFECTS (else_))
!     return shortcut_cond_r (pred, true_label_p, false_label_p);
! 
!   /* If our last subexpression already has a terminal label, reuse it.  */
    if (TREE_SIDE_EFFECTS (else_))
      expr = expr_last (else_);
    else
      expr = expr_last (then_);
    if (TREE_CODE (expr) == LABEL_EXPR)
!     end_label = LABEL_EXPR_LABEL (expr);
  
!   /* If we don't care about jumping to the 'else' branch, jump to the end
!      if the condition is false.  */
!   if (!false_label_p)
!     false_label_p = &end_label;
! 
!   /* We only want to emit these labels if we aren't hijacking them.  */
!   emit_end = (end_label == NULL_TREE);
!   emit_false = (false_label == NULL_TREE);
! 
!   expr = shortcut_cond_r (pred, true_label_p, false_label_p);
  
    add_tree (then_, &expr);
    if (TREE_SIDE_EFFECTS (else_))
      {
        add_tree (build_and_jump (&end_label), &expr);
!       if (emit_false)
! 	add_tree (build1 (LABEL_EXPR, void_type_node, false_label), &expr);
        add_tree (else_, &expr);
      }
!   if (emit_end && end_label)
      add_tree (build1 (LABEL_EXPR, void_type_node, end_label), &expr);
  
    return expr;

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