[tree-ssa] More COND_EXPR improvements
law@redhat.com
law@redhat.com
Tue Jul 1 19:48:00 GMT 2003
This integrates Jason's work to improve COND_EXPR expansion. It picks
up a couple hundred more optimizable cases in my tests. It also attempts
to deal with saved stack positions.
This has gone through the usual tests.
* expr.c (expand_expr, case COND_EXPR): Correctly (?) handle
cases where a containing block has a stack level. Handle
cases where one arm is a GOTO_EXPR and the other arm has
side effects.
* stmt.c (containing_blocks_have_cleanups_or_stack_level): New
function.
(any_pending_cleanups): Further simplification.
* tree.h (containing_blocks_have_cleanups_or_stack_level): Prototype.
Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.467.2.36
diff -c -3 -p -r1.467.2.36 expr.c
*** expr.c 1 Jul 2003 02:04:50 -0000 1.467.2.36
--- expr.c 1 Jul 2003 17:52:17 -0000
*************** expand_expr (exp, target, tmode, modifie
*** 8814,8842 ****
tree then_ = TREE_OPERAND (exp, 1);
tree else_ = TREE_OPERAND (exp, 2);
! /* If the conditional has only one useful arm and that arm is an
! unconditional jump to a local label and we have no pending
! cleanups, then we can simplify the resulting INSN stream
! by using jumpif/jumpifnot. */
! if (optimize > 0
! && TREE_CODE (then_) == GOTO_EXPR
! && TREE_CODE (GOTO_DESTINATION (then_)) == LABEL_DECL
! && ! NONLOCAL_LABEL (GOTO_DESTINATION (then_))
! && ! TREE_SIDE_EFFECTS (else_)
! && ! any_pending_cleanups ())
{
jumpif (pred, label_rtx (GOTO_DESTINATION (then_)));
! return const0_rtx;
}
! else if (optimize > 0
! && TREE_CODE (else_) == GOTO_EXPR
&& TREE_CODE (GOTO_DESTINATION (else_)) == LABEL_DECL
! && ! NONLOCAL_LABEL (GOTO_DESTINATION (else_))
! && ! TREE_SIDE_EFFECTS (then_)
! && ! any_pending_cleanups ())
{
jumpifnot (pred, label_rtx (GOTO_DESTINATION (else_)));
! return const0_rtx;
}
/* Just use the 'if' machinery. */
--- 8814,8839 ----
tree then_ = TREE_OPERAND (exp, 1);
tree else_ = TREE_OPERAND (exp, 2);
! /* If we do not have any pending cleanups or stack_levels
! to restore, and at least one arm of the COND_EXPR is a
! GOTO_EXPR to a local label, then we can emit more efficient
! code by using jumpif/jumpifnot instead of the 'if' machinery. */
! if (! optimize
! || containing_blocks_have_cleanups_or_stack_level ())
! ;
! else if (TREE_CODE (then_) == GOTO_EXPR
! && TREE_CODE (GOTO_DESTINATION (then_)) == LABEL_DECL
! && ! NONLOCAL_LABEL (GOTO_DESTINATION (then_)))
{
jumpif (pred, label_rtx (GOTO_DESTINATION (then_)));
! return expand_expr (else_, const0_rtx, VOIDmode, 0);
}
! else if (TREE_CODE (else_) == GOTO_EXPR
&& TREE_CODE (GOTO_DESTINATION (else_)) == LABEL_DECL
! && ! NONLOCAL_LABEL (GOTO_DESTINATION (else_)))
{
jumpifnot (pred, label_rtx (GOTO_DESTINATION (else_)));
! return expand_expr (then_, const0_rtx, VOIDmode, 0);
}
/* Just use the 'if' machinery. */
Index: stmt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/stmt.c,v
retrieving revision 1.267.2.21
diff -c -3 -p -r1.267.2.21 stmt.c
*** stmt.c 1 Jul 2003 02:04:51 -0000 1.267.2.21
--- stmt.c 1 Jul 2003 17:52:41 -0000
*************** last_cleanup_this_contour ()
*** 4448,4453 ****
--- 4448,4470 ----
return block_stack->data.block.cleanups;
}
+
+ /* Return nonzero if any containing block has a stack level or
+ cleanups. */
+
+ int
+ containing_blocks_have_cleanups_or_stack_level ()
+ {
+ struct nesting *block;
+
+ for (block = block_stack; block; block = block->next)
+ if (block->data.block.stack_level != 0
+ || block->data.block.cleanups != 0)
+ return 1;
+
+ return 0;
+ }
+
/* Return 1 if there are any pending cleanups at this point.
Check the current contour as well as contours that enclose
the current contour. */
*************** any_pending_cleanups ()
*** 4462,4469 ****
if (block_stack->data.block.cleanups != NULL)
return 1;
! if (block_stack->data.block.cleanups == 0
! && block_stack->data.block.outer_cleanups == 0)
return 0;
for (block = block_stack->next; block; block = block->next)
--- 4479,4486 ----
if (block_stack->data.block.cleanups != NULL)
return 1;
!
! if (block_stack->data.block.outer_cleanups == 0)
return 0;
for (block = block_stack->next; block; block = block->next)
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.342.2.72
diff -c -3 -p -r1.342.2.72 tree.h
*** tree.h 1 Jul 2003 04:04:32 -0000 1.342.2.72
--- tree.h 1 Jul 2003 17:53:42 -0000
*************** extern void expand_asm_expr PARAMS ((tr
*** 3274,3279 ****
--- 3274,3280 ----
extern bool asm_op_is_mem_input (tree, tree);
extern tree resolve_asm_operand_names (tree, tree, tree);
extern int any_pending_cleanups PARAMS ((void));
+ extern int containing_blocks_have_cleanups_or_stack_level PARAMS ((void));
extern void init_stmt_for_function PARAMS ((void));
extern void expand_start_target_temps PARAMS ((void));
extern void expand_end_target_temps PARAMS ((void));
More information about the Gcc-patches
mailing list