This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[tree-ssa] jump threading for switch_expr
- From: Richard Henderson <rth at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 30 Oct 2003 16:34:27 -0800
- Subject: [tree-ssa] jump threading for switch_expr
Even fixes
-FAIL: gcc.dg/tree-ssa/20030703-2.c scan-tree-dump-times if 1
-FAIL: gcc.dg/tree-ssa/20030708-1.c scan-tree-dump-times if 0
-FAIL: gcc.dg/tree-ssa/20030808-1.c scan-tree-dump-times if 0
though you'll note that none of these have switches...
r~
* tree-cfg.c (thread_jumps): Allow SWITCH_EXPR.
(thread_edge): Handle it. Tidy surrounding code.
Index: tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-cfg.c,v
retrieving revision 1.1.4.187
diff -c -p -d -r1.1.4.187 tree-cfg.c
*** tree-cfg.c 30 Oct 2003 21:39:58 -0000 1.1.4.187
--- tree-cfg.c 31 Oct 2003 00:27:20 -0000
*************** thread_jumps (void)
*** 4424,4430 ****
if (stmt
&& stmt_ends_bb_p (stmt)
&& TREE_CODE (stmt) != GOTO_EXPR
! && TREE_CODE (stmt) != COND_EXPR)
continue;
/* This block is now part of a forwarding path, mark it as not
--- 4424,4431 ----
if (stmt
&& stmt_ends_bb_p (stmt)
&& TREE_CODE (stmt) != GOTO_EXPR
! && TREE_CODE (stmt) != COND_EXPR
! && TREE_CODE (stmt) != SWITCH_EXPR)
continue;
/* This block is now part of a forwarding path, mark it as not
*************** thread_jumps (void)
*** 4522,4541 ****
edge
thread_edge (edge e, basic_block dest)
{
- block_stmt_iterator dest_iterator = bsi_start (dest);
tree dest_stmt = first_stmt (dest);
! tree label, goto_stmt, stmt;
basic_block bb = e->src, new_bb;
int flags;
/* We need a label at our final destination. If it does not already exist,
create it. */
! if (!dest_stmt
! || TREE_CODE (dest_stmt) != LABEL_EXPR)
{
! if (dest_stmt && TREE_CODE (dest_stmt) == CASE_LABEL_EXPR)
! abort ();
!
label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
DECL_CONTEXT (label) = current_function_decl;
dest_stmt = build1 (LABEL_EXPR, void_type_node, label);
--- 4523,4538 ----
edge
thread_edge (edge e, basic_block dest)
{
tree dest_stmt = first_stmt (dest);
! tree label, stmt;
basic_block bb = e->src, new_bb;
int flags;
/* We need a label at our final destination. If it does not already exist,
create it. */
! if (!dest_stmt || TREE_CODE (dest_stmt) != LABEL_EXPR)
{
! block_stmt_iterator dest_iterator = bsi_start (dest);
label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
DECL_CONTEXT (label) = current_function_decl;
dest_stmt = build1 (LABEL_EXPR, void_type_node, label);
*************** thread_edge (edge e, basic_block dest)
*** 4544,4573 ****
else
label = LABEL_EXPR_LABEL (dest_stmt);
! /* If our block does not end with a GOTO, then create one. Otherwise redirect
! the existing GOTO_EXPR to LABEL. */
stmt = last_stmt (bb);
! if (stmt && TREE_CODE (stmt) == COND_EXPR)
{
stmt = (e->flags & EDGE_TRUE_VALUE
? COND_EXPR_THEN (stmt)
: COND_EXPR_ELSE (stmt));
flags = e->flags;
! if (TREE_CODE (stmt) != GOTO_EXPR)
! abort ();
! }
! else
! flags = 0;
! if (!stmt || TREE_CODE (stmt) != GOTO_EXPR)
! {
! goto_stmt = build1 (GOTO_EXPR, void_type_node, label);
! bsi_insert_on_edge_immediate (e, goto_stmt, NULL, &new_bb);
! }
! else
! {
GOTO_DESTINATION (stmt) = label;
! new_bb = NULL;
}
/* Update/insert PHI nodes as necessary. */
--- 4541,4584 ----
else
label = LABEL_EXPR_LABEL (dest_stmt);
! /* If our block does not end with a GOTO, then create one.
! Otherwise redirect the existing GOTO_EXPR to LABEL. */
!
stmt = last_stmt (bb);
! new_bb = NULL;
! flags = 0;
!
! switch (stmt ? TREE_CODE (stmt) : ERROR_MARK)
{
+ case COND_EXPR:
stmt = (e->flags & EDGE_TRUE_VALUE
? COND_EXPR_THEN (stmt)
: COND_EXPR_ELSE (stmt));
flags = e->flags;
! /* FALLTHRU */
! case GOTO_EXPR:
GOTO_DESTINATION (stmt) = label;
! break;
!
! case SWITCH_EXPR:
! {
! tree vec = SWITCH_LABELS (stmt);
! size_t i, n = TREE_VEC_LENGTH (vec);
!
! for (i = 0; i < n; ++i)
! {
! tree elt = TREE_VEC_ELT (vec, i);
! if (label_to_block (CASE_LABEL (elt)) == e->dest)
! CASE_LABEL (elt) = label;
! }
! }
! break;
!
! default:
! stmt = build1 (GOTO_EXPR, void_type_node, label);
! bsi_insert_on_edge_immediate (e, stmt, NULL, &new_bb);
! break;
}
/* Update/insert PHI nodes as necessary. */