This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[tree-ssa] PATCH to shortcut_cond_expr
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 27 May 2003 18:48:31 -0400
- Subject: [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;