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]

[tuples] Avoid generating too much garbage in gimplify_cond_expr (PR tree-optimization/36389)


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


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