aboutsummaryrefslogtreecommitdiff
path: root/gcc/ifcvt.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ifcvt.c')
-rw-r--r--gcc/ifcvt.c86
1 files changed, 38 insertions, 48 deletions
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index bdb44c4..08ec087 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -106,7 +106,7 @@ static int find_if_case_2 PARAMS ((basic_block, edge, edge));
static int find_cond_trap PARAMS ((basic_block, edge, edge));
static int find_memory PARAMS ((rtx *, void *));
static int dead_or_predicable PARAMS ((basic_block, basic_block,
- basic_block, rtx, int));
+ basic_block, basic_block, int));
static void noce_emit_move_insn PARAMS ((rtx, rtx));
/* Abuse the basic_block AUX field to store the original block index,
@@ -2183,9 +2183,8 @@ find_if_case_1 (test_bb, then_edge, else_edge)
edge then_edge, else_edge;
{
basic_block then_bb = then_edge->dest;
- basic_block else_bb = else_edge->dest;
+ basic_block else_bb = else_edge->dest, new_bb;
edge then_succ = then_bb->succ;
- rtx new_lab;
/* THEN has one successor. */
if (!then_succ || then_succ->succ_next != NULL)
@@ -2199,8 +2198,8 @@ find_if_case_1 (test_bb, then_edge, else_edge)
if (then_bb->pred->pred_next != NULL)
return FALSE;
- /* ELSE follows THEN. (??? could be moved) */
- if (else_bb->index != then_bb->index + 1)
+ /* THEN must do something. */
+ if (forwarder_block_p (then_bb))
return FALSE;
num_possible_if_blocks++;
@@ -2213,18 +2212,9 @@ find_if_case_1 (test_bb, then_edge, else_edge)
if (count_bb_insns (then_bb) > BRANCH_COST)
return FALSE;
- /* Find the label for THEN's destination. */
- if (then_succ->dest == EXIT_BLOCK_PTR)
- new_lab = NULL_RTX;
- else
- {
- new_lab = JUMP_LABEL (then_bb->end);
- if (! new_lab)
- abort ();
- }
-
/* Registers set are dead, or are predicable. */
- if (! dead_or_predicable (test_bb, then_bb, else_bb, new_lab, 1))
+ if (! dead_or_predicable (test_bb, then_bb, else_bb,
+ then_bb->succ->dest, 1))
return FALSE;
/* Conversion went ok, including moving the insns and fixing up the
@@ -2235,9 +2225,17 @@ find_if_case_1 (test_bb, then_edge, else_edge)
else_bb->global_live_at_start,
then_bb->global_live_at_end, BITMAP_IOR);
- make_edge (NULL, test_bb, then_succ->dest, 0);
+ new_bb = redirect_edge_and_branch_force (FALLTHRU_EDGE (test_bb), else_bb);
+ /* Make rest of code believe that the newly created block is the THEN_BB
+ block we are going to remove. */
+ if (new_bb)
+ {
+ new_bb->aux = then_bb->aux;
+ SET_UPDATE_LIFE (then_bb);
+ }
flow_delete_block (then_bb);
- tidy_fallthru_edge (else_edge, test_bb, else_bb);
+ /* We've possibly created jump to next insn, cleanup_cfg will solve that
+ later. */
num_removed_blocks++;
num_updated_if_blocks++;
@@ -2255,7 +2253,7 @@ find_if_case_2 (test_bb, then_edge, else_edge)
basic_block then_bb = then_edge->dest;
basic_block else_bb = else_edge->dest;
edge else_succ = else_bb->succ;
- rtx new_lab, note;
+ rtx note;
/* ELSE has one successor. */
if (!else_succ || else_succ->succ_next != NULL)
@@ -2294,27 +2292,8 @@ find_if_case_2 (test_bb, then_edge, else_edge)
if (count_bb_insns (then_bb) > BRANCH_COST)
return FALSE;
- /* Find the label for ELSE's destination. */
- if (else_succ->dest == EXIT_BLOCK_PTR)
- new_lab = NULL_RTX;
- else
- {
- if (else_succ->flags & EDGE_FALLTHRU)
- {
- new_lab = else_succ->dest->head;
- if (GET_CODE (new_lab) != CODE_LABEL)
- abort ();
- }
- else
- {
- new_lab = JUMP_LABEL (else_bb->end);
- if (! new_lab)
- abort ();
- }
- }
-
/* Registers set are dead, or are predicable. */
- if (! dead_or_predicable (test_bb, else_bb, then_bb, new_lab, 0))
+ if (! dead_or_predicable (test_bb, else_bb, then_bb, else_succ->dest, 0))
return FALSE;
/* Conversion went ok, including moving the insns and fixing up the
@@ -2325,8 +2304,6 @@ find_if_case_2 (test_bb, then_edge, else_edge)
then_bb->global_live_at_start,
else_bb->global_live_at_end, BITMAP_IOR);
- remove_edge (else_edge);
- make_edge (NULL, test_bb, else_succ->dest, 0);
flow_delete_block (else_bb);
num_removed_blocks++;
@@ -2360,10 +2337,10 @@ find_memory (px, data)
static int
dead_or_predicable (test_bb, merge_bb, other_bb, new_dest, reversep)
basic_block test_bb, merge_bb, other_bb;
- rtx new_dest;
+ basic_block new_dest;
int reversep;
{
- rtx head, end, jump, earliest, old_dest;
+ rtx head, end, jump, earliest, old_dest, new_label;
jump = test_bb->end;
@@ -2548,9 +2525,10 @@ dead_or_predicable (test_bb, merge_bb, other_bb, new_dest, reversep)
change group management. */
old_dest = JUMP_LABEL (jump);
+ new_label = block_label (new_dest);
if (reversep
- ? ! invert_jump_1 (jump, new_dest)
- : ! redirect_jump_1 (jump, new_dest))
+ ? ! invert_jump_1 (jump, new_label)
+ : ! redirect_jump_1 (jump, new_label))
goto cancel;
if (! apply_change_group ())
@@ -2558,13 +2536,25 @@ dead_or_predicable (test_bb, merge_bb, other_bb, new_dest, reversep)
if (old_dest)
LABEL_NUSES (old_dest) -= 1;
- if (new_dest)
- LABEL_NUSES (new_dest) += 1;
- JUMP_LABEL (jump) = new_dest;
+ if (new_label)
+ LABEL_NUSES (new_label) += 1;
+ JUMP_LABEL (jump) = new_label;
if (reversep)
invert_br_probabilities (jump);
+ redirect_edge_succ (BRANCH_EDGE (test_bb), new_dest);
+ if (reversep)
+ {
+ gcov_type count, probability;
+ count = BRANCH_EDGE (test_bb)->count;
+ BRANCH_EDGE (test_bb)->count = FALLTHRU_EDGE (test_bb)->count;
+ FALLTHRU_EDGE (test_bb)->count = count;
+ probability = BRANCH_EDGE (test_bb)->probability;
+ BRANCH_EDGE (test_bb)->probability = FALLTHRU_EDGE (test_bb)->probability;
+ FALLTHRU_EDGE (test_bb)->probability = probability;
+ }
+
/* Move the insns out of MERGE_BB to before the branch. */
if (head != NULL)
{