This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[tree-ssa] PATCH to expand_expr:COND_EXPR
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 01 Jun 2003 11:54:03 -0400
- Subject: [tree-ssa] PATCH to expand_expr:COND_EXPR
This patch is a simpler way to generate less RTL for the void COND_EXPRs in
GIMPLE.
We still emit unnecessary jumps for something like
if (a)
goto b;
I tried expanding this as a conditional jump, but that breaks for gotos
that need some sort of fixup (nonlocal gotos, gotos that need to run C++
cleanups or restore the stack position). Indeed, we don't want to convert
this to a conditional jump in such cases. Darn implicit semantics...
Tested i686-pc-linux-gnu, applied to tree-ssa branch.
2003-06-01 Jason Merrill <jason@redhat.com>
* expr.c (expand_expr) <COND_EXPR>: Use the if-statement code if
it's void.
*** expr.c.~1~ Tue May 27 18:38:25 2003
--- expr.c Thu May 29 18:57:48 2003
*************** expand_expr (exp, target, tmode, modifie
*** 8805,8810 ****
--- 8805,8844 ----
modifier);
case COND_EXPR:
+ /* If it's void, we don't need to worry about computing a value. */
+ if (VOID_TYPE_P (TREE_TYPE (exp)))
+ {
+ tree pred = TREE_OPERAND (exp, 0);
+ tree then_ = TREE_OPERAND (exp, 1);
+ tree else_ = TREE_OPERAND (exp, 2);
+
+ /* Just use the 'if' machinery. */
+ expand_start_cond (pred, 0);
+ start_cleanup_deferral ();
+ expand_expr (then_, const0_rtx, VOIDmode, 0);
+
+ exp = else_;
+
+ /* Iterate over 'else if's instead of recursing. */
+ for (; TREE_CODE (exp) == COND_EXPR; exp = TREE_OPERAND (exp, 2))
+ {
+ expand_start_else ();
+ if (TREE_LOCUS (exp))
+ emit_line_note (TREE_FILENAME (exp), TREE_LINENO (exp));
+ expand_elseif (TREE_OPERAND (exp, 0));
+ expand_expr (TREE_OPERAND (exp, 1), const0_rtx, VOIDmode, 0);
+ }
+ /* Don't emit the jump and label if there's no 'else' clause. */
+ if (TREE_SIDE_EFFECTS (exp))
+ {
+ expand_start_else ();
+ expand_expr (exp, const0_rtx, VOIDmode, 0);
+ }
+ end_cleanup_deferral ();
+ expand_end_cond ();
+ return const0_rtx;
+ }
+
/* If we would have a "singleton" (see below) were it not for a
conversion in each arm, bring that conversion back out. */
if (TREE_CODE (TREE_OPERAND (exp, 1)) == NOP_EXPR
*************** expand_expr (exp, target, tmode, modifie
*** 9061,9144 ****
}
else
{
! /* This used heavily by gimplified code, so it's worth
! trying to be semi-intelligent about the code we generate. */
!
! /* Expand the condition and jump around THEN clause if the
! condition does not hold.
! However, if the THEN clause is empty, then jump around
! the ELSE clause if the condition does hold.
! If both the THEN and the ELSE are empty, then just emit
! the condition (in case it had embedded side effects). */
! if (! IS_EMPTY_STMT (TREE_OPERAND (exp, 1)))
! jumpifnot (TREE_OPERAND (exp, 0), op0);
! else if (! IS_EMPTY_STMT (TREE_OPERAND (exp, 2)))
! {
! op1 = gen_label_rtx ();
! jumpif (TREE_OPERAND (exp, 0), op1);
! }
else
! expand_expr (TREE_OPERAND (exp, 0),
ignore ? const0_rtx : NULL_RTX, VOIDmode, 0);
-
- /* Generate RTL for the THEN clause if it is not empty. */
- if (! IS_EMPTY_STMT (TREE_OPERAND (exp, 1)))
- {
- start_cleanup_deferral ();
-
- /* One branch of the cond can be void, if it never returns. For
- example A ? throw : E */
- if (temp != 0
- && TREE_TYPE (TREE_OPERAND (exp, 1)) != void_type_node)
- store_expr (TREE_OPERAND (exp, 1), temp,
- modifier == EXPAND_STACK_PARM ? 2 : 0);
- else
- expand_expr (TREE_OPERAND (exp, 1),
- ignore ? const0_rtx : NULL_RTX, VOIDmode, 0);
- end_cleanup_deferral ();
- emit_queue ();
-
- /* If the ELSE clause was not empty, then we need to
- jump around it. */
- if (! IS_EMPTY_STMT (TREE_OPERAND (exp, 2)))
- {
- op1 = gen_label_rtx ();
- emit_jump_insn (gen_jump (op1));
- emit_barrier ();
- }
-
- /* This is the target of the jump around the THEN block. */
- emit_label (op0);
- }
-
- /* Generate RTL for the ELSE clause if it is not empty. */
- if (! IS_EMPTY_STMT (TREE_OPERAND (exp, 2)))
- {
- start_cleanup_deferral ();
-
- if (temp != 0
- && TREE_TYPE (TREE_OPERAND (exp, 2)) != void_type_node)
- store_expr (TREE_OPERAND (exp, 2), temp,
- modifier == EXPAND_STACK_PARM ? 2 : 0);
- else
- expand_expr (TREE_OPERAND (exp, 2),
- ignore ? const0_rtx : NULL_RTX, VOIDmode, 0);
-
- end_cleanup_deferral ();
-
- emit_queue ();
- emit_label (op1);
- }
- OK_DEFER_POP;
- return temp;
}
- /* We fall into this path from earlier in the COND_EXPR case, so this
- can not be pulled up into the trailing else clause. */
end_cleanup_deferral ();
!
emit_queue ();
emit_label (op1);
OK_DEFER_POP;
--- 9095,9131 ----
}
else
{
! op1 = gen_label_rtx ();
! jumpifnot (TREE_OPERAND (exp, 0), op0);
! start_cleanup_deferral ();
! /* One branch of the cond can be void, if it never returns. For
! example A ? throw : E */
! if (temp != 0
! && TREE_TYPE (TREE_OPERAND (exp, 1)) != void_type_node)
! store_expr (TREE_OPERAND (exp, 1), temp,
! modifier == EXPAND_STACK_PARM ? 2 : 0);
else
! expand_expr (TREE_OPERAND (exp, 1),
! ignore ? const0_rtx : NULL_RTX, VOIDmode, 0);
! end_cleanup_deferral ();
! emit_queue ();
! emit_jump_insn (gen_jump (op1));
! emit_barrier ();
! emit_label (op0);
! start_cleanup_deferral ();
! if (temp != 0
! && TREE_TYPE (TREE_OPERAND (exp, 2)) != void_type_node)
! store_expr (TREE_OPERAND (exp, 2), temp,
! modifier == EXPAND_STACK_PARM ? 2 : 0);
! else
! expand_expr (TREE_OPERAND (exp, 2),
ignore ? const0_rtx : NULL_RTX, VOIDmode, 0);
}
end_cleanup_deferral ();
!
emit_queue ();
emit_label (op1);
OK_DEFER_POP;