X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fifcvt.c;h=a5494b85f6f49f21beed90cc83c084e224aca40a;hb=a6d2110e40dacd2544907a3b46ed516585c6e67e;hp=33c1918313278e505406ce660021b1328cbd6931;hpb=0bb604cafe6928727adf8950d6e36793ce7ff880;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index 33c19183132..a5494b85f6f 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -27,10 +27,10 @@ #include "flags.h" #include "insn-config.h" #include "recog.h" +#include "hard-reg-set.h" #include "basic-block.h" #include "expr.h" #include "output.h" -#include "hard-reg-set.h" #include "tm_p.h" @@ -51,8 +51,6 @@ #define MAX_CONDITIONAL_EXECUTE (BRANCH_COST + 1) #endif -#define EDGE_COMPLEX (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_EH) - #define NULL_EDGE ((struct edge_def *)NULL) #define NULL_BLOCK ((struct basic_block_def *)NULL) @@ -73,8 +71,9 @@ static sbitmap *post_dominators; static int count_bb_insns PARAMS ((basic_block)); static rtx first_active_insn PARAMS ((basic_block)); static int last_active_insn_p PARAMS ((basic_block, rtx)); +static int seq_contains_jump PARAMS ((rtx)); -static int cond_exec_process_insns PARAMS ((rtx, rtx, rtx, int)); +static int cond_exec_process_insns PARAMS ((rtx, rtx, rtx, rtx, int)); static rtx cond_exec_get_condition PARAMS ((rtx)); static int cond_exec_process_if_block PARAMS ((basic_block, basic_block, basic_block, basic_block)); @@ -173,20 +172,40 @@ last_active_insn_p (bb, insn) return GET_CODE (insn) == JUMP_INSN; } + +/* It is possible, especially when having dealt with multi-word + arithmetic, for the expanders to have emitted jumps. Search + through the sequence and return TRUE if a jump exists so that + we can abort the conversion. */ + +static int +seq_contains_jump (insn) + rtx insn; +{ + while (insn) + { + if (GET_CODE (insn) == JUMP_INSN) + return 1; + insn = NEXT_INSN (insn); + } + return 0; +} /* Go through a bunch of insns, converting them to conditional execution format if possible. Return TRUE if all of the non-note insns were processed. */ static int -cond_exec_process_insns (start, end, test, mod_ok) +cond_exec_process_insns (start, end, test, prob_val, mod_ok) rtx start; /* first insn to look at */ rtx end; /* last insn to look at */ rtx test; /* conditional execution test */ + rtx prob_val; /* probability of branch taken. */ int mod_ok; /* true if modifications ok last insn. */ { int must_be_last = FALSE; rtx insn; + rtx pattern; for (insn = start; ; insn = NEXT_INSN (insn)) { @@ -196,6 +215,17 @@ cond_exec_process_insns (start, end, test, mod_ok) if (GET_CODE (insn) != INSN && GET_CODE (insn) != CALL_INSN) abort (); + /* Remove USE insns that get in the way. */ + if (reload_completed && GET_CODE (PATTERN (insn)) == USE) + { + /* ??? Ug. Actually unlinking the thing is problematic, + given what we'd have to coordinate with our callers. */ + PUT_CODE (insn, NOTE); + NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED; + NOTE_SOURCE_FILE (insn) = 0; + goto insn_done; + } + /* Last insn wasn't last? */ if (must_be_last) return FALSE; @@ -208,9 +238,25 @@ cond_exec_process_insns (start, end, test, mod_ok) } /* Now build the conditional form of the instruction. */ + pattern = PATTERN (insn); + + /* If the machine needs to modify the insn being conditionally executed, + say for example to force a constant integer operand into a temp + register, do so here. */ +#ifdef IFCVT_MODIFY_INSN + IFCVT_MODIFY_INSN (pattern, insn); + if (! pattern) + return FALSE; +#endif + validate_change (insn, &PATTERN (insn), gen_rtx_COND_EXEC (VOIDmode, copy_rtx (test), - PATTERN (insn)), 1); + pattern), 1); + + if (GET_CODE (insn) == CALL_INSN && prob_val) + validate_change (insn, ®_NOTES (insn), + alloc_EXPR_LIST (REG_BR_PROB, prob_val, + REG_NOTES (insn)), 1); insn_done: if (insn == end) @@ -228,10 +274,8 @@ cond_exec_get_condition (jump) { rtx test_if, cond; - if (condjump_p (jump)) - test_if = SET_SRC (PATTERN (jump)); - else if (condjump_in_parallel_p (jump)) - test_if = SET_SRC (XVECEXP (PATTERN (jump), 0, 0)); + if (any_condjump_p (jump)) + test_if = SET_SRC (pc_set (jump)); else return NULL_RTX; cond = XEXP (test_if, 0); @@ -261,12 +305,14 @@ cond_exec_process_if_block (test_bb, then_bb, else_bb, join_bb) rtx test_expr; /* expression in IF_THEN_ELSE that is tested */ rtx then_start; /* first insn in THEN block */ rtx then_end; /* last insn + 1 in THEN block */ - rtx else_start; /* first insn in ELSE block or NULL */ - rtx else_end; /* last insn + 1 in ELSE block */ + rtx else_start = NULL_RTX; /* first insn in ELSE block or NULL */ + rtx else_end = NULL_RTX; /* last insn + 1 in ELSE block */ int max; /* max # of insns to convert. */ int then_mod_ok; /* whether conditional mods are ok in THEN */ rtx true_expr; /* test for else block insns */ rtx false_expr; /* test for then block insns */ + rtx true_prob_val; /* probability of else block */ + rtx false_prob_val; /* probability of then block */ int n_insns; /* Find the conditional jump to the ELSE or JOIN part, and isolate @@ -275,11 +321,20 @@ cond_exec_process_if_block (test_bb, then_bb, else_bb, join_bb) if (! test_expr) return FALSE; + /* If the conditional jump is more than just a conditional jump, + then we can not do conditional execution conversion on this block. */ + if (!onlyjump_p (test_bb->end)) + return FALSE; + /* Collect the bounds of where we're to search. */ then_start = then_bb->head; then_end = then_bb->end; + /* Skip a label heading THEN block. */ + if (GET_CODE (then_start) == CODE_LABEL) + then_start = NEXT_INSN (then_start); + /* Skip a (use (const_int 0)) or branch as the final insn. */ if (GET_CODE (then_end) == INSN && GET_CODE (PATTERN (then_end)) == USE @@ -324,6 +379,26 @@ cond_exec_process_if_block (test_bb, then_bb, else_bb, join_bb) GET_MODE (true_expr), XEXP (true_expr, 0), XEXP (true_expr, 1)); +#ifdef IFCVT_MODIFY_TESTS + /* If the machine description needs to modify the tests, such as setting a + conditional execution register from a comparison, it can do so here. */ + IFCVT_MODIFY_TESTS (true_expr, false_expr, test_bb, then_bb, else_bb, + join_bb); + + /* See if the conversion failed */ + if (!true_expr || !false_expr) + goto fail; +#endif + + true_prob_val = find_reg_note (test_bb->end, REG_BR_PROB, NULL_RTX); + if (true_prob_val) + { + true_prob_val = XEXP (true_prob_val, 0); + false_prob_val = GEN_INT (REG_BR_PROB_BASE - INTVAL (true_prob_val)); + } + else + false_prob_val = NULL_RTX; + /* For IF-THEN-ELSE blocks, we don't allow modifications of the test on then THEN block. */ then_mod_ok = (else_bb == NULL_BLOCK); @@ -333,17 +408,22 @@ cond_exec_process_if_block (test_bb, then_bb, else_bb, join_bb) if (then_end && ! cond_exec_process_insns (then_start, then_end, - false_expr, then_mod_ok)) + false_expr, false_prob_val, then_mod_ok)) goto fail; if (else_bb && ! cond_exec_process_insns (else_start, else_end, - true_expr, TRUE)) + true_expr, true_prob_val, TRUE)) goto fail; if (! apply_change_group ()) return FALSE; +#ifdef IFCVT_MODIFY_FINAL + /* Do any machine dependent final modifications */ + IFCVT_MODIFY_FINAL (test_bb, then_bb, else_bb, join_bb); +#endif + /* Conversion succeeded. */ if (rtl_dump_file) fprintf (rtl_dump_file, "%d insn%s converted to conditional execution.\n", @@ -354,6 +434,11 @@ cond_exec_process_if_block (test_bb, then_bb, else_bb, join_bb) return TRUE; fail: +#ifdef IFCVT_MODIFY_CANCEL + /* Cancel any machine dependent changes. */ + IFCVT_MODIFY_CANCEL (test_bb, then_bb, else_bb, join_bb); +#endif + cancel_changes (0); return FALSE; } @@ -402,7 +487,7 @@ noce_emit_store_flag (if_info, x, reversep, normalize) build the store_flag insn directly. */ if (cond_complex) - cond = XEXP (SET_SRC (PATTERN (if_info->jump)), 0); + cond = XEXP (SET_SRC (pc_set (if_info->jump)), 0); if ((if_info->cond_earliest == if_info->jump || cond_complex) && (normalize == 0 || STORE_FLAG_VALUE == normalize)) @@ -605,6 +690,10 @@ noce_try_store_flag_constants (if_info) seq = get_insns (); end_sequence (); + + if (seq_contains_jump (seq)) + return FALSE; + emit_insns_before (seq, if_info->cond_earliest); return TRUE; @@ -659,6 +748,10 @@ noce_try_store_flag_inc (if_info) seq = get_insns (); end_sequence (); + + if (seq_contains_jump (seq)) + return FALSE; + emit_insns_before (seq, if_info->cond_earliest); return TRUE; @@ -706,6 +799,10 @@ noce_try_store_flag_mask (if_info) seq = get_insns (); end_sequence (); + + if (seq_contains_jump (seq)) + return FALSE; + emit_insns_before (seq, if_info->cond_earliest); return TRUE; @@ -758,10 +855,18 @@ noce_emit_cmove (if_info, x, code, cmp_a, cmp_b, vfalse, vtrue) || ! general_operand (cmp_b, GET_MODE (cmp_b))) return NULL_RTX; +#if HAVE_conditional_move return emit_conditional_move (x, code, cmp_a, cmp_b, VOIDmode, vtrue, vfalse, GET_MODE (x), (code == LTU || code == GEU || code == LEU || code == GTU)); +#else + /* We'll never get here, as noce_process_if_block doesn't call the + functions involved. Ifdef code, however, should be discouraged + because it leads to typos in the code not selected. However, + emit_conditional_move won't exist either. */ + return NULL_RTX; +#endif } /* Try only simple constants and registers here. More complex cases @@ -835,9 +940,9 @@ noce_try_cmove_arith (if_info) } /* ??? We could handle this if we knew that a load from A or B could - not fault. This is true of stack memories or if we've already loaded + not fault. This is also true if we've already loaded from the address along the path from ENTRY. */ - else if (GET_CODE (a) == MEM || GET_CODE (b) == MEM) + else if (may_trap_p (a) || may_trap_p (b)) return FALSE; /* if (test) x = a + b; else x = c - d; @@ -972,14 +1077,17 @@ noce_get_condition (jump, earliest) rtx *earliest; { rtx cond; + rtx set; /* If the condition variable is a register and is MODE_INT, accept it. Otherwise, fall back on get_condition. */ - if (! condjump_p (jump)) + if (! any_condjump_p (jump)) return NULL_RTX; - cond = XEXP (SET_SRC (PATTERN (jump)), 0); + set = pc_set (jump); + + cond = XEXP (SET_SRC (set), 0); if (GET_CODE (XEXP (cond, 0)) == REG && GET_MODE_CLASS (GET_MODE (XEXP (cond, 0))) == MODE_INT) { @@ -987,8 +1095,8 @@ noce_get_condition (jump, earliest) /* If this branches to JUMP_LABEL when the condition is false, reverse the condition. */ - if (GET_CODE (XEXP (SET_SRC (PATTERN (jump)), 2)) == LABEL_REF - && XEXP (XEXP (SET_SRC (PATTERN (jump)), 2), 0) == JUMP_LABEL (jump)) + if (GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF + && XEXP (XEXP (SET_SRC (set), 2), 0) == JUMP_LABEL (jump)) cond = gen_rtx_fmt_ee (reverse_condition (GET_CODE (cond)), GET_MODE (cond), XEXP (cond, 0), XEXP (cond, 1)); @@ -1024,7 +1132,7 @@ noce_process_if_block (test_bb, then_bb, else_bb, join_bb) rtx insn_a, insn_b; rtx set_a, set_b; rtx orig_x, x, a, b; - rtx jump, cond; + rtx jump, cond, insn; /* If this is not a standard conditional jump, we can't parse it. */ jump = test_bb->end; @@ -1032,6 +1140,11 @@ noce_process_if_block (test_bb, then_bb, else_bb, join_bb) if (! cond) return FALSE; + /* If the conditional jump is more than just a conditional jump, + then we can not do if-conversion on this block. */ + if (! onlyjump_p (jump)) + return FALSE; + /* We must be comparing objects whose modes imply the size. */ if (GET_MODE (XEXP (cond, 0)) == BLKmode) return FALSE; @@ -1070,11 +1183,24 @@ noce_process_if_block (test_bb, then_bb, else_bb, join_bb) || GET_CODE (insn_b) != INSN || (set_b = single_set (insn_b)) == NULL_RTX || ! rtx_equal_p (x, SET_DEST (set_b)) - || reg_mentioned_p (x, cond)) + || reg_mentioned_p (x, cond) + || reg_mentioned_p (x, a) + || reg_mentioned_p (x, SET_SRC (set_b))) insn_b = set_b = NULL_RTX; } b = (set_b ? SET_SRC (set_b) : x); + /* X may not be mentioned in the range (cond_earliest, jump]. */ + for (insn = jump; insn != if_info.cond_earliest; insn = PREV_INSN (insn)) + if (INSN_P (insn) && reg_mentioned_p (x, insn)) + return FALSE; + + /* A and B may not be modified in the range [cond_earliest, jump). */ + for (insn = if_info.cond_earliest; insn != jump; insn = NEXT_INSN (insn)) + if (INSN_P (insn) + && (modified_in_p (a, insn) || modified_in_p (b, insn))) + return FALSE; + /* Only operate on register destinations, and even then avoid extending the lifetime of hard registers on small register class machines. */ orig_x = x; @@ -1120,8 +1246,13 @@ noce_process_if_block (test_bb, then_bb, else_bb, join_bb) else_bb->end = PREV_INSN (insn_b); reorder_insns (insn_b, insn_b, PREV_INSN (if_info.cond_earliest)); insn_b = NULL_RTX; - x = orig_x; } + /* If we have "x = b; if (...) x = a;", and x has side-effects, then + x must be executed twice. */ + else if (insn_b && side_effects_p (orig_x)) + return FALSE; + + x = orig_x; goto success; } @@ -1165,10 +1296,10 @@ noce_process_if_block (test_bb, then_bb, else_bb, join_bb) } /* The new insns will have been inserted before cond_earliest. We should - be able to remove cond_earliest through the jump with impunity. */ - insn_a = prev_nonnote_insn (if_info.cond_earliest); - flow_delete_insn_chain (if_info.cond_earliest, test_bb->end); - test_bb->end = insn_a; + be able to remove the jump with impunity, but the condition itself may + have been modified by gcse to be shared across basic blocks. */ + test_bb->end = PREV_INSN (jump); + flow_delete_insn (jump); /* If we used a temporary, fix it up now. */ if (orig_x != x) @@ -1178,7 +1309,7 @@ noce_process_if_block (test_bb, then_bb, else_bb, join_bb) insn_b = gen_sequence (); end_sequence (); - test_bb->end = emit_insn_after (insn_b, insn_a); + test_bb->end = emit_insn_after (insn_b, test_bb->end); } /* Merge the blocks! */ @@ -1237,37 +1368,8 @@ merge_if_block (test_bb, then_bb, else_bb, join_bb) get their addresses taken. */ if (else_bb) { - if (LABEL_NUSES (else_bb->head) == 0 - && ! LABEL_PRESERVE_P (else_bb->head) - && ! LABEL_NAME (else_bb->head)) - { - /* We can merge the ELSE. */ - merge_blocks_nomove (combo_bb, else_bb); - num_removed_blocks++; - } - else - { - /* We cannot merge the ELSE. */ - - /* Properly rewire the edge out of the now combined - TEST-THEN block to point here. */ - remove_edge (combo_bb->succ); - if (combo_bb->succ || else_bb->pred) - abort (); - make_edge (NULL, combo_bb, else_bb, EDGE_FALLTHRU); - - /* Remove the jump and cruft from the end of the TEST-THEN block. */ - tidy_fallthru_edge (combo_bb->succ, combo_bb, else_bb); - - /* Make sure we update life info properly. */ - SET_UPDATE_LIFE(combo_bb); - if (else_bb->global_live_at_end) - COPY_REG_SET (else_bb->global_live_at_start, - else_bb->global_live_at_end); - - /* The ELSE is the new combo block. */ - combo_bb = else_bb; - } + merge_blocks_nomove (combo_bb, else_bb); + num_removed_blocks++; } /* If there was no join block reported, that means it was not adjacent @@ -1287,12 +1389,13 @@ merge_if_block (test_bb, then_bb, else_bb, join_bb) abort (); } - /* The JOIN block had a label. It may have had quite a number - of other predecessors too, but probably not. See if we can - merge this with the others. */ - else if (LABEL_NUSES (join_bb->head) == 0 - && ! LABEL_PRESERVE_P (join_bb->head) - && ! LABEL_NAME (join_bb->head)) + /* The JOIN block may have had quite a number of other predecessors too. + Since we've already merged the TEST, THEN and ELSE blocks, we should + have only one remaining edge from our if-then-else diamond. If there + is more than one remaining edge, it must come from elsewhere. There + may be zero incoming edges if the THEN block didn't actually join + back up (as with a call to abort). */ + else if (join_bb->pred == NULL || join_bb->pred->pred_next == NULL) { /* We can merge the JOIN. */ if (combo_bb->global_live_at_end) @@ -1394,20 +1497,44 @@ find_if_block (test_bb, then_edge, else_edge) if (then_bb->pred->pred_next != NULL_EDGE) return FALSE; - /* The THEN block of an IF-THEN combo must have exactly one successor. */ - if (then_succ == NULL_EDGE - || then_succ->succ_next != NULL_EDGE - || (then_succ->flags & EDGE_COMPLEX)) + /* The THEN block of an IF-THEN combo must have zero or one successors. */ + if (then_succ != NULL_EDGE + && (then_succ->succ_next != NULL_EDGE + || (then_succ->flags & EDGE_COMPLEX))) return FALSE; - /* The THEN block may not start with a label, as might happen with an - unused user label that has had its address taken. */ - if (GET_CODE (then_bb->head) == CODE_LABEL) - return FALSE; + /* If the THEN block has no successors, conditional execution can still + make a conditional call. Don't do this unless the ELSE block has + only one incoming edge -- the CFG manipulation is too ugly otherwise. + Check for the last insn of the THEN block being an indirect jump, which + is listed as not having any successors, but confuses the rest of the CE + code processing. XXX we should fix this in the future. */ + if (then_succ == NULL) + { + if (else_bb->pred->pred_next == NULL_EDGE) + { + rtx last_insn = then_bb->end; + + while (last_insn + && GET_CODE (last_insn) == NOTE + && last_insn != then_bb->head) + last_insn = PREV_INSN (last_insn); + + if (last_insn + && GET_CODE (last_insn) == JUMP_INSN + && ! simplejump_p (last_insn)) + return FALSE; + + join_bb = else_bb; + else_bb = NULL_BLOCK; + } + else + return FALSE; + } /* If the THEN block's successor is the other edge out of the TEST block, then we have an IF-THEN combo without an ELSE. */ - if (then_succ->dest == else_bb) + else if (then_succ->dest == else_bb) { join_bb = else_bb; else_bb = NULL_BLOCK; @@ -1562,10 +1689,6 @@ find_if_case_1 (test_bb, then_edge, else_edge) if (then_bb->pred->pred_next != NULL) return FALSE; - /* THEN has no label. */ - if (GET_CODE (then_bb->head) == CODE_LABEL) - return FALSE; - /* ELSE follows THEN. (??? could be moved) */ if (else_bb->index != then_bb->index + 1) return FALSE; @@ -1636,10 +1759,8 @@ find_if_case_2 (test_bb, then_edge, else_edge) if (else_bb->pred->pred_next != NULL) return FALSE; - /* ELSE has a label we can delete. */ - if (LABEL_NUSES (else_bb->head) > 1 - || LABEL_PRESERVE_P (else_bb->head) - || LABEL_NAME (else_bb->head)) + /* THEN is not EXIT. */ + if (then_bb->index < 0) return FALSE; /* ELSE is predicted or SUCC(ELSE) postdominates THEN. */ @@ -1647,9 +1768,8 @@ find_if_case_2 (test_bb, then_edge, else_edge) if (note && INTVAL (XEXP (note, 0)) >= REG_BR_PROB_BASE / 2) ; else if (else_succ->dest->index < 0 - || (then_bb->index >= 0 - && TEST_BIT (post_dominators[ORIG_INDEX (then_bb)], - ORIG_INDEX (else_succ->dest)))) + || TEST_BIT (post_dominators[ORIG_INDEX (then_bb)], + ORIG_INDEX (else_succ->dest))) ; else return FALSE; @@ -1735,6 +1855,15 @@ dead_or_predicable (test_bb, merge_bb, other_bb, new_dest, reversep) { rtx head, end, jump, earliest, old_dest; + /* No code movement can occur if we'd be scrogging EH regions. + Within MERGE_BB, ensure that we've not got stray EH_BEG or EH_END + notes within the block. Between the blocks, checking that the end + region numbers match ensures that we won't disrupt the nesting + between regions. */ + if (merge_bb->eh_beg != merge_bb->eh_end + || merge_bb->eh_end != test_bb->eh_end) + return FALSE; + jump = test_bb->end; /* Find the extent of the real code in the merge block. */ @@ -1763,6 +1892,9 @@ dead_or_predicable (test_bb, merge_bb, other_bb, new_dest, reversep) end = PREV_INSN (end); } + /* Disable handling dead code by conditional execution if the machine needs + to do anything funny with the tests, etc. */ +#ifndef IFCVT_MODIFY_TESTS if (HAVE_conditional_execution) { /* In the conditional execution case, we have things easy. We know @@ -1771,20 +1903,30 @@ dead_or_predicable (test_bb, merge_bb, other_bb, new_dest, reversep) All that's left is making sure the insns involved can actually be predicated. */ - rtx cond; + rtx cond, prob_val; cond = cond_exec_get_condition (jump); + + prob_val = find_reg_note (jump, REG_BR_PROB, NULL_RTX); + if (prob_val) + prob_val = XEXP (prob_val, 0); + if (reversep) - cond = gen_rtx_fmt_ee (reverse_condition (GET_CODE (cond)), - GET_MODE (cond), XEXP (cond, 0), - XEXP (cond, 1)); + { + cond = gen_rtx_fmt_ee (reverse_condition (GET_CODE (cond)), + GET_MODE (cond), XEXP (cond, 0), + XEXP (cond, 1)); + if (prob_val) + prob_val = GEN_INT (REG_BR_PROB_BASE - INTVAL (prob_val)); + } - if (! cond_exec_process_insns (head, end, cond, 0)) + if (! cond_exec_process_insns (head, end, cond, prob_val, 0)) goto cancel; earliest = jump; } else +#endif { /* In the non-conditional execution case, we have to verify that there are no trapping operations, no calls, no references to memory, and @@ -1818,7 +1960,7 @@ dead_or_predicable (test_bb, merge_bb, other_bb, new_dest, reversep) break; } - if (! condjump_p (jump)) + if (! any_condjump_p (jump)) return FALSE; /* Find the extent of the conditional. */ @@ -1840,7 +1982,7 @@ dead_or_predicable (test_bb, merge_bb, other_bb, new_dest, reversep) /* ??? bb->local_set is only valid during calculate_global_regs_live, so we must recompute usage for MERGE_BB. Not so bad, I suppose, since we've already asserted that MERGE_BB is small. */ - propagate_block (merge_bb, tmp, merge_set, 0); + propagate_block (merge_bb, tmp, merge_set, merge_set, 0); /* For small register class machines, don't lengthen lifetimes of hard registers before reload. */ @@ -1860,7 +2002,8 @@ dead_or_predicable (test_bb, merge_bb, other_bb, new_dest, reversep) Moreover, we're interested in the insns live from OTHER_BB. */ COPY_REG_SET (test_live, other_bb->global_live_at_start); - pbi = init_propagate_block_info (test_bb, test_live, test_set, 0); + pbi = init_propagate_block_info (test_bb, test_live, test_set, test_set, + 0); for (insn = jump; ; insn = prev) { @@ -1922,11 +2065,25 @@ dead_or_predicable (test_bb, merge_bb, other_bb, new_dest, reversep) } /* Move the insns out of MERGE_BB to before the branch. */ - if (end == merge_bb->end) - merge_bb->end = merge_bb->head; if (head != NULL) { + if (end == merge_bb->end) + merge_bb->end = PREV_INSN (head); + head = squeeze_notes (head, end); + if (GET_CODE (end) == NOTE + && (NOTE_LINE_NUMBER (end) == NOTE_INSN_BLOCK_END + || NOTE_LINE_NUMBER (end) == NOTE_INSN_BLOCK_BEG + || NOTE_LINE_NUMBER (end) == NOTE_INSN_LOOP_BEG + || NOTE_LINE_NUMBER (end) == NOTE_INSN_LOOP_END + || NOTE_LINE_NUMBER (end) == NOTE_INSN_LOOP_CONT + || NOTE_LINE_NUMBER (end) == NOTE_INSN_LOOP_VTOP)) + { + if (head == end) + return TRUE; + end = PREV_INSN (end); + } + reorder_insns (head, end, PREV_INSN (earliest)); } return TRUE; @@ -1957,7 +2114,7 @@ if_convert (life_data_ok) if (HAVE_conditional_execution || life_data_ok) { post_dominators = sbitmap_vector_alloc (n_basic_blocks, n_basic_blocks); - compute_flow_dominators (NULL, post_dominators); + calculate_dominance_info (NULL, post_dominators, CDI_POST_DOMINATORS); } /* Record initial block numbers. */ @@ -1974,7 +2131,8 @@ if_convert (life_data_ok) block_num++; } - sbitmap_vector_free (post_dominators); + if (post_dominators) + sbitmap_vector_free (post_dominators); if (rtl_dump_file) fflush (rtl_dump_file); @@ -2000,8 +2158,11 @@ if_convert (life_data_ok) SET_BIT (update_life_blocks, block_num); count_or_remove_death_notes (update_life_blocks, 1); - update_life_info (update_life_blocks, UPDATE_LIFE_LOCAL, - PROP_DEATH_NOTES); + /* ??? See about adding a mode that verifies that the initial + set of blocks don't let registers come live. */ + update_life_info (update_life_blocks, UPDATE_LIFE_GLOBAL, + PROP_DEATH_NOTES | PROP_SCAN_DEAD_CODE + | PROP_KILL_DEAD_CODE); sbitmap_free (update_life_blocks); } @@ -2020,5 +2181,7 @@ if_convert (life_data_ok) num_removed_blocks); } +#ifdef ENABLE_CHECKING verify_flow_info (); +#endif }