This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[tuples] Avoid generating too much garbage in gimplify_cond_expr (PR tree-optimization/36389)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Diego Novillo <dnovillo at google dot com>, Aldy Hernandez <aldyh at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Sat, 31 May 2008 18:10:32 -0400
- Subject: [tuples] Avoid generating too much garbage in gimplify_cond_expr (PR tree-optimization/36389)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
On the tuples branch gimplify_cond_expr generates horrible code
when one or both of the arms is GOTO_EXPR LABEL_DECL, or
one of the arms is NULL. Fixed by the following patch.
The tree-eh.c and tree-cfg.c hunks fix regressions the gimplify.c
change caused. replace_goto_queue_cond_clause would pass
LABEL_EXPR down to gimple_build_label (label) which of course
ICEs, as gimple_build_label expects a LABEL_DECL. And,
the arms of a GOTO_COND can contain branches which escape a try_finally
block (the tree-cfg.c hunk fixes cleanup-4.c and goto1.C failures).
Bootstrapped/regtested on x86_64-linux, ok for tuples?
2008-05-31 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/36389
* gimplify.c (gimplify_cond_expr): If one or both branches are
GOTO_EXPRs jumping to LABEL_DECLs, don't create unnecessary
extra LABEL_DECLs and jumps around.
* tree-cfg.c (remove_useless_stmts_cond): Set may_branch also
for GIMPLE_COND stmts.
* tree-eh.c (replace_goto_queue_cond_clause): Set label to
create_artificial_label () rather than LABEL_EXPR.
--- gcc/tree-cfg.c.jj 2008-05-28 09:17:31.000000000 +0200
+++ gcc/tree-cfg.c 2008-05-31 21:53:58.000000000 +0200
@@ -1558,6 +1558,8 @@ remove_useless_stmts_cond (gimple_stmt_i
/* The folded result must still be a conditional statement. */
fold_stmt_inplace (stmt);
+ data->may_branch = true;
+
/* Attempt to evaluate the condition at compile-time.
Because we are in GIMPLE here, only the most trivial
comparisons of a constant to a constant can be handled.
--- gcc/tree-eh.c.jj 2008-05-27 14:34:52.000000000 +0200
+++ gcc/tree-eh.c 2008-05-31 18:44:54.000000000 +0200
@@ -496,7 +496,7 @@ replace_goto_queue_cond_clause (tree *tp
return;
}
- label = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
+ label = create_artificial_label ();
/* Set the new label for the GIMPLE_COND */
*tp = label;
--- gcc/gimplify.c.jj 2008-05-30 13:29:15.000000000 +0200
+++ gcc/gimplify.c 2008-05-31 21:32:16.000000000 +0200
@@ -2923,8 +2923,29 @@ gimplify_cond_expr (tree *expr_p, gimple
gimple_push_condition ();
- label_true = create_artificial_label ();
- label_false = create_artificial_label ();
+ have_then_clause_p = have_else_clause_p = false;
+ if (TREE_OPERAND (expr, 1) != NULL
+ && TREE_CODE (TREE_OPERAND (expr, 1)) == GOTO_EXPR
+ && TREE_CODE (GOTO_DESTINATION (TREE_OPERAND (expr, 1))) == LABEL_DECL
+ && (DECL_CONTEXT (GOTO_DESTINATION (TREE_OPERAND (expr, 1)))
+ == current_function_decl))
+ {
+ label_true = GOTO_DESTINATION (TREE_OPERAND (expr, 1));
+ have_then_clause_p = true;
+ }
+ else
+ label_true = create_artificial_label ();
+ if (TREE_OPERAND (expr, 2) != NULL
+ && TREE_CODE (TREE_OPERAND (expr, 2)) == GOTO_EXPR
+ && TREE_CODE (GOTO_DESTINATION (TREE_OPERAND (expr, 2))) == LABEL_DECL
+ && (DECL_CONTEXT (GOTO_DESTINATION (TREE_OPERAND (expr, 2)))
+ == current_function_decl))
+ {
+ label_false = GOTO_DESTINATION (TREE_OPERAND (expr, 2));
+ have_else_clause_p = true;
+ }
+ else
+ label_false = create_artificial_label ();
gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr), &pred_code, &arm1,
&arm2);
@@ -2933,13 +2954,36 @@ gimplify_cond_expr (tree *expr_p, gimple
label_false);
gimplify_seq_add_stmt (pre_p, gimple_cond);
- gimplify_seq_add_stmt (pre_p, gimple_build_label (label_true));
- have_then_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 1), pre_p);
- label_cont = create_artificial_label ();
- gimplify_seq_add_stmt (pre_p, gimple_build_goto (label_cont));
- gimplify_seq_add_stmt (pre_p, gimple_build_label (label_false));
- have_else_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 2), pre_p);
- gimplify_seq_add_stmt (pre_p, gimple_build_label (label_cont));
+ label_cont = NULL_TREE;
+ if (!have_then_clause_p)
+ {
+ /* For if (...) {} else { code; } put label_true after
+ the else block. */
+ if (TREE_OPERAND (expr, 1) == NULL_TREE
+ && !have_else_clause_p
+ && TREE_OPERAND (expr, 2) != NULL_TREE)
+ label_cont = label_true;
+ else
+ {
+ gimplify_seq_add_stmt (pre_p, gimple_build_label (label_true));
+ have_then_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 1), pre_p);
+ /* For if (...) { code; } else {} or
+ if (...) { code; } else goto label;
+ label_cont isn't needed. */
+ if (!have_else_clause_p && TREE_OPERAND (expr, 2) != NULL_TREE)
+ {
+ label_cont = create_artificial_label ();
+ gimplify_seq_add_stmt (pre_p, gimple_build_goto (label_cont));
+ }
+ }
+ }
+ if (!have_else_clause_p)
+ {
+ gimplify_seq_add_stmt (pre_p, gimple_build_label (label_false));
+ have_else_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 2), pre_p);
+ }
+ if (label_cont)
+ gimplify_seq_add_stmt (pre_p, gimple_build_label (label_cont));
gimple_pop_condition (pre_p);
Jakub