Commit a9b77cd1 by Zdenek Dvorak Committed by Zdenek Dvorak

tree-ssa-loop-im.c (determine_invariantness_stmt): Attempt to transform only GIMPLE_MODIFY_STMTs.

	* 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.

From-SVN: r124214
parent f5c3dc96
2007-04-27 Zdenek Dvorak <dvorakz@suse.cz>
* 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.
2007-04-26 Ian Lance Taylor <iant@google.com> 2007-04-26 Ian Lance Taylor <iant@google.com>
PR target/28675 PR target/28675
......
...@@ -1244,6 +1244,38 @@ maybe_dump_rtl_for_tree_stmt (tree stmt, rtx since) ...@@ -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. /* A subroutine of expand_gimple_basic_block. Expand one COND_EXPR.
Returns a new basic block if we've terminated the current basic Returns a new basic block if we've terminated the current basic
block and created a new one. */ block and created a new one. */
...@@ -1256,10 +1288,10 @@ expand_gimple_cond_expr (basic_block bb, tree stmt) ...@@ -1256,10 +1288,10 @@ expand_gimple_cond_expr (basic_block bb, tree stmt)
edge true_edge; edge true_edge;
edge false_edge; edge false_edge;
tree pred = COND_EXPR_COND (stmt); tree pred = COND_EXPR_COND (stmt);
tree then_exp = COND_EXPR_THEN (stmt);
tree else_exp = COND_EXPR_ELSE (stmt);
rtx last2, last; rtx last2, last;
gcc_assert (COND_EXPR_THEN (stmt) == NULL_TREE);
gcc_assert (COND_EXPR_ELSE (stmt) == NULL_TREE);
last2 = last = get_last_insn (); last2 = last = get_last_insn ();
extract_true_false_edges_from_block (bb, &true_edge, &false_edge); extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
...@@ -1275,31 +1307,31 @@ expand_gimple_cond_expr (basic_block bb, tree stmt) ...@@ -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 /* 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. */ 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); add_reg_br_prob_note (last, true_edge->probability);
maybe_dump_rtl_for_tree_stmt (stmt, last); maybe_dump_rtl_for_tree_stmt (stmt, last);
if (EXPR_LOCUS (then_exp)) if (true_edge->goto_locus)
emit_line_note (*(EXPR_LOCUS (then_exp))); emit_line_note (*true_edge->goto_locus);
false_edge->flags |= EDGE_FALLTHRU;
return NULL; 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); add_reg_br_prob_note (last, false_edge->probability);
maybe_dump_rtl_for_tree_stmt (stmt, last); maybe_dump_rtl_for_tree_stmt (stmt, last);
if (EXPR_LOCUS (else_exp)) if (false_edge->goto_locus)
emit_line_note (*(EXPR_LOCUS (else_exp))); emit_line_note (*false_edge->goto_locus);
true_edge->flags |= EDGE_FALLTHRU;
return NULL; 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); add_reg_br_prob_note (last, true_edge->probability);
last = get_last_insn (); 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; BB_END (bb) = last;
if (BARRIER_P (BB_END (bb))) if (BARRIER_P (BB_END (bb)))
...@@ -1321,8 +1353,8 @@ expand_gimple_cond_expr (basic_block bb, tree stmt) ...@@ -1321,8 +1353,8 @@ expand_gimple_cond_expr (basic_block bb, tree stmt)
maybe_dump_rtl_for_tree_stmt (stmt, last2); maybe_dump_rtl_for_tree_stmt (stmt, last2);
if (EXPR_LOCUS (else_exp)) if (false_edge->goto_locus)
emit_line_note (*(EXPR_LOCUS (else_exp))); emit_line_note (*false_edge->goto_locus);
return new_bb; return new_bb;
} }
...@@ -1457,6 +1489,25 @@ expand_gimple_basic_block (basic_block bb) ...@@ -1457,6 +1489,25 @@ expand_gimple_basic_block (basic_block bb)
init_rtl_bb_info (bb); init_rtl_bb_info (bb);
bb->flags |= BB_RTL; 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); tsi = tsi_start (stmts);
if (!tsi_end_p (tsi)) if (!tsi_end_p (tsi))
stmt = tsi_stmt (tsi); stmt = tsi_stmt (tsi);
...@@ -1546,6 +1597,21 @@ expand_gimple_basic_block (basic_block bb) ...@@ -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 (); do_pending_stack_adjust ();
/* Find the block tail. The last insn in the block is the insn /* Find the block tail. The last insn in the block is the insn
......
...@@ -2450,7 +2450,7 @@ perfect_nestify (struct loop *loop, ...@@ -2450,7 +2450,7 @@ perfect_nestify (struct loop *loop,
{ {
basic_block *bbs; basic_block *bbs;
tree exit_condition; tree exit_condition;
tree then_label, else_label, cond_stmt; tree cond_stmt;
basic_block preheaderbb, headerbb, bodybb, latchbb, olddest; basic_block preheaderbb, headerbb, bodybb, latchbb, olddest;
int i; int i;
block_stmt_iterator bsi, firstbsi; block_stmt_iterator bsi, firstbsi;
...@@ -2498,13 +2498,11 @@ perfect_nestify (struct loop *loop, ...@@ -2498,13 +2498,11 @@ perfect_nestify (struct loop *loop,
bodybb = create_empty_bb (EXIT_BLOCK_PTR->prev_bb); bodybb = create_empty_bb (EXIT_BLOCK_PTR->prev_bb);
latchbb = create_empty_bb (EXIT_BLOCK_PTR->prev_bb); latchbb = create_empty_bb (EXIT_BLOCK_PTR->prev_bb);
make_edge (headerbb, bodybb, EDGE_FALLTHRU); make_edge (headerbb, bodybb, EDGE_FALLTHRU);
then_label = build1 (GOTO_EXPR, void_type_node, tree_block_label (latchbb));
else_label = build1 (GOTO_EXPR, void_type_node, tree_block_label (olddest));
cond_stmt = build3 (COND_EXPR, void_type_node, cond_stmt = build3 (COND_EXPR, void_type_node,
build2 (NE_EXPR, boolean_type_node, build2 (NE_EXPR, boolean_type_node,
integer_one_node, integer_one_node,
integer_zero_node), integer_zero_node),
then_label, else_label); NULL_TREE, NULL_TREE);
bsi = bsi_start (bodybb); bsi = bsi_start (bodybb);
bsi_insert_after (&bsi, cond_stmt, BSI_NEW_STMT); bsi_insert_after (&bsi, cond_stmt, BSI_NEW_STMT);
e = make_edge (bodybb, olddest, EDGE_FALSE_VALUE); e = make_edge (bodybb, olddest, EDGE_FALSE_VALUE);
......
...@@ -2203,7 +2203,7 @@ expand_parallel_call (struct omp_region *region, basic_block bb, ...@@ -2203,7 +2203,7 @@ expand_parallel_call (struct omp_region *region, basic_block bb,
{ {
basic_block cond_bb, then_bb, else_bb; basic_block cond_bb, then_bb, else_bb;
edge e; edge e;
tree t, then_lab, else_lab, tmp; tree t, tmp;
tmp = create_tmp_var (TREE_TYPE (val), NULL); tmp = create_tmp_var (TREE_TYPE (val), NULL);
e = split_block (bb, NULL); e = split_block (bb, NULL);
...@@ -2213,26 +2213,18 @@ expand_parallel_call (struct omp_region *region, basic_block bb, ...@@ -2213,26 +2213,18 @@ expand_parallel_call (struct omp_region *region, basic_block bb,
then_bb = create_empty_bb (cond_bb); then_bb = create_empty_bb (cond_bb);
else_bb = create_empty_bb (then_bb); else_bb = create_empty_bb (then_bb);
then_lab = create_artificial_label ();
else_lab = create_artificial_label ();
t = build3 (COND_EXPR, void_type_node, t = build3 (COND_EXPR, void_type_node,
cond, cond, NULL_TREE, NULL_TREE);
build_and_jump (&then_lab),
build_and_jump (&else_lab));
si = bsi_start (cond_bb); si = bsi_start (cond_bb);
bsi_insert_after (&si, t, BSI_CONTINUE_LINKING); bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
si = bsi_start (then_bb); si = bsi_start (then_bb);
t = build1 (LABEL_EXPR, void_type_node, then_lab);
bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
t = build_gimple_modify_stmt (tmp, val); t = build_gimple_modify_stmt (tmp, val);
bsi_insert_after (&si, t, BSI_CONTINUE_LINKING); bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
si = bsi_start (else_bb); si = bsi_start (else_bb);
t = build1 (LABEL_EXPR, void_type_node, else_lab);
bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
t = build_gimple_modify_stmt (tmp, t = build_gimple_modify_stmt (tmp,
build_int_cst (unsigned_type_node, 1)); build_int_cst (unsigned_type_node, 1));
bsi_insert_after (&si, t, BSI_CONTINUE_LINKING); bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
...@@ -2579,7 +2571,6 @@ expand_omp_for_generic (struct omp_region *region, ...@@ -2579,7 +2571,6 @@ expand_omp_for_generic (struct omp_region *region,
enum built_in_function start_fn, enum built_in_function start_fn,
enum built_in_function next_fn) enum built_in_function next_fn)
{ {
tree l0, l1, l2 = NULL, l3 = NULL;
tree type, istart0, iend0, iend; tree type, istart0, iend0, iend;
tree t, list; tree t, list;
basic_block entry_bb, cont_bb, exit_bb, l0_bb, l1_bb; basic_block entry_bb, cont_bb, exit_bb, l0_bb, l1_bb;
...@@ -2601,18 +2592,12 @@ expand_omp_for_generic (struct omp_region *region, ...@@ -2601,18 +2592,12 @@ expand_omp_for_generic (struct omp_region *region,
l0_bb = create_empty_bb (entry_bb); l0_bb = create_empty_bb (entry_bb);
l1_bb = single_succ (entry_bb); l1_bb = single_succ (entry_bb);
l0 = tree_block_label (l0_bb);
l1 = tree_block_label (l1_bb);
cont_bb = region->cont; cont_bb = region->cont;
exit_bb = region->exit; exit_bb = region->exit;
if (cont_bb) if (cont_bb)
{ {
l2_bb = create_empty_bb (cont_bb); l2_bb = create_empty_bb (cont_bb);
l3_bb = single_succ (cont_bb); l3_bb = single_succ (cont_bb);
l2 = tree_block_label (l2_bb);
l3 = tree_block_label (l3_bb);
} }
si = bsi_last (entry_bb); si = bsi_last (entry_bb);
...@@ -2640,8 +2625,7 @@ expand_omp_for_generic (struct omp_region *region, ...@@ -2640,8 +2625,7 @@ expand_omp_for_generic (struct omp_region *region,
t = get_formal_tmp_var (t, &list); t = get_formal_tmp_var (t, &list);
if (cont_bb) if (cont_bb)
{ {
t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&l0), t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
build_and_jump (&l3));
append_to_statement_list (t, &list); append_to_statement_list (t, &list);
} }
bsi_insert_after (&si, list, BSI_SAME_STMT); bsi_insert_after (&si, list, BSI_SAME_STMT);
...@@ -2682,8 +2666,7 @@ expand_omp_for_generic (struct omp_region *region, ...@@ -2682,8 +2666,7 @@ expand_omp_for_generic (struct omp_region *region,
t = build2 (fd->cond_code, boolean_type_node, fd->v, iend); t = build2 (fd->cond_code, boolean_type_node, fd->v, iend);
t = get_formal_tmp_var (t, &list); t = get_formal_tmp_var (t, &list);
t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&l1), t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
build_and_jump (&l2));
append_to_statement_list (t, &list); append_to_statement_list (t, &list);
si = bsi_last (cont_bb); si = bsi_last (cont_bb);
...@@ -2698,8 +2681,7 @@ expand_omp_for_generic (struct omp_region *region, ...@@ -2698,8 +2681,7 @@ expand_omp_for_generic (struct omp_region *region,
build_fold_addr_expr (istart0), build_fold_addr_expr (istart0),
build_fold_addr_expr (iend0)); build_fold_addr_expr (iend0));
t = get_formal_tmp_var (t, &list); t = get_formal_tmp_var (t, &list);
t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&l0), t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
build_and_jump (&l3));
append_to_statement_list (t, &list); append_to_statement_list (t, &list);
si = bsi_start (l2_bb); si = bsi_start (l2_bb);
...@@ -2768,7 +2750,7 @@ static void ...@@ -2768,7 +2750,7 @@ static void
expand_omp_for_static_nochunk (struct omp_region *region, expand_omp_for_static_nochunk (struct omp_region *region,
struct omp_for_data *fd) struct omp_for_data *fd)
{ {
tree l0, l1, l2, n, q, s0, e0, e, t, nthreads, threadid; tree n, q, s0, e0, e, t, nthreads, threadid;
tree type, list; tree type, list;
basic_block entry_bb, exit_bb, seq_start_bb, body_bb, cont_bb; basic_block entry_bb, exit_bb, seq_start_bb, body_bb, cont_bb;
basic_block fin_bb; basic_block fin_bb;
...@@ -2783,10 +2765,6 @@ expand_omp_for_static_nochunk (struct omp_region *region, ...@@ -2783,10 +2765,6 @@ expand_omp_for_static_nochunk (struct omp_region *region,
fin_bb = single_succ (cont_bb); fin_bb = single_succ (cont_bb);
exit_bb = region->exit; exit_bb = region->exit;
l0 = tree_block_label (seq_start_bb);
l1 = tree_block_label (body_bb);
l2 = tree_block_label (fin_bb);
/* Iteration space partitioning goes in ENTRY_BB. */ /* Iteration space partitioning goes in ENTRY_BB. */
list = alloc_stmt_list (); list = alloc_stmt_list ();
...@@ -2837,8 +2815,7 @@ expand_omp_for_static_nochunk (struct omp_region *region, ...@@ -2837,8 +2815,7 @@ expand_omp_for_static_nochunk (struct omp_region *region,
e0 = get_formal_tmp_var (t, &list); e0 = get_formal_tmp_var (t, &list);
t = build2 (GE_EXPR, boolean_type_node, s0, e0); t = build2 (GE_EXPR, boolean_type_node, s0, e0);
t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&l2), t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
build_and_jump (&l0));
append_to_statement_list (t, &list); append_to_statement_list (t, &list);
si = bsi_last (entry_bb); si = bsi_last (entry_bb);
...@@ -2872,8 +2849,7 @@ expand_omp_for_static_nochunk (struct omp_region *region, ...@@ -2872,8 +2849,7 @@ expand_omp_for_static_nochunk (struct omp_region *region,
t = build2 (fd->cond_code, boolean_type_node, fd->v, e); t = build2 (fd->cond_code, boolean_type_node, fd->v, e);
t = get_formal_tmp_var (t, &list); t = get_formal_tmp_var (t, &list);
t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&l1), t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
build_and_jump (&l2));
append_to_statement_list (t, &list); append_to_statement_list (t, &list);
si = bsi_last (cont_bb); si = bsi_last (cont_bb);
...@@ -2937,7 +2913,7 @@ expand_omp_for_static_nochunk (struct omp_region *region, ...@@ -2937,7 +2913,7 @@ expand_omp_for_static_nochunk (struct omp_region *region,
static void static void
expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd) expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
{ {
tree l0, l1, l2, l3, l4, n, s0, e0, e, t; tree n, s0, e0, e, t;
tree trip, nthreads, threadid; tree trip, nthreads, threadid;
tree type; tree type;
basic_block entry_bb, exit_bb, body_bb, seq_start_bb, iter_part_bb; basic_block entry_bb, exit_bb, body_bb, seq_start_bb, iter_part_bb;
...@@ -2956,12 +2932,6 @@ expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd) ...@@ -2956,12 +2932,6 @@ expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
fin_bb = single_succ (cont_bb); fin_bb = single_succ (cont_bb);
exit_bb = region->exit; exit_bb = region->exit;
l0 = tree_block_label (iter_part_bb);
l1 = tree_block_label (seq_start_bb);
l2 = tree_block_label (body_bb);
l3 = tree_block_label (trip_update_bb);
l4 = tree_block_label (fin_bb);
/* Trip and adjustment setup goes in ENTRY_BB. */ /* Trip and adjustment setup goes in ENTRY_BB. */
list = alloc_stmt_list (); list = alloc_stmt_list ();
...@@ -3021,8 +2991,7 @@ expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd) ...@@ -3021,8 +2991,7 @@ expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
e0 = get_formal_tmp_var (t, &list); e0 = get_formal_tmp_var (t, &list);
t = build2 (LT_EXPR, boolean_type_node, s0, n); t = build2 (LT_EXPR, boolean_type_node, s0, n);
t = build3 (COND_EXPR, void_type_node, t, t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
build_and_jump (&l1), build_and_jump (&l4));
append_to_statement_list (t, &list); append_to_statement_list (t, &list);
si = bsi_start (iter_part_bb); si = bsi_start (iter_part_bb);
...@@ -3055,8 +3024,7 @@ expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd) ...@@ -3055,8 +3024,7 @@ expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
t = build2 (fd->cond_code, boolean_type_node, fd->v, e); t = build2 (fd->cond_code, boolean_type_node, fd->v, e);
t = get_formal_tmp_var (t, &list); t = get_formal_tmp_var (t, &list);
t = build3 (COND_EXPR, void_type_node, t, t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
build_and_jump (&l2), build_and_jump (&l3));
append_to_statement_list (t, &list); append_to_statement_list (t, &list);
si = bsi_last (cont_bb); si = bsi_last (cont_bb);
......
...@@ -615,6 +615,10 @@ make_cond_expr_edges (basic_block bb) ...@@ -615,6 +615,10 @@ make_cond_expr_edges (basic_block bb)
e->goto_locus = EXPR_LOCUS (COND_EXPR_ELSE (entry)); e->goto_locus = EXPR_LOCUS (COND_EXPR_ELSE (entry));
#endif #endif
} }
/* We do not need the gotos anymore. */
COND_EXPR_THEN (entry) = NULL_TREE;
COND_EXPR_ELSE (entry) = NULL_TREE;
} }
...@@ -928,10 +932,12 @@ cleanup_dead_labels (void) ...@@ -928,10 +932,12 @@ cleanup_dead_labels (void)
true_branch = COND_EXPR_THEN (stmt); true_branch = COND_EXPR_THEN (stmt);
false_branch = COND_EXPR_ELSE (stmt); false_branch = COND_EXPR_ELSE (stmt);
GOTO_DESTINATION (true_branch) if (true_branch)
= main_block_label (GOTO_DESTINATION (true_branch)); GOTO_DESTINATION (true_branch)
GOTO_DESTINATION (false_branch) = main_block_label (GOTO_DESTINATION (true_branch));
= main_block_label (GOTO_DESTINATION (false_branch)); if (false_branch)
GOTO_DESTINATION (false_branch)
= main_block_label (GOTO_DESTINATION (false_branch));
break; break;
} }
...@@ -2522,87 +2528,6 @@ stmt_ends_bb_p (tree t) ...@@ -2522,87 +2528,6 @@ stmt_ends_bb_p (tree t)
return is_ctrl_stmt (t) || is_ctrl_altering_stmt (t); return is_ctrl_stmt (t) || is_ctrl_altering_stmt (t);
} }
/* Add gotos that used to be represented implicitly in the CFG. */
void
disband_implicit_edges (void)
{
basic_block bb;
block_stmt_iterator last;
edge e;
edge_iterator ei;
tree stmt, label;
FOR_EACH_BB (bb)
{
last = bsi_last (bb);
stmt = last_stmt (bb);
if (stmt && TREE_CODE (stmt) == COND_EXPR)
{
/* Remove superfluous gotos from COND_EXPR branches. Moved
from cfg_remove_useless_stmts here since it violates the
invariants for tree--cfg correspondence and thus fits better
here where we do it anyway. */
e = find_edge (bb, bb->next_bb);
if (e)
{
if (e->flags & EDGE_TRUE_VALUE)
COND_EXPR_THEN (stmt) = build_empty_stmt ();
else if (e->flags & EDGE_FALSE_VALUE)
COND_EXPR_ELSE (stmt) = build_empty_stmt ();
else
gcc_unreachable ();
e->flags |= EDGE_FALLTHRU;
}
continue;
}
if (stmt && TREE_CODE (stmt) == RETURN_EXPR)
{
/* Remove the RETURN_EXPR if we may fall though to the exit
instead. */
gcc_assert (single_succ_p (bb));
gcc_assert (single_succ (bb) == EXIT_BLOCK_PTR);
if (bb->next_bb == EXIT_BLOCK_PTR
&& !TREE_OPERAND (stmt, 0))
{
bsi_remove (&last, true);
single_succ_edge (bb)->flags |= EDGE_FALLTHRU;
}
continue;
}
/* There can be no fallthru edge if the last statement is a control
one. */
if (stmt && is_ctrl_stmt (stmt))
continue;
/* Find a fallthru edge and emit the goto if necessary. */
FOR_EACH_EDGE (e, ei, bb->succs)
if (e->flags & EDGE_FALLTHRU)
break;
if (!e || e->dest == bb->next_bb)
continue;
gcc_assert (e->dest != EXIT_BLOCK_PTR);
label = tree_block_label (e->dest);
stmt = build1 (GOTO_EXPR, void_type_node, label);
#ifdef USE_MAPPED_LOCATION
SET_EXPR_LOCATION (stmt, e->goto_locus);
#else
SET_EXPR_LOCUS (stmt, e->goto_locus);
#endif
bsi_insert_after (&last, stmt, BSI_NEW_STMT);
e->flags &= ~EDGE_FALLTHRU;
}
}
/* Remove block annotations and other datastructures. */ /* Remove block annotations and other datastructures. */
void void
...@@ -3136,27 +3061,6 @@ tree_split_edge (edge edge_in) ...@@ -3136,27 +3061,6 @@ tree_split_edge (edge edge_in)
return new_bb; return new_bb;
} }
/* Return true when BB has label LABEL in it. */
static bool
has_label_p (basic_block bb, tree label)
{
block_stmt_iterator bsi;
for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
{
tree stmt = bsi_stmt (bsi);
if (TREE_CODE (stmt) != LABEL_EXPR)
return false;
if (LABEL_EXPR_LABEL (stmt) == label)
return true;
}
return false;
}
/* Callback for walk_tree, check that all elements with address taken are /* Callback for walk_tree, check that all elements with address taken are
properly noticed as such. The DATA is an int* that is 1 if TP was seen properly noticed as such. The DATA is an int* that is 1 if TP was seen
inside a PHI node. */ inside a PHI node. */
...@@ -3789,10 +3693,12 @@ tree_verify_flow_info (void) ...@@ -3789,10 +3693,12 @@ tree_verify_flow_info (void)
{ {
edge true_edge; edge true_edge;
edge false_edge; edge false_edge;
if (TREE_CODE (COND_EXPR_THEN (stmt)) != GOTO_EXPR
|| TREE_CODE (COND_EXPR_ELSE (stmt)) != GOTO_EXPR) if (COND_EXPR_THEN (stmt) != NULL_TREE
|| COND_EXPR_ELSE (stmt) != NULL_TREE)
{ {
error ("structured COND_EXPR at the end of bb %d", bb->index); error ("COND_EXPR with code in branches at the end of bb %d",
bb->index);
err = 1; err = 1;
} }
...@@ -3809,22 +3715,6 @@ tree_verify_flow_info (void) ...@@ -3809,22 +3715,6 @@ tree_verify_flow_info (void)
bb->index); bb->index);
err = 1; err = 1;
} }
if (!has_label_p (true_edge->dest,
GOTO_DESTINATION (COND_EXPR_THEN (stmt))))
{
error ("%<then%> label does not match edge at end of bb %d",
bb->index);
err = 1;
}
if (!has_label_p (false_edge->dest,
GOTO_DESTINATION (COND_EXPR_ELSE (stmt))))
{
error ("%<else%> label does not match edge at end of bb %d",
bb->index);
err = 1;
}
} }
break; break;
...@@ -4103,10 +3993,7 @@ tree_redirect_edge_and_branch (edge e, basic_block dest) ...@@ -4103,10 +3993,7 @@ tree_redirect_edge_and_branch (edge e, basic_block dest)
switch (stmt ? TREE_CODE (stmt) : ERROR_MARK) switch (stmt ? TREE_CODE (stmt) : ERROR_MARK)
{ {
case COND_EXPR: case COND_EXPR:
stmt = (e->flags & EDGE_TRUE_VALUE /* For COND_EXPR, we only need to redirect the edge. */
? COND_EXPR_THEN (stmt)
: COND_EXPR_ELSE (stmt));
GOTO_DESTINATION (stmt) = label;
break; break;
case GOTO_EXPR: case GOTO_EXPR:
...@@ -5676,20 +5563,18 @@ tree_lv_adjust_loop_header_phi (basic_block first, basic_block second, ...@@ -5676,20 +5563,18 @@ tree_lv_adjust_loop_header_phi (basic_block first, basic_block second,
SECOND_HEAD is the destination of the THEN and FIRST_HEAD is SECOND_HEAD is the destination of the THEN and FIRST_HEAD is
the destination of the ELSE part. */ the destination of the ELSE part. */
static void static void
tree_lv_add_condition_to_bb (basic_block first_head, basic_block second_head, tree_lv_add_condition_to_bb (basic_block first_head ATTRIBUTE_UNUSED,
basic_block cond_bb, void *cond_e) basic_block second_head ATTRIBUTE_UNUSED,
basic_block cond_bb, void *cond_e)
{ {
block_stmt_iterator bsi; block_stmt_iterator bsi;
tree goto1 = NULL_TREE;
tree goto2 = NULL_TREE;
tree new_cond_expr = NULL_TREE; tree new_cond_expr = NULL_TREE;
tree cond_expr = (tree) cond_e; tree cond_expr = (tree) cond_e;
edge e0; edge e0;
/* Build new conditional expr */ /* Build new conditional expr */
goto1 = build1 (GOTO_EXPR, void_type_node, tree_block_label (first_head)); new_cond_expr = build3 (COND_EXPR, void_type_node, cond_expr,
goto2 = build1 (GOTO_EXPR, void_type_node, tree_block_label (second_head)); NULL_TREE, NULL_TREE);
new_cond_expr = build3 (COND_EXPR, void_type_node, cond_expr, goto1, goto2);
/* Add new cond in cond_bb. */ /* Add new cond in cond_bb. */
bsi = bsi_start (cond_bb); bsi = bsi_start (cond_bb);
......
...@@ -1060,11 +1060,6 @@ expand_complex_div_wide (block_stmt_iterator *bsi, tree inner_type, ...@@ -1060,11 +1060,6 @@ expand_complex_div_wide (block_stmt_iterator *bsi, tree inner_type,
bb_true = create_empty_bb (bb_cond); bb_true = create_empty_bb (bb_cond);
bb_false = create_empty_bb (bb_true); bb_false = create_empty_bb (bb_true);
t1 = build1 (GOTO_EXPR, void_type_node, tree_block_label (bb_true));
t2 = build1 (GOTO_EXPR, void_type_node, tree_block_label (bb_false));
COND_EXPR_THEN (cond) = t1;
COND_EXPR_ELSE (cond) = t2;
/* Wire the blocks together. */ /* Wire the blocks together. */
e->flags = EDGE_TRUE_VALUE; e->flags = EDGE_TRUE_VALUE;
redirect_edge_succ (e, bb_true); redirect_edge_succ (e, bb_true);
...@@ -1377,8 +1372,15 @@ expand_complex_operations_1 (block_stmt_iterator *bsi) ...@@ -1377,8 +1372,15 @@ expand_complex_operations_1 (block_stmt_iterator *bsi)
default: default:
{ {
tree lhs = GENERIC_TREE_OPERAND (stmt, 0); tree lhs, rhs;
tree rhs = GENERIC_TREE_OPERAND (stmt, 1);
/* COND_EXPR may also fallthru here, but we do not need to do anything
with it. */
if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
return;
lhs = GIMPLE_STMT_OPERAND (stmt, 0);
rhs = GIMPLE_STMT_OPERAND (stmt, 1);
if (TREE_CODE (type) == COMPLEX_TYPE) if (TREE_CODE (type) == COMPLEX_TYPE)
expand_complex_move (bsi, stmt, type, lhs, rhs); expand_complex_move (bsi, stmt, type, lhs, rhs);
......
...@@ -722,7 +722,6 @@ extern void free_omp_regions (void); ...@@ -722,7 +722,6 @@ extern void free_omp_regions (void);
#define PENDING_STMT(e) ((e)->insns.t) #define PENDING_STMT(e) ((e)->insns.t)
extern void delete_tree_cfg_annotations (void); extern void delete_tree_cfg_annotations (void);
extern void disband_implicit_edges (void);
extern bool stmt_ends_bb_p (tree); extern bool stmt_ends_bb_p (tree);
extern bool is_ctrl_stmt (tree); extern bool is_ctrl_stmt (tree);
extern bool is_ctrl_altering_stmt (tree); extern bool is_ctrl_altering_stmt (tree);
......
...@@ -291,6 +291,8 @@ tsi_split_statement_list_before (tree_stmt_iterator *i) ...@@ -291,6 +291,8 @@ tsi_split_statement_list_before (tree_stmt_iterator *i)
cur->prev = NULL; cur->prev = NULL;
if (prev) if (prev)
prev->next = NULL; prev->next = NULL;
else
STATEMENT_LIST_HEAD (old_sl) = NULL;
return new_sl; return new_sl;
} }
......
...@@ -630,9 +630,7 @@ mf_build_check_statement_for (tree base, tree limit, ...@@ -630,9 +630,7 @@ mf_build_check_statement_for (tree base, tree limit,
/* Build the conditional jump. 'cond' is just a temporary so we can /* Build the conditional jump. 'cond' is just a temporary so we can
simply build a void COND_EXPR. We do need labels in both arms though. */ simply build a void COND_EXPR. We do need labels in both arms though. */
t = build3 (COND_EXPR, void_type_node, cond, t = build3 (COND_EXPR, void_type_node, cond, NULL_TREE, NULL_TREE);
build1 (GOTO_EXPR, void_type_node, tree_block_label (then_bb)),
build1 (GOTO_EXPR, void_type_node, tree_block_label (join_bb)));
SET_EXPR_LOCUS (t, locus); SET_EXPR_LOCUS (t, locus);
tsi_link_after (&tsi, t, TSI_CONTINUE_LINKING); tsi_link_after (&tsi, t, TSI_CONTINUE_LINKING);
...@@ -685,7 +683,6 @@ mf_build_check_statement_for (tree base, tree limit, ...@@ -685,7 +683,6 @@ mf_build_check_statement_for (tree base, tree limit,
bsi_insert_after (&bsi, tsi_stmt (tsi), BSI_CONTINUE_LINKING); bsi_insert_after (&bsi, tsi_stmt (tsi), BSI_CONTINUE_LINKING);
*instr_bsi = bsi_start (join_bb); *instr_bsi = bsi_start (join_bb);
bsi_next (instr_bsi);
} }
......
...@@ -208,13 +208,10 @@ struct tree_opt_pass pass_cleanup_cfg_post_optimizing = ...@@ -208,13 +208,10 @@ struct tree_opt_pass pass_cleanup_cfg_post_optimizing =
static unsigned int static unsigned int
execute_free_datastructures (void) execute_free_datastructures (void)
{ {
/* ??? This isn't the right place for this. Worse, it got computed
more or less at random in various passes. */
free_dominance_info (CDI_DOMINATORS); free_dominance_info (CDI_DOMINATORS);
free_dominance_info (CDI_POST_DOMINATORS); free_dominance_info (CDI_POST_DOMINATORS);
/* Remove the ssa structures. Do it here since this includes statement /* Remove the ssa structures. */
annotations that need to be intact during disband_implicit_edges. */
if (cfun->gimple_df) if (cfun->gimple_df)
delete_tree_ssa (); delete_tree_ssa ();
return 0; return 0;
...@@ -241,9 +238,6 @@ struct tree_opt_pass pass_free_datastructures = ...@@ -241,9 +238,6 @@ struct tree_opt_pass pass_free_datastructures =
static unsigned int static unsigned int
execute_free_cfg_annotations (void) execute_free_cfg_annotations (void)
{ {
/* Emit gotos for implicit jumps. */
disband_implicit_edges ();
/* And get rid of annotations we no longer need. */ /* And get rid of annotations we no longer need. */
delete_tree_cfg_annotations (); delete_tree_cfg_annotations ();
......
...@@ -2958,6 +2958,29 @@ dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent, ...@@ -2958,6 +2958,29 @@ dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
{ {
edge e; edge e;
edge_iterator ei; edge_iterator ei;
tree stmt;
stmt = last_stmt (bb);
if (stmt && TREE_CODE (stmt) == COND_EXPR)
{
edge true_edge, false_edge;
/* When we are emitting the code or changing CFG, it is possible that
the edges are not yet created. When we are using debug_bb in such
a situation, we do not want it to crash. */
if (EDGE_COUNT (bb->succs) != 2)
return;
extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
INDENT (indent + 2);
pp_cfg_jump (buffer, true_edge->dest);
newline_and_indent (buffer, indent);
pp_string (buffer, "else");
newline_and_indent (buffer, indent + 2);
pp_cfg_jump (buffer, false_edge->dest);
pp_newline (buffer);
return;
}
/* If there is a fallthru edge, we may need to add an artificial goto to the /* If there is a fallthru edge, we may need to add an artificial goto to the
dump. */ dump. */
......
...@@ -731,29 +731,32 @@ determine_invariantness_stmt (struct dom_walk_data *dw_data ATTRIBUTE_UNUSED, ...@@ -731,29 +731,32 @@ determine_invariantness_stmt (struct dom_walk_data *dw_data ATTRIBUTE_UNUSED,
continue; continue;
} }
rhs = GENERIC_TREE_OPERAND (stmt, 1); if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
{
/* If divisor is invariant, convert a/b to a*(1/b), allowing reciprocal rhs = GIMPLE_STMT_OPERAND (stmt, 1);
to be hoisted out of loop, saving expensive divide. */
if (pos == MOVE_POSSIBLE /* If divisor is invariant, convert a/b to a*(1/b), allowing reciprocal
&& TREE_CODE (rhs) == RDIV_EXPR to be hoisted out of loop, saving expensive divide. */
&& flag_unsafe_math_optimizations if (pos == MOVE_POSSIBLE
&& !flag_trapping_math && TREE_CODE (rhs) == RDIV_EXPR
&& outermost_invariant_loop_expr (TREE_OPERAND (rhs, 1), && flag_unsafe_math_optimizations
loop_containing_stmt (stmt)) != NULL && !flag_trapping_math
&& outermost_invariant_loop_expr (rhs, && outermost_invariant_loop_expr (TREE_OPERAND (rhs, 1),
loop_containing_stmt (stmt)) == NULL) loop_containing_stmt (stmt)) != NULL
stmt = rewrite_reciprocal (&bsi); && outermost_invariant_loop_expr (rhs,
loop_containing_stmt (stmt)) == NULL)
/* If the shift count is invariant, convert (A >> B) & 1 to stmt = rewrite_reciprocal (&bsi);
A & (1 << B) allowing the bit mask to be hoisted out of the loop
saving an expensive shift. */ /* If the shift count is invariant, convert (A >> B) & 1 to
if (pos == MOVE_POSSIBLE A & (1 << B) allowing the bit mask to be hoisted out of the loop
&& TREE_CODE (rhs) == BIT_AND_EXPR saving an expensive shift. */
&& integer_onep (TREE_OPERAND (rhs, 1)) if (pos == MOVE_POSSIBLE
&& TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME && TREE_CODE (rhs) == BIT_AND_EXPR
&& has_single_use (TREE_OPERAND (rhs, 0))) && integer_onep (TREE_OPERAND (rhs, 1))
stmt = rewrite_bittest (&bsi); && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME
&& has_single_use (TREE_OPERAND (rhs, 0)))
stmt = rewrite_bittest (&bsi);
}
stmt_ann (stmt)->common.aux = xcalloc (1, sizeof (struct lim_aux_data)); stmt_ann (stmt)->common.aux = xcalloc (1, sizeof (struct lim_aux_data));
LIM_DATA (stmt)->always_executed_in = outermost; LIM_DATA (stmt)->always_executed_in = outermost;
......
...@@ -604,17 +604,6 @@ tree_duplicate_loop_to_header_edge (struct loop *loop, edge e, ...@@ -604,17 +604,6 @@ tree_duplicate_loop_to_header_edge (struct loop *loop, edge e,
return true; return true;
} }
/* Build if (COND) goto THEN_LABEL; else goto ELSE_LABEL; */
static tree
build_if_stmt (tree cond, tree then_label, tree else_label)
{
return build3 (COND_EXPR, void_type_node,
cond,
build1 (GOTO_EXPR, void_type_node, then_label),
build1 (GOTO_EXPR, void_type_node, else_label));
}
/* Returns true if we can unroll LOOP FACTOR times. Number /* Returns true if we can unroll LOOP FACTOR times. Number
of iterations of the loop is returned in NITER. */ of iterations of the loop is returned in NITER. */
...@@ -932,9 +921,9 @@ tree_transform_and_unroll_loop (struct loop *loop, unsigned factor, ...@@ -932,9 +921,9 @@ tree_transform_and_unroll_loop (struct loop *loop, unsigned factor,
REG_BR_PROB_BASE - exit->probability); REG_BR_PROB_BASE - exit->probability);
bsi = bsi_last (exit_bb); bsi = bsi_last (exit_bb);
exit_if = build_if_stmt (boolean_true_node, exit_if = build3 (COND_EXPR, void_type_node, boolean_true_node,
tree_block_label (loop->latch), NULL_TREE, NULL_TREE);
tree_block_label (rest));
bsi_insert_after (&bsi, exit_if, BSI_NEW_STMT); bsi_insert_after (&bsi, exit_if, BSI_NEW_STMT);
new_exit = make_edge (exit_bb, rest, EDGE_FALSE_VALUE | irr); new_exit = make_edge (exit_bb, rest, EDGE_FALSE_VALUE | irr);
rescan_loop_exit (new_exit, true, false); rescan_loop_exit (new_exit, true, false);
......
...@@ -767,12 +767,8 @@ slpeel_make_loop_iterate_ntimes (struct loop *loop, tree niters) ...@@ -767,12 +767,8 @@ slpeel_make_loop_iterate_ntimes (struct loop *loop, tree niters)
block_stmt_iterator loop_cond_bsi; block_stmt_iterator loop_cond_bsi;
block_stmt_iterator incr_bsi; block_stmt_iterator incr_bsi;
bool insert_after; bool insert_after;
tree begin_label = tree_block_label (loop->latch);
tree exit_label = tree_block_label (single_exit (loop)->dest);
tree init = build_int_cst (TREE_TYPE (niters), 0); tree init = build_int_cst (TREE_TYPE (niters), 0);
tree step = build_int_cst (TREE_TYPE (niters), 1); tree step = build_int_cst (TREE_TYPE (niters), 1);
tree then_label;
tree else_label;
LOC loop_loc; LOC loop_loc;
orig_cond = get_loop_exit_condition (loop); orig_cond = get_loop_exit_condition (loop);
...@@ -784,20 +780,12 @@ slpeel_make_loop_iterate_ntimes (struct loop *loop, tree niters) ...@@ -784,20 +780,12 @@ slpeel_make_loop_iterate_ntimes (struct loop *loop, tree niters)
&incr_bsi, insert_after, &indx_before_incr, &indx_after_incr); &incr_bsi, insert_after, &indx_before_incr, &indx_after_incr);
if (exit_edge->flags & EDGE_TRUE_VALUE) /* 'then' edge exits the loop. */ if (exit_edge->flags & EDGE_TRUE_VALUE) /* 'then' edge exits the loop. */
{ cond = build2 (GE_EXPR, boolean_type_node, indx_after_incr, niters);
cond = build2 (GE_EXPR, boolean_type_node, indx_after_incr, niters);
then_label = build1 (GOTO_EXPR, void_type_node, exit_label);
else_label = build1 (GOTO_EXPR, void_type_node, begin_label);
}
else /* 'then' edge loops back. */ else /* 'then' edge loops back. */
{ cond = build2 (LT_EXPR, boolean_type_node, indx_after_incr, niters);
cond = build2 (LT_EXPR, boolean_type_node, indx_after_incr, niters);
then_label = build1 (GOTO_EXPR, void_type_node, begin_label);
else_label = build1 (GOTO_EXPR, void_type_node, exit_label);
}
cond_stmt = build3 (COND_EXPR, TREE_TYPE (orig_cond), cond, cond_stmt = build3 (COND_EXPR, TREE_TYPE (orig_cond), cond,
then_label, else_label); NULL_TREE, NULL_TREE);
bsi_insert_before (&loop_cond_bsi, cond_stmt, BSI_SAME_STMT); bsi_insert_before (&loop_cond_bsi, cond_stmt, BSI_SAME_STMT);
/* Remove old loop exit test: */ /* Remove old loop exit test: */
...@@ -935,19 +923,15 @@ slpeel_add_loop_guard (basic_block guard_bb, tree cond, basic_block exit_bb, ...@@ -935,19 +923,15 @@ slpeel_add_loop_guard (basic_block guard_bb, tree cond, basic_block exit_bb,
{ {
block_stmt_iterator bsi; block_stmt_iterator bsi;
edge new_e, enter_e; edge new_e, enter_e;
tree cond_stmt, then_label, else_label; tree cond_stmt;
enter_e = EDGE_SUCC (guard_bb, 0); enter_e = EDGE_SUCC (guard_bb, 0);
enter_e->flags &= ~EDGE_FALLTHRU; enter_e->flags &= ~EDGE_FALLTHRU;
enter_e->flags |= EDGE_FALSE_VALUE; enter_e->flags |= EDGE_FALSE_VALUE;
bsi = bsi_last (guard_bb); bsi = bsi_last (guard_bb);
then_label = build1 (GOTO_EXPR, void_type_node,
tree_block_label (exit_bb));
else_label = build1 (GOTO_EXPR, void_type_node,
tree_block_label (enter_e->dest));
cond_stmt = build3 (COND_EXPR, void_type_node, cond, cond_stmt = build3 (COND_EXPR, void_type_node, cond,
then_label, else_label); NULL_TREE, NULL_TREE);
bsi_insert_after (&bsi, cond_stmt, BSI_NEW_STMT); bsi_insert_after (&bsi, cond_stmt, BSI_NEW_STMT);
/* Add new edge to connect guard block to the merge/loop-exit block. */ /* Add new edge to connect guard block to the merge/loop-exit block. */
new_e = make_edge (guard_bb, exit_bb, EDGE_TRUE_VALUE); new_e = make_edge (guard_bb, exit_bb, EDGE_TRUE_VALUE);
......
...@@ -3128,7 +3128,16 @@ build3_stat (enum tree_code code, tree tt, tree arg0, tree arg1, ...@@ -3128,7 +3128,16 @@ build3_stat (enum tree_code code, tree tt, tree arg0, tree arg1,
t = make_node_stat (code PASS_MEM_STAT); t = make_node_stat (code PASS_MEM_STAT);
TREE_TYPE (t) = tt; TREE_TYPE (t) = tt;
side_effects = TREE_SIDE_EFFECTS (t); /* As a special exception, if COND_EXPR has NULL branches, we
assume that it is a gimple statement and always consider
it to have side effects. */
if (code == COND_EXPR
&& tt == void_type_node
&& arg1 == NULL_TREE
&& arg2 == NULL_TREE)
side_effects = true;
else
side_effects = TREE_SIDE_EFFECTS (t);
PROCESS_ARG(0); PROCESS_ARG(0);
PROCESS_ARG(1); PROCESS_ARG(1);
......
...@@ -527,8 +527,7 @@ tree_divmod_fixed_value (tree stmt, tree operation, ...@@ -527,8 +527,7 @@ tree_divmod_fixed_value (tree stmt, tree operation,
stmt2 = build_gimple_modify_stmt (tmp1, op2); stmt2 = build_gimple_modify_stmt (tmp1, op2);
stmt3 = build3 (COND_EXPR, void_type_node, stmt3 = build3 (COND_EXPR, void_type_node,
build2 (NE_EXPR, boolean_type_node, tmp1, tmpv), build2 (NE_EXPR, boolean_type_node, tmp1, tmpv),
build1 (GOTO_EXPR, void_type_node, label_decl2), NULL_TREE, NULL_TREE);
build1 (GOTO_EXPR, void_type_node, label_decl1));
bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT); bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT); bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT);
bsi_insert_before (&bsi, stmt3, BSI_SAME_STMT); bsi_insert_before (&bsi, stmt3, BSI_SAME_STMT);
...@@ -689,8 +688,7 @@ tree_mod_pow2 (tree stmt, tree operation, tree op1, tree op2, int prob, ...@@ -689,8 +688,7 @@ tree_mod_pow2 (tree stmt, tree operation, tree op1, tree op2, int prob,
stmt4 = build3 (COND_EXPR, void_type_node, stmt4 = build3 (COND_EXPR, void_type_node,
build2 (NE_EXPR, boolean_type_node, build2 (NE_EXPR, boolean_type_node,
tmp3, build_int_cst (optype, 0)), tmp3, build_int_cst (optype, 0)),
build1 (GOTO_EXPR, void_type_node, label_decl2), NULL_TREE, NULL_TREE);
build1 (GOTO_EXPR, void_type_node, label_decl1));
bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT); bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT);
bsi_insert_before (&bsi, stmt3, BSI_SAME_STMT); bsi_insert_before (&bsi, stmt3, BSI_SAME_STMT);
bsi_insert_before (&bsi, stmt4, BSI_SAME_STMT); bsi_insert_before (&bsi, stmt4, BSI_SAME_STMT);
...@@ -845,9 +843,7 @@ tree_mod_subtract (tree stmt, tree operation, tree op1, tree op2, ...@@ -845,9 +843,7 @@ tree_mod_subtract (tree stmt, tree operation, tree op1, tree op2,
stmt2 = build_gimple_modify_stmt (tmp1, op2); stmt2 = build_gimple_modify_stmt (tmp1, op2);
stmt3 = build3 (COND_EXPR, void_type_node, stmt3 = build3 (COND_EXPR, void_type_node,
build2 (LT_EXPR, boolean_type_node, result, tmp1), build2 (LT_EXPR, boolean_type_node, result, tmp1),
build1 (GOTO_EXPR, void_type_node, label_decl3), NULL_TREE, NULL_TREE);
build1 (GOTO_EXPR, void_type_node,
ncounts ? label_decl1 : label_decl2));
bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT); bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT); bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT);
bsi_insert_before (&bsi, stmt3, BSI_SAME_STMT); bsi_insert_before (&bsi, stmt3, BSI_SAME_STMT);
...@@ -861,8 +857,7 @@ tree_mod_subtract (tree stmt, tree operation, tree op1, tree op2, ...@@ -861,8 +857,7 @@ tree_mod_subtract (tree stmt, tree operation, tree op1, tree op2,
result, tmp1)); result, tmp1));
stmt2 = build3 (COND_EXPR, void_type_node, stmt2 = build3 (COND_EXPR, void_type_node,
build2 (LT_EXPR, boolean_type_node, result, tmp1), build2 (LT_EXPR, boolean_type_node, result, tmp1),
build1 (GOTO_EXPR, void_type_node, label_decl3), NULL_TREE, NULL_TREE);
build1 (GOTO_EXPR, void_type_node, label_decl2));
bsi_insert_before (&bsi, label1, BSI_SAME_STMT); bsi_insert_before (&bsi, label1, BSI_SAME_STMT);
bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT); bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT); bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT);
...@@ -1084,8 +1079,7 @@ tree_ic (tree stmt, tree call, struct cgraph_node* direct_call, ...@@ -1084,8 +1079,7 @@ tree_ic (tree stmt, tree call, struct cgraph_node* direct_call,
stmt2 = build_gimple_modify_stmt (tmp1, tmp); stmt2 = build_gimple_modify_stmt (tmp1, tmp);
stmt3 = build3 (COND_EXPR, void_type_node, stmt3 = build3 (COND_EXPR, void_type_node,
build2 (NE_EXPR, boolean_type_node, tmp1, tmpv), build2 (NE_EXPR, boolean_type_node, tmp1, tmpv),
build1 (GOTO_EXPR, void_type_node, label_decl2), NULL_TREE, NULL_TREE);
build1 (GOTO_EXPR, void_type_node, label_decl1));
bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT); bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT); bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT);
bsi_insert_before (&bsi, stmt3, BSI_SAME_STMT); bsi_insert_before (&bsi, stmt3, BSI_SAME_STMT);
...@@ -1288,8 +1282,7 @@ tree_stringop_fixed_value (tree stmt, tree value, int prob, gcov_type count, ...@@ -1288,8 +1282,7 @@ tree_stringop_fixed_value (tree stmt, tree value, int prob, gcov_type count,
stmt2 = build_gimple_modify_stmt (tmp1, blck_size); stmt2 = build_gimple_modify_stmt (tmp1, blck_size);
stmt3 = build3 (COND_EXPR, void_type_node, stmt3 = build3 (COND_EXPR, void_type_node,
build2 (NE_EXPR, boolean_type_node, tmp1, tmpv), build2 (NE_EXPR, boolean_type_node, tmp1, tmpv),
build1 (GOTO_EXPR, void_type_node, label_decl2), NULL_TREE, NULL_TREE);
build1 (GOTO_EXPR, void_type_node, label_decl1));
bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT); bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT); bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT);
bsi_insert_before (&bsi, stmt3, BSI_SAME_STMT); bsi_insert_before (&bsi, stmt3, BSI_SAME_STMT);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment