summaryrefslogtreecommitdiff
path: root/gcc/cfgexpand.c
diff options
context:
space:
mode:
authorrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>2007-04-27 08:20:39 +0000
committerrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>2007-04-27 08:20:39 +0000
commit63f88450d46e1453137aa58c1808134fe68a8f18 (patch)
tree27999109f6865e3cf09cab56d6dcff63b98e5594 /gcc/cfgexpand.c
parent8d91a9b7a1b6b01a0a1b8c4321274f9fbed7cff6 (diff)
downloadgcc-63f88450d46e1453137aa58c1808134fe68a8f18.tar.gz
* tree-ssa-loop-im.c (determine_invariantness_stmt): Attempt to
transform only GIMPLE_MODIFY_STMTs. * tree-complex.c (expand_complex_operations_1): Ditto. (expand_complex_div_wide): Do not create gotos in COND_EXPR branches. * tree-ssa-loop-manip.c (build_if_stmt): Removed. (tree_transform_and_unroll_loop): Do not create gotos in COND_EXPR branches. * value-prof.c (tree_divmod_fixed_value, tree_mod_pow2, tree_mod_subtract, tree_ic, tree_stringop_fixed_value): Ditto. * omp-low.c (expand_parallel_call, expand_omp_for_generic, expand_omp_for_static_chunk, expand_omp_for_static_nochunk): Ditto. * tree-vectorizer.c (slpeel_make_loop_iterate_ntimes, slpeel_add_loop_guard): Ditto. * tree-mudflap.c (mf_build_check_statement_for): Ditto. * lambda-code.c (perfect_nestify): Ditto. * tree-iterator.c (tsi_split_statement_list_before): Fix splitting before the first statement. * tree-optimize.c (execute_free_datastructures): Fix comments. (execute_free_cfg_annotations): Do not call disband_implicit_edges. * tree-flow.h (disband_implicit_edges): Declaration removed. * tree-cfg.c (make_cond_expr_edges): Remove gotos from COND_EXPR branches. (cleanup_dead_labels, tree_redirect_edge_and_branch): Handle COND_EXPRs without gotos. (disband_implicit_edges, has_label_p): Removed. (tree_verify_flow_info): Verify that COND_EXPR branches are empty. (tree_lv_add_condition_to_bb): Do not create gotos in COND_EXPR branches. * tree.c (build3_stat): Mark COND_EXPRs used as statements as having side effects. * tree-pretty-print.c (dump_implicit_edges): Dump implicit edges also for COND_EXPRs. * cfgexpand.c (label_rtx_for_bb): New function. (expand_gimple_cond_expr): Do not expect gotos in COND_EXPR branches. Use label_rtx_for_bb to find the labels. (expand_gimple_basic_block): Remove RETURN_EXPR at the end of the last block. Detect fallthru edges. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@124214 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cfgexpand.c')
-rw-r--r--gcc/cfgexpand.c98
1 files changed, 82 insertions, 16 deletions
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index ab2b9d36af2..643ff207108 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -1244,6 +1244,38 @@ maybe_dump_rtl_for_tree_stmt (tree stmt, rtx since)
}
}
+/* Returns the label_rtx expression for a label starting basic block BB. */
+
+static rtx
+label_rtx_for_bb (basic_block bb)
+{
+ tree_stmt_iterator tsi;
+ tree lab, lab_stmt;
+
+ if (bb->flags & BB_RTL)
+ return block_label (bb);
+
+ /* We cannot use tree_block_label, as we no longer have stmt annotations.
+ TODO -- avoid creating the new tree labels. */
+ for (tsi = tsi_start (bb_stmt_list (bb)); !tsi_end_p (tsi); tsi_next (&tsi))
+ {
+ lab_stmt = tsi_stmt (tsi);
+ if (TREE_CODE (lab_stmt) != LABEL_EXPR)
+ break;
+
+ lab = LABEL_EXPR_LABEL (lab_stmt);
+ if (DECL_NONLOCAL (lab))
+ break;
+
+ return label_rtx (lab);
+ }
+
+ lab = create_artificial_label ();
+ lab_stmt = build1 (LABEL_EXPR, void_type_node, lab);
+ tsi_link_before (&tsi, lab_stmt, TSI_NEW_STMT);
+ return label_rtx (lab);
+}
+
/* A subroutine of expand_gimple_basic_block. Expand one COND_EXPR.
Returns a new basic block if we've terminated the current basic
block and created a new one. */
@@ -1256,10 +1288,10 @@ expand_gimple_cond_expr (basic_block bb, tree stmt)
edge true_edge;
edge false_edge;
tree pred = COND_EXPR_COND (stmt);
- tree then_exp = COND_EXPR_THEN (stmt);
- tree else_exp = COND_EXPR_ELSE (stmt);
rtx last2, last;
+ gcc_assert (COND_EXPR_THEN (stmt) == NULL_TREE);
+ gcc_assert (COND_EXPR_ELSE (stmt) == NULL_TREE);
last2 = last = get_last_insn ();
extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
@@ -1275,31 +1307,31 @@ expand_gimple_cond_expr (basic_block bb, tree stmt)
/* We can either have a pure conditional jump with one fallthru edge or
two-way jump that needs to be decomposed into two basic blocks. */
- if (TREE_CODE (then_exp) == GOTO_EXPR && IS_EMPTY_STMT (else_exp))
+ if (false_edge->dest == bb->next_bb)
{
- jumpif (pred, label_rtx (GOTO_DESTINATION (then_exp)));
+ jumpif (pred, label_rtx_for_bb (true_edge->dest));
add_reg_br_prob_note (last, true_edge->probability);
maybe_dump_rtl_for_tree_stmt (stmt, last);
- if (EXPR_LOCUS (then_exp))
- emit_line_note (*(EXPR_LOCUS (then_exp)));
+ if (true_edge->goto_locus)
+ emit_line_note (*true_edge->goto_locus);
+ false_edge->flags |= EDGE_FALLTHRU;
return NULL;
}
- if (TREE_CODE (else_exp) == GOTO_EXPR && IS_EMPTY_STMT (then_exp))
+ if (true_edge->dest == bb->next_bb)
{
- jumpifnot (pred, label_rtx (GOTO_DESTINATION (else_exp)));
+ jumpifnot (pred, label_rtx_for_bb (false_edge->dest));
add_reg_br_prob_note (last, false_edge->probability);
maybe_dump_rtl_for_tree_stmt (stmt, last);
- if (EXPR_LOCUS (else_exp))
- emit_line_note (*(EXPR_LOCUS (else_exp)));
+ if (false_edge->goto_locus)
+ emit_line_note (*false_edge->goto_locus);
+ true_edge->flags |= EDGE_FALLTHRU;
return NULL;
}
- gcc_assert (TREE_CODE (then_exp) == GOTO_EXPR
- && TREE_CODE (else_exp) == GOTO_EXPR);
- jumpif (pred, label_rtx (GOTO_DESTINATION (then_exp)));
+ jumpif (pred, label_rtx_for_bb (true_edge->dest));
add_reg_br_prob_note (last, true_edge->probability);
last = get_last_insn ();
- expand_expr (else_exp, const0_rtx, VOIDmode, 0);
+ emit_jump (label_rtx_for_bb (false_edge->dest));
BB_END (bb) = last;
if (BARRIER_P (BB_END (bb)))
@@ -1321,8 +1353,8 @@ expand_gimple_cond_expr (basic_block bb, tree stmt)
maybe_dump_rtl_for_tree_stmt (stmt, last2);
- if (EXPR_LOCUS (else_exp))
- emit_line_note (*(EXPR_LOCUS (else_exp)));
+ if (false_edge->goto_locus)
+ emit_line_note (*false_edge->goto_locus);
return new_bb;
}
@@ -1457,6 +1489,25 @@ expand_gimple_basic_block (basic_block bb)
init_rtl_bb_info (bb);
bb->flags |= BB_RTL;
+ /* Remove the RETURN_EXPR if we may fall though to the exit
+ instead. */
+ tsi = tsi_last (stmts);
+ if (!tsi_end_p (tsi)
+ && TREE_CODE (tsi_stmt (tsi)) == RETURN_EXPR)
+ {
+ tree ret_stmt = tsi_stmt (tsi);
+
+ gcc_assert (single_succ_p (bb));
+ gcc_assert (single_succ (bb) == EXIT_BLOCK_PTR);
+
+ if (bb->next_bb == EXIT_BLOCK_PTR
+ && !TREE_OPERAND (ret_stmt, 0))
+ {
+ tsi_delink (&tsi);
+ single_succ_edge (bb)->flags |= EDGE_FALLTHRU;
+ }
+ }
+
tsi = tsi_start (stmts);
if (!tsi_end_p (tsi))
stmt = tsi_stmt (tsi);
@@ -1546,6 +1597,21 @@ expand_gimple_basic_block (basic_block bb)
}
}
+ /* Expand implicit goto. */
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ {
+ if (e->flags & EDGE_FALLTHRU)
+ break;
+ }
+
+ if (e && e->dest != bb->next_bb)
+ {
+ emit_jump (label_rtx_for_bb (e->dest));
+ if (e->goto_locus)
+ emit_line_note (*e->goto_locus);
+ e->flags &= ~EDGE_FALLTHRU;
+ }
+
do_pending_stack_adjust ();
/* Find the block tail. The last insn in the block is the insn