Mercurial > hg > CbC > CbC_gcc
comparison gcc/sel-sched.c @ 69:1b10fe6932e1
merge 69
author | Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 21 Aug 2011 07:53:12 +0900 |
parents | f6334be47118 |
children | 04ced10e8804 |
comparison
equal
deleted
inserted
replaced
66:b362627d71ba | 69:1b10fe6932e1 |
---|---|
1 /* Instruction scheduling pass. Selective scheduler and pipeliner. | 1 /* Instruction scheduling pass. Selective scheduler and pipeliner. |
2 Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc. | 2 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 |
3 Free Software Foundation, Inc. | |
3 | 4 |
4 This file is part of GCC. | 5 This file is part of GCC. |
5 | 6 |
6 GCC is free software; you can redistribute it and/or modify it under | 7 GCC is free software; you can redistribute it and/or modify it under |
7 the terms of the GNU General Public License as published by the Free | 8 the terms of the GNU General Public License as published by the Free |
19 | 20 |
20 #include "config.h" | 21 #include "config.h" |
21 #include "system.h" | 22 #include "system.h" |
22 #include "coretypes.h" | 23 #include "coretypes.h" |
23 #include "tm.h" | 24 #include "tm.h" |
24 #include "toplev.h" | 25 #include "rtl-error.h" |
25 #include "rtl.h" | |
26 #include "tm_p.h" | 26 #include "tm_p.h" |
27 #include "hard-reg-set.h" | 27 #include "hard-reg-set.h" |
28 #include "regs.h" | 28 #include "regs.h" |
29 #include "function.h" | 29 #include "function.h" |
30 #include "flags.h" | 30 #include "flags.h" |
31 #include "insn-config.h" | 31 #include "insn-config.h" |
32 #include "insn-attr.h" | 32 #include "insn-attr.h" |
33 #include "except.h" | 33 #include "except.h" |
34 #include "toplev.h" | |
35 #include "recog.h" | 34 #include "recog.h" |
36 #include "params.h" | 35 #include "params.h" |
37 #include "target.h" | 36 #include "target.h" |
38 #include "output.h" | 37 #include "output.h" |
39 #include "timevar.h" | 38 #include "timevar.h" |
43 #include "tree.h" | 42 #include "tree.h" |
44 #include "vec.h" | 43 #include "vec.h" |
45 #include "langhooks.h" | 44 #include "langhooks.h" |
46 #include "rtlhooks-def.h" | 45 #include "rtlhooks-def.h" |
47 #include "output.h" | 46 #include "output.h" |
47 #include "emit-rtl.h" | |
48 | 48 |
49 #ifdef INSN_SCHEDULING | 49 #ifdef INSN_SCHEDULING |
50 #include "sel-sched-ir.h" | 50 #include "sel-sched-ir.h" |
51 #include "sel-sched-dump.h" | 51 #include "sel-sched-dump.h" |
52 #include "sel-sched.h" | 52 #include "sel-sched.h" |
586 advance_state (FENCE_STATE (fence)); | 586 advance_state (FENCE_STATE (fence)); |
587 cycle = ++FENCE_CYCLE (fence); | 587 cycle = ++FENCE_CYCLE (fence); |
588 FENCE_ISSUED_INSNS (fence) = 0; | 588 FENCE_ISSUED_INSNS (fence) = 0; |
589 FENCE_STARTS_CYCLE_P (fence) = 1; | 589 FENCE_STARTS_CYCLE_P (fence) = 1; |
590 can_issue_more = issue_rate; | 590 can_issue_more = issue_rate; |
591 FENCE_ISSUE_MORE (fence) = can_issue_more; | |
591 | 592 |
592 for (i = 0; VEC_iterate (rtx, FENCE_EXECUTING_INSNS (fence), i, insn); ) | 593 for (i = 0; VEC_iterate (rtx, FENCE_EXECUTING_INSNS (fence), i, insn); ) |
593 { | 594 { |
594 if (INSN_READY_CYCLE (insn) < cycle) | 595 if (INSN_READY_CYCLE (insn) < cycle) |
595 { | 596 { |
610 skipping empty basic blocks. */ | 611 skipping empty basic blocks. */ |
611 static bool | 612 static bool |
612 in_fallthru_bb_p (rtx insn, rtx succ) | 613 in_fallthru_bb_p (rtx insn, rtx succ) |
613 { | 614 { |
614 basic_block bb = BLOCK_FOR_INSN (insn); | 615 basic_block bb = BLOCK_FOR_INSN (insn); |
616 edge e; | |
615 | 617 |
616 if (bb == BLOCK_FOR_INSN (succ)) | 618 if (bb == BLOCK_FOR_INSN (succ)) |
617 return true; | 619 return true; |
618 | 620 |
619 if (find_fallthru_edge (bb)) | 621 e = find_fallthru_edge_from (bb); |
620 bb = find_fallthru_edge (bb)->dest; | 622 if (e) |
623 bb = e->dest; | |
621 else | 624 else |
622 return false; | 625 return false; |
623 | 626 |
624 while (sel_bb_empty_p (bb)) | 627 while (sel_bb_empty_p (bb)) |
625 bb = bb->next_bb; | 628 bb = bb->next_bb; |
833 return -1; | 836 return -1; |
834 } | 837 } |
835 | 838 |
836 if (GET_CODE (*cur_rtx) == SUBREG | 839 if (GET_CODE (*cur_rtx) == SUBREG |
837 && REG_P (p->x) | 840 && REG_P (p->x) |
838 && REGNO (SUBREG_REG (*cur_rtx)) == REGNO (p->x)) | 841 && (!REG_P (SUBREG_REG (*cur_rtx)) |
842 || REGNO (SUBREG_REG (*cur_rtx)) == REGNO (p->x))) | |
839 { | 843 { |
840 /* ??? Do not support substituting regs inside subregs. In that case, | 844 /* ??? Do not support substituting regs inside subregs. In that case, |
841 simplify_subreg will be called by validate_replace_rtx, and | 845 simplify_subreg will be called by validate_replace_rtx, and |
842 unsubstitution will fail later. */ | 846 unsubstitution will fail later. */ |
843 p->n = 0; | 847 p->n = 0; |
1134 if (fixed_regs[cur_reg + i] | 1138 if (fixed_regs[cur_reg + i] |
1135 || global_regs[cur_reg + i] | 1139 || global_regs[cur_reg + i] |
1136 /* Can't use regs which aren't saved by | 1140 /* Can't use regs which aren't saved by |
1137 the prologue. */ | 1141 the prologue. */ |
1138 || !TEST_HARD_REG_BIT (sel_hrd.regs_ever_used, cur_reg + i) | 1142 || !TEST_HARD_REG_BIT (sel_hrd.regs_ever_used, cur_reg + i) |
1143 /* Can't use regs with non-null REG_BASE_VALUE, because adjusting | |
1144 it affects aliasing globally and invalidates all AV sets. */ | |
1145 || get_reg_base_value (cur_reg + i) | |
1139 #ifdef LEAF_REGISTERS | 1146 #ifdef LEAF_REGISTERS |
1140 /* We can't use a non-leaf register if we're in a | 1147 /* We can't use a non-leaf register if we're in a |
1141 leaf function. */ | 1148 leaf function. */ |
1142 || (current_function_is_leaf | 1149 || (current_function_is_leaf |
1143 && !LEAF_REGISTERS[cur_reg + i]) | 1150 && !LEAF_REGISTERS[cur_reg + i]) |
1226 | 1233 |
1227 /* If before reload, don't try to work with pseudos. */ | 1234 /* If before reload, don't try to work with pseudos. */ |
1228 if (!reload_completed && !HARD_REGISTER_NUM_P (regno)) | 1235 if (!reload_completed && !HARD_REGISTER_NUM_P (regno)) |
1229 return; | 1236 return; |
1230 | 1237 |
1231 mode = GET_MODE (orig_dest); | 1238 if (reload_completed) |
1232 | 1239 cl = get_reg_class (def->orig_insn); |
1233 /* Stop when mode is not supported for renaming. Also can't proceed | 1240 |
1234 if the original register is one of the fixed_regs, global_regs or | 1241 /* Stop if the original register is one of the fixed_regs, global_regs or |
1235 frame pointer. */ | 1242 frame pointer, or we could not discover its class. */ |
1236 if (fixed_regs[regno] | 1243 if (fixed_regs[regno] |
1237 || global_regs[regno] | 1244 || global_regs[regno] |
1238 #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM | 1245 #if !HARD_FRAME_POINTER_IS_FRAME_POINTER |
1239 || (frame_pointer_needed && regno == HARD_FRAME_POINTER_REGNUM) | 1246 || (frame_pointer_needed && regno == HARD_FRAME_POINTER_REGNUM) |
1240 #else | 1247 #else |
1241 || (frame_pointer_needed && regno == FRAME_POINTER_REGNUM) | 1248 || (frame_pointer_needed && regno == FRAME_POINTER_REGNUM) |
1242 #endif | 1249 #endif |
1243 ) | 1250 || (reload_completed && cl == NO_REGS)) |
1244 { | 1251 { |
1245 SET_HARD_REG_SET (reg_rename_p->unavailable_hard_regs); | 1252 SET_HARD_REG_SET (reg_rename_p->unavailable_hard_regs); |
1246 | 1253 |
1247 /* Give a chance for original register, if it isn't in used_regs. */ | 1254 /* Give a chance for original register, if it isn't in used_regs. */ |
1248 if (!def->crosses_call) | 1255 if (!def->crosses_call) |
1260 | 1267 |
1261 for (i = hard_regno_nregs[FRAME_POINTER_REGNUM][Pmode]; i--;) | 1268 for (i = hard_regno_nregs[FRAME_POINTER_REGNUM][Pmode]; i--;) |
1262 SET_HARD_REG_BIT (reg_rename_p->unavailable_hard_regs, | 1269 SET_HARD_REG_BIT (reg_rename_p->unavailable_hard_regs, |
1263 FRAME_POINTER_REGNUM + i); | 1270 FRAME_POINTER_REGNUM + i); |
1264 | 1271 |
1265 #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM | 1272 #if !HARD_FRAME_POINTER_IS_FRAME_POINTER |
1266 for (i = hard_regno_nregs[HARD_FRAME_POINTER_REGNUM][Pmode]; i--;) | 1273 for (i = hard_regno_nregs[HARD_FRAME_POINTER_REGNUM][Pmode]; i--;) |
1267 SET_HARD_REG_BIT (reg_rename_p->unavailable_hard_regs, | 1274 SET_HARD_REG_BIT (reg_rename_p->unavailable_hard_regs, |
1268 HARD_FRAME_POINTER_REGNUM + i); | 1275 HARD_FRAME_POINTER_REGNUM + i); |
1269 #endif | 1276 #endif |
1270 } | 1277 } |
1293 if (!reload_completed) | 1300 if (!reload_completed) |
1294 return; | 1301 return; |
1295 | 1302 |
1296 /* Leave regs as 'available' only from the current | 1303 /* Leave regs as 'available' only from the current |
1297 register class. */ | 1304 register class. */ |
1298 cl = get_reg_class (def->orig_insn); | |
1299 gcc_assert (cl != NO_REGS); | |
1300 COPY_HARD_REG_SET (reg_rename_p->available_for_renaming, | 1305 COPY_HARD_REG_SET (reg_rename_p->available_for_renaming, |
1301 reg_class_contents[cl]); | 1306 reg_class_contents[cl]); |
1307 | |
1308 mode = GET_MODE (orig_dest); | |
1302 | 1309 |
1303 /* Leave only registers available for this mode. */ | 1310 /* Leave only registers available for this mode. */ |
1304 if (!sel_hrd.regs_for_mode_ok[mode]) | 1311 if (!sel_hrd.regs_for_mode_ok[mode]) |
1305 init_regs_for_mode (mode); | 1312 init_regs_for_mode (mode); |
1306 AND_HARD_REG_SET (reg_rename_p->available_for_renaming, | 1313 AND_HARD_REG_SET (reg_rename_p->available_for_renaming, |
1426 allocated earliest. */ | 1433 allocated earliest. */ |
1427 EXECUTE_IF_SET_IN_HARD_REG_SET (reg_rename_p->available_for_renaming, | 1434 EXECUTE_IF_SET_IN_HARD_REG_SET (reg_rename_p->available_for_renaming, |
1428 0, cur_reg, hrsi) | 1435 0, cur_reg, hrsi) |
1429 if (! TEST_HARD_REG_BIT (hard_regs_used, cur_reg)) | 1436 if (! TEST_HARD_REG_BIT (hard_regs_used, cur_reg)) |
1430 { | 1437 { |
1438 /* Check that all hard regs for mode are available. */ | |
1439 for (i = 1, n = hard_regno_nregs[cur_reg][mode]; i < n; i++) | |
1440 if (TEST_HARD_REG_BIT (hard_regs_used, cur_reg + i) | |
1441 || !TEST_HARD_REG_BIT (reg_rename_p->available_for_renaming, | |
1442 cur_reg + i)) | |
1443 break; | |
1444 | |
1445 if (i < n) | |
1446 continue; | |
1447 | |
1431 /* All hard registers are available. */ | 1448 /* All hard registers are available. */ |
1432 if (best_new_reg < 0 | 1449 if (best_new_reg < 0 |
1433 || reg_rename_tick[cur_reg] < reg_rename_tick[best_new_reg]) | 1450 || reg_rename_tick[cur_reg] < reg_rename_tick[best_new_reg]) |
1434 { | 1451 { |
1435 best_new_reg = cur_reg; | 1452 best_new_reg = cur_reg; |
1457 def_list_t original_insns, bool *is_orig_reg_p_ptr) | 1474 def_list_t original_insns, bool *is_orig_reg_p_ptr) |
1458 { | 1475 { |
1459 rtx best_reg = choose_best_reg_1 (hard_regs_used, reg_rename_p, | 1476 rtx best_reg = choose_best_reg_1 (hard_regs_used, reg_rename_p, |
1460 original_insns, is_orig_reg_p_ptr); | 1477 original_insns, is_orig_reg_p_ptr); |
1461 | 1478 |
1479 /* FIXME loop over hard_regno_nregs here. */ | |
1462 gcc_assert (best_reg == NULL_RTX | 1480 gcc_assert (best_reg == NULL_RTX |
1463 || TEST_HARD_REG_BIT (sel_hrd.regs_ever_used, REGNO (best_reg))); | 1481 || TEST_HARD_REG_BIT (sel_hrd.regs_ever_used, REGNO (best_reg))); |
1464 | 1482 |
1465 return best_reg; | 1483 return best_reg; |
1466 } | 1484 } |
1640 /* Return TRUE if it is possible to replace LHSes of ORIG_INSNS with BEST_REG. | 1658 /* Return TRUE if it is possible to replace LHSes of ORIG_INSNS with BEST_REG. |
1641 If BEST_REG is valid, replace LHS of EXPR with it. */ | 1659 If BEST_REG is valid, replace LHS of EXPR with it. */ |
1642 static bool | 1660 static bool |
1643 try_replace_dest_reg (ilist_t orig_insns, rtx best_reg, expr_t expr) | 1661 try_replace_dest_reg (ilist_t orig_insns, rtx best_reg, expr_t expr) |
1644 { | 1662 { |
1645 if (expr_dest_regno (expr) == REGNO (best_reg)) | |
1646 { | |
1647 EXPR_TARGET_AVAILABLE (expr) = 1; | |
1648 return true; | |
1649 } | |
1650 | |
1651 gcc_assert (orig_insns); | |
1652 | |
1653 /* Try whether we'll be able to generate the insn | 1663 /* Try whether we'll be able to generate the insn |
1654 'dest := best_reg' at the place of the original operation. */ | 1664 'dest := best_reg' at the place of the original operation. */ |
1655 for (; orig_insns; orig_insns = ILIST_NEXT (orig_insns)) | 1665 for (; orig_insns; orig_insns = ILIST_NEXT (orig_insns)) |
1656 { | 1666 { |
1657 insn_t orig_insn = DEF_LIST_DEF (orig_insns)->orig_insn; | 1667 insn_t orig_insn = DEF_LIST_DEF (orig_insns)->orig_insn; |
1658 | 1668 |
1659 gcc_assert (EXPR_SEPARABLE_P (INSN_EXPR (orig_insn))); | 1669 gcc_assert (EXPR_SEPARABLE_P (INSN_EXPR (orig_insn))); |
1660 | 1670 |
1661 if (!replace_src_with_reg_ok_p (orig_insn, best_reg) | 1671 if (REGNO (best_reg) != REGNO (INSN_LHS (orig_insn)) |
1662 || !replace_dest_with_reg_ok_p (orig_insn, best_reg)) | 1672 && (! replace_src_with_reg_ok_p (orig_insn, best_reg) |
1673 || ! replace_dest_with_reg_ok_p (orig_insn, best_reg))) | |
1663 return false; | 1674 return false; |
1664 } | 1675 } |
1665 | 1676 |
1666 /* Make sure that EXPR has the right destination | 1677 /* Make sure that EXPR has the right destination |
1667 register. */ | 1678 register. */ |
1668 replace_dest_with_reg_in_expr (expr, best_reg); | 1679 if (expr_dest_regno (expr) != REGNO (best_reg)) |
1680 replace_dest_with_reg_in_expr (expr, best_reg); | |
1681 else | |
1682 EXPR_TARGET_AVAILABLE (expr) = 1; | |
1683 | |
1669 return true; | 1684 return true; |
1670 } | 1685 } |
1671 | 1686 |
1672 /* Select and assign best register to EXPR searching from BNDS. | 1687 /* Select and assign best register to EXPR searching from BNDS. |
1673 Set *IS_ORIG_REG_P to TRUE if original register was selected. | 1688 Set *IS_ORIG_REG_P to TRUE if original register was selected. |
1855 /* Emit copy of original insn (though with replaced target register, | 1870 /* Emit copy of original insn (though with replaced target register, |
1856 if needed) to the recovery block. */ | 1871 if needed) to the recovery block. */ |
1857 if (recovery_block != NULL) | 1872 if (recovery_block != NULL) |
1858 { | 1873 { |
1859 rtx twin_rtx; | 1874 rtx twin_rtx; |
1860 insn_t twin; | |
1861 | 1875 |
1862 twin_rtx = copy_rtx (PATTERN (EXPR_INSN_RTX (c_expr))); | 1876 twin_rtx = copy_rtx (PATTERN (EXPR_INSN_RTX (c_expr))); |
1863 twin_rtx = create_insn_rtx_from_pattern (twin_rtx, NULL_RTX); | 1877 twin_rtx = create_insn_rtx_from_pattern (twin_rtx, NULL_RTX); |
1864 twin = sel_gen_recovery_insn_from_rtx_after (twin_rtx, | 1878 sel_gen_recovery_insn_from_rtx_after (twin_rtx, |
1865 INSN_EXPR (orig_insn), | 1879 INSN_EXPR (orig_insn), |
1866 INSN_SEQNO (insn), | 1880 INSN_SEQNO (insn), |
1867 bb_note (recovery_block)); | 1881 bb_note (recovery_block)); |
1868 } | 1882 } |
1869 | 1883 |
1870 /* If we've generated a data speculation check, make sure | 1884 /* If we've generated a data speculation check, make sure |
1871 that all the bookkeeping instruction we'll create during | 1885 that all the bookkeeping instruction we'll create during |
1872 this move_op () will allocate an ALAT entry so that the | 1886 this move_op () will allocate an ALAT entry so that the |
2126 bool was_changed = false; | 2140 bool was_changed = false; |
2127 bool as_rhs = false; | 2141 bool as_rhs = false; |
2128 ds_t *has_dep_p; | 2142 ds_t *has_dep_p; |
2129 ds_t full_ds; | 2143 ds_t full_ds; |
2130 | 2144 |
2145 /* ??? We use dependencies of non-debug insns on debug insns to | |
2146 indicate that the debug insns need to be reset if the non-debug | |
2147 insn is pulled ahead of it. It's hard to figure out how to | |
2148 introduce such a notion in sel-sched, but it already fails to | |
2149 support debug insns in other ways, so we just go ahead and | |
2150 let the deug insns go corrupt for now. */ | |
2151 if (DEBUG_INSN_P (through_insn) && !DEBUG_INSN_P (insn)) | |
2152 return MOVEUP_EXPR_SAME; | |
2153 | |
2131 /* When inside_insn_group, delegate to the helper. */ | 2154 /* When inside_insn_group, delegate to the helper. */ |
2132 if (inside_insn_group) | 2155 if (inside_insn_group) |
2133 return moveup_expr_inside_insn_group (expr, through_insn); | 2156 return moveup_expr_inside_insn_group (expr, through_insn); |
2134 | 2157 |
2135 /* Deal with unique insns and control dependencies. */ | 2158 /* Deal with unique insns and control dependencies. */ |
2156 this block should be in the current region. */ | 2179 this block should be in the current region. */ |
2157 if ((fallthru_bb = fallthru_bb_of_jump (insn)) == NULL | 2180 if ((fallthru_bb = fallthru_bb_of_jump (insn)) == NULL |
2158 || ! in_current_region_p (fallthru_bb)) | 2181 || ! in_current_region_p (fallthru_bb)) |
2159 return MOVEUP_EXPR_NULL; | 2182 return MOVEUP_EXPR_NULL; |
2160 | 2183 |
2161 /* And it should be mutually exclusive with through_insn, or | 2184 /* And it should be mutually exclusive with through_insn. */ |
2162 be an unconditional jump. */ | 2185 if (! sched_insns_conditions_mutex_p (insn, through_insn) |
2163 if (! any_uncondjump_p (insn) | |
2164 && ! sched_insns_conditions_mutex_p (insn, through_insn) | |
2165 && ! DEBUG_INSN_P (through_insn)) | 2186 && ! DEBUG_INSN_P (through_insn)) |
2166 return MOVEUP_EXPR_NULL; | 2187 return MOVEUP_EXPR_NULL; |
2167 } | 2188 } |
2168 | 2189 |
2169 /* Don't move what we can't move. */ | 2190 /* Don't move what we can't move. */ |
2400 change_vinsn_in_expr (expr, pti->vinsn_new); | 2421 change_vinsn_in_expr (expr, pti->vinsn_new); |
2401 if (pti->was_target_conflict) | 2422 if (pti->was_target_conflict) |
2402 EXPR_TARGET_AVAILABLE (expr) = false; | 2423 EXPR_TARGET_AVAILABLE (expr) = false; |
2403 if (pti->type == TRANS_SPECULATION) | 2424 if (pti->type == TRANS_SPECULATION) |
2404 { | 2425 { |
2405 ds_t ds; | |
2406 | |
2407 ds = EXPR_SPEC_DONE_DS (expr); | |
2408 | |
2409 EXPR_SPEC_DONE_DS (expr) = pti->ds; | 2426 EXPR_SPEC_DONE_DS (expr) = pti->ds; |
2410 EXPR_NEEDS_SPEC_CHECK_P (expr) |= pti->needs_check; | 2427 EXPR_NEEDS_SPEC_CHECK_P (expr) |= pti->needs_check; |
2411 } | 2428 } |
2412 | 2429 |
2413 if (sched_verbose >= 6) | 2430 if (sched_verbose >= 6) |
2730 } | 2747 } |
2731 | 2748 |
2732 /* Add insn to to the tail of current path. */ | 2749 /* Add insn to to the tail of current path. */ |
2733 ilist_add (&p, insn); | 2750 ilist_add (&p, insn); |
2734 | 2751 |
2735 for (is = 0; VEC_iterate (rtx, sinfo->succs_ok, is, succ); is++) | 2752 FOR_EACH_VEC_ELT (rtx, sinfo->succs_ok, is, succ) |
2736 { | 2753 { |
2737 av_set_t succ_set; | 2754 av_set_t succ_set; |
2738 | 2755 |
2739 /* We will edit SUCC_SET and EXPR_SPEC field of its elements. */ | 2756 /* We will edit SUCC_SET and EXPR_SPEC field of its elements. */ |
2740 succ_set = compute_av_set_inside_bb (succ, p, ws, true); | 2757 succ_set = compute_av_set_inside_bb (succ, p, ws, true); |
2741 | 2758 |
2742 av_set_split_usefulness (succ_set, | 2759 av_set_split_usefulness (succ_set, |
2743 VEC_index (int, sinfo->probs_ok, is), | 2760 VEC_index (int, sinfo->probs_ok, is), |
2744 sinfo->all_prob); | 2761 sinfo->all_prob); |
2745 | 2762 |
2746 if (sinfo->all_succs_n > 1 | 2763 if (sinfo->all_succs_n > 1) |
2747 && sinfo->all_succs_n == sinfo->succs_ok_n) | |
2748 { | 2764 { |
2749 /* Find EXPR'es that came from *all* successors and save them | 2765 /* Find EXPR'es that came from *all* successors and save them |
2750 into expr_in_all_succ_branches. This set will be used later | 2766 into expr_in_all_succ_branches. This set will be used later |
2751 for calculating speculation attributes of EXPR'es. */ | 2767 for calculating speculation attributes of EXPR'es. */ |
2752 if (is == 0) | 2768 if (is == 0) |
2785 } | 2801 } |
2786 | 2802 |
2787 /* Check liveness restrictions via hard way when there are more than | 2803 /* Check liveness restrictions via hard way when there are more than |
2788 two successors. */ | 2804 two successors. */ |
2789 if (sinfo->succs_ok_n > 2) | 2805 if (sinfo->succs_ok_n > 2) |
2790 for (is = 0; VEC_iterate (rtx, sinfo->succs_ok, is, succ); is++) | 2806 FOR_EACH_VEC_ELT (rtx, sinfo->succs_ok, is, succ) |
2791 { | 2807 { |
2792 basic_block succ_bb = BLOCK_FOR_INSN (succ); | 2808 basic_block succ_bb = BLOCK_FOR_INSN (succ); |
2793 | 2809 |
2794 gcc_assert (BB_LV_SET_VALID_P (succ_bb)); | 2810 gcc_assert (BB_LV_SET_VALID_P (succ_bb)); |
2795 mark_unavailable_targets (av1, BB_AV_SET (succ_bb), | 2811 mark_unavailable_targets (av1, BB_AV_SET (succ_bb), |
2796 BB_LV_SET (succ_bb)); | 2812 BB_LV_SET (succ_bb)); |
2797 } | 2813 } |
2798 | 2814 |
2799 /* Finally, check liveness restrictions on paths leaving the region. */ | 2815 /* Finally, check liveness restrictions on paths leaving the region. */ |
2800 if (sinfo->all_succs_n > sinfo->succs_ok_n) | 2816 if (sinfo->all_succs_n > sinfo->succs_ok_n) |
2801 for (is = 0; VEC_iterate (rtx, sinfo->succs_other, is, succ); is++) | 2817 FOR_EACH_VEC_ELT (rtx, sinfo->succs_other, is, succ) |
2802 mark_unavailable_targets | 2818 mark_unavailable_targets |
2803 (av1, NULL, BB_LV_SET (BLOCK_FOR_INSN (succ))); | 2819 (av1, NULL, BB_LV_SET (BLOCK_FOR_INSN (succ))); |
2804 | 2820 |
2805 if (sinfo->all_succs_n > 1) | 2821 if (sinfo->all_succs_n > 1) |
2806 { | 2822 { |
3302 /* If the priority has changed, adjust EXPR_PRIORITY_ADJ accordingly. */ | 3318 /* If the priority has changed, adjust EXPR_PRIORITY_ADJ accordingly. */ |
3303 EXPR_PRIORITY_ADJ (expr) = new_priority - EXPR_PRIORITY (expr); | 3319 EXPR_PRIORITY_ADJ (expr) = new_priority - EXPR_PRIORITY (expr); |
3304 | 3320 |
3305 gcc_assert (EXPR_PRIORITY_ADJ (expr) >= 0); | 3321 gcc_assert (EXPR_PRIORITY_ADJ (expr) >= 0); |
3306 | 3322 |
3307 if (sched_verbose >= 2) | 3323 if (sched_verbose >= 4) |
3308 sel_print ("sel_target_adjust_priority: insn %d, %d +%d = %d.\n", | 3324 sel_print ("sel_target_adjust_priority: insn %d, %d+%d = %d.\n", |
3309 INSN_UID (EXPR_INSN_RTX (expr)), EXPR_PRIORITY (expr), | 3325 INSN_UID (EXPR_INSN_RTX (expr)), EXPR_PRIORITY (expr), |
3310 EXPR_PRIORITY_ADJ (expr), new_priority); | 3326 EXPR_PRIORITY_ADJ (expr), new_priority); |
3311 | 3327 |
3312 return new_priority; | 3328 return new_priority; |
3313 } | 3329 } |
3567 vinsn_vec_has_expr_p (vinsn_vec_t vinsn_vec, expr_t expr) | 3583 vinsn_vec_has_expr_p (vinsn_vec_t vinsn_vec, expr_t expr) |
3568 { | 3584 { |
3569 vinsn_t vinsn; | 3585 vinsn_t vinsn; |
3570 int n; | 3586 int n; |
3571 | 3587 |
3572 for (n = 0; VEC_iterate (vinsn_t, vinsn_vec, n, vinsn); n++) | 3588 FOR_EACH_VEC_ELT (vinsn_t, vinsn_vec, n, vinsn) |
3573 if (VINSN_SEPARABLE_P (vinsn)) | 3589 if (VINSN_SEPARABLE_P (vinsn)) |
3574 { | 3590 { |
3575 if (vinsn_equal_p (vinsn, EXPR_VINSN (expr))) | 3591 if (vinsn_equal_p (vinsn, EXPR_VINSN (expr))) |
3576 return true; | 3592 return true; |
3577 } | 3593 } |
3641 if (len > 0) | 3657 if (len > 0) |
3642 { | 3658 { |
3643 vinsn_t vinsn; | 3659 vinsn_t vinsn; |
3644 int n; | 3660 int n; |
3645 | 3661 |
3646 for (n = 0; VEC_iterate (vinsn_t, *vinsn_vec, n, vinsn); n++) | 3662 FOR_EACH_VEC_ELT (vinsn_t, *vinsn_vec, n, vinsn) |
3647 vinsn_detach (vinsn); | 3663 vinsn_detach (vinsn); |
3648 VEC_block_remove (vinsn_t, *vinsn_vec, 0, len); | 3664 VEC_block_remove (vinsn_t, *vinsn_vec, 0, len); |
3649 } | 3665 } |
3650 } | 3666 } |
3651 | 3667 |
3714 /* Adjust priority using target backend hook. */ | 3730 /* Adjust priority using target backend hook. */ |
3715 sel_target_adjust_priority (expr); | 3731 sel_target_adjust_priority (expr); |
3716 } | 3732 } |
3717 | 3733 |
3718 /* Sort the vector. */ | 3734 /* Sort the vector. */ |
3719 qsort (VEC_address (expr_t, vec_av_set), VEC_length (expr_t, vec_av_set), | 3735 VEC_qsort (expr_t, vec_av_set, sel_rank_for_schedule); |
3720 sizeof (expr_t), sel_rank_for_schedule); | |
3721 | 3736 |
3722 /* We record maximal priority of insns in av set for current instruction | 3737 /* We record maximal priority of insns in av set for current instruction |
3723 group. */ | 3738 group. */ |
3724 if (FENCE_STARTS_CYCLE_P (fence)) | 3739 if (FENCE_STARTS_CYCLE_P (fence)) |
3725 av_max_prio = est_ticks_till_branch = INT_MIN; | 3740 av_max_prio = est_ticks_till_branch = INT_MIN; |
3729 moves last element in place of one being deleted. */ | 3744 moves last element in place of one being deleted. */ |
3730 for (n = VEC_length (expr_t, vec_av_set) - 1, stalled = 0; n >= 0; n--) | 3745 for (n = VEC_length (expr_t, vec_av_set) - 1, stalled = 0; n >= 0; n--) |
3731 { | 3746 { |
3732 expr_t expr = VEC_index (expr_t, vec_av_set, n); | 3747 expr_t expr = VEC_index (expr_t, vec_av_set, n); |
3733 insn_t insn = EXPR_INSN_RTX (expr); | 3748 insn_t insn = EXPR_INSN_RTX (expr); |
3734 char target_available; | 3749 signed char target_available; |
3735 bool is_orig_reg_p = true; | 3750 bool is_orig_reg_p = true; |
3736 int need_cycles, new_prio; | 3751 int need_cycles, new_prio; |
3737 | 3752 |
3738 /* Don't allow any insns other than from SCHED_GROUP if we have one. */ | 3753 /* Don't allow any insns other than from SCHED_GROUP if we have one. */ |
3739 if (FENCE_SCHED_NEXT (fence) && insn != FENCE_SCHED_NEXT (fence)) | 3754 if (FENCE_SCHED_NEXT (fence) && insn != FENCE_SCHED_NEXT (fence)) |
3929 } | 3944 } |
3930 else | 3945 else |
3931 gcc_assert (min_need_stall == 0); | 3946 gcc_assert (min_need_stall == 0); |
3932 | 3947 |
3933 /* Sort the vector. */ | 3948 /* Sort the vector. */ |
3934 qsort (VEC_address (expr_t, vec_av_set), VEC_length (expr_t, vec_av_set), | 3949 VEC_qsort (expr_t, vec_av_set, sel_rank_for_schedule); |
3935 sizeof (expr_t), sel_rank_for_schedule); | |
3936 | 3950 |
3937 if (sched_verbose >= 4) | 3951 if (sched_verbose >= 4) |
3938 { | 3952 { |
3939 sel_print ("Total ready exprs: %d, stalled: %d\n", | 3953 sel_print ("Total ready exprs: %d, stalled: %d\n", |
3940 VEC_length (expr_t, vec_av_set), stalled); | 3954 VEC_length (expr_t, vec_av_set), stalled); |
3941 sel_print ("Sorted av set (%d): ", VEC_length (expr_t, vec_av_set)); | 3955 sel_print ("Sorted av set (%d): ", VEC_length (expr_t, vec_av_set)); |
3942 for (n = 0; VEC_iterate (expr_t, vec_av_set, n, expr); n++) | 3956 FOR_EACH_VEC_ELT (expr_t, vec_av_set, n, expr) |
3943 dump_expr (expr); | 3957 dump_expr (expr); |
3944 sel_print ("\n"); | 3958 sel_print ("\n"); |
3945 } | 3959 } |
3946 | 3960 |
3947 *pneed_stall = 0; | 3961 *pneed_stall = 0; |
3966 { | 3980 { |
3967 max_issue_size = ready.n_ready; | 3981 max_issue_size = ready.n_ready; |
3968 sched_extend_ready_list (ready.n_ready); | 3982 sched_extend_ready_list (ready.n_ready); |
3969 } | 3983 } |
3970 | 3984 |
3971 for (n = 0; VEC_iterate (expr_t, vec_av_set, n, expr); n++) | 3985 FOR_EACH_VEC_ELT (expr_t, vec_av_set, n, expr) |
3972 { | 3986 { |
3973 vinsn_t vi = EXPR_VINSN (expr); | 3987 vinsn_t vi = EXPR_VINSN (expr); |
3974 insn_t insn = VINSN_INSN_RTX (vi); | 3988 insn_t insn = VINSN_INSN_RTX (vi); |
3975 | 3989 |
3976 ready_try[n] = 0; | 3990 ready_try[n] = 0; |
4104 } | 4118 } |
4105 | 4119 |
4106 ran_hook = true; | 4120 ran_hook = true; |
4107 } | 4121 } |
4108 else | 4122 else |
4109 issue_more = issue_rate; | 4123 issue_more = FENCE_ISSUE_MORE (fence); |
4110 | 4124 |
4111 /* Ensure that ready list and vec_av_set are in line with each other, | 4125 /* Ensure that ready list and vec_av_set are in line with each other, |
4112 i.e. vec_av_set[i] == ready_element (&ready, i). */ | 4126 i.e. vec_av_set[i] == ready_element (&ready, i). */ |
4113 if (issue_more && ran_hook) | 4127 if (issue_more && ran_hook) |
4114 { | 4128 { |
4206 /* Calculate the number of privileged insns and return it. */ | 4220 /* Calculate the number of privileged insns and return it. */ |
4207 static int | 4221 static int |
4208 calculate_privileged_insns (void) | 4222 calculate_privileged_insns (void) |
4209 { | 4223 { |
4210 expr_t cur_expr, min_spec_expr = NULL; | 4224 expr_t cur_expr, min_spec_expr = NULL; |
4211 insn_t cur_insn, min_spec_insn; | |
4212 int privileged_n = 0, i; | 4225 int privileged_n = 0, i; |
4213 | 4226 |
4214 for (i = 0; i < ready.n_ready; i++) | 4227 for (i = 0; i < ready.n_ready; i++) |
4215 { | 4228 { |
4216 if (ready_try[i]) | 4229 if (ready_try[i]) |
4217 continue; | 4230 continue; |
4218 | 4231 |
4219 if (! min_spec_expr) | 4232 if (! min_spec_expr) |
4220 { | 4233 min_spec_expr = find_expr_for_ready (i, true); |
4221 min_spec_insn = ready_element (&ready, i); | 4234 |
4222 min_spec_expr = find_expr_for_ready (i, true); | |
4223 } | |
4224 | |
4225 cur_insn = ready_element (&ready, i); | |
4226 cur_expr = find_expr_for_ready (i, true); | 4235 cur_expr = find_expr_for_ready (i, true); |
4227 | 4236 |
4228 if (EXPR_SPEC (cur_expr) > EXPR_SPEC (min_spec_expr)) | 4237 if (EXPR_SPEC (cur_expr) > EXPR_SPEC (min_spec_expr)) |
4229 break; | 4238 break; |
4230 | 4239 |
4295 rtx insn = EXPR_INSN_RTX (expr); | 4304 rtx insn = EXPR_INSN_RTX (expr); |
4296 | 4305 |
4297 if (recog_memoized (insn) < 0) | 4306 if (recog_memoized (insn) < 0) |
4298 { | 4307 { |
4299 if (!FENCE_STARTS_CYCLE_P (fence) | 4308 if (!FENCE_STARTS_CYCLE_P (fence) |
4300 /* FIXME: Is this condition necessary? */ | |
4301 && VINSN_UNIQUE_P (EXPR_VINSN (expr)) | |
4302 && INSN_ASM_P (insn)) | 4309 && INSN_ASM_P (insn)) |
4303 /* This is asm insn which is tryed to be issued on the | 4310 /* This is asm insn which is tryed to be issued on the |
4304 cycle not first. Issue it on the next cycle. */ | 4311 cycle not first. Issue it on the next cycle. */ |
4305 return 1; | 4312 return 1; |
4306 else | 4313 else |
4322 int can_issue = 0; | 4329 int can_issue = 0; |
4323 | 4330 |
4324 if (dfa_lookahead > 0) | 4331 if (dfa_lookahead > 0) |
4325 { | 4332 { |
4326 cycle_issued_insns = FENCE_ISSUED_INSNS (fence); | 4333 cycle_issued_insns = FENCE_ISSUED_INSNS (fence); |
4334 /* TODO: pass equivalent of first_cycle_insn_p to max_issue (). */ | |
4327 can_issue = max_issue (&ready, privileged_n, | 4335 can_issue = max_issue (&ready, privileged_n, |
4328 FENCE_STATE (fence), index); | 4336 FENCE_STATE (fence), true, index); |
4329 if (sched_verbose >= 2) | 4337 if (sched_verbose >= 2) |
4330 sel_print ("max_issue: we can issue %d insns, already did %d insns\n", | 4338 sel_print ("max_issue: we can issue %d insns, already did %d insns\n", |
4331 can_issue, FENCE_ISSUED_INSNS (fence)); | 4339 can_issue, FENCE_ISSUED_INSNS (fence)); |
4332 } | 4340 } |
4333 else | 4341 else |
4376 2) calling the reorder hook; | 4384 2) calling the reorder hook; |
4377 3) calling max_issue. */ | 4385 3) calling max_issue. */ |
4378 best = fill_ready_list (av_vliw_ptr, bnds, fence, pneed_stall); | 4386 best = fill_ready_list (av_vliw_ptr, bnds, fence, pneed_stall); |
4379 if (best == NULL && ready.n_ready > 0) | 4387 if (best == NULL && ready.n_ready > 0) |
4380 { | 4388 { |
4381 int privileged_n, index, avail_n; | 4389 int privileged_n, index; |
4382 | 4390 |
4383 can_issue_more = invoke_reorder_hooks (fence); | 4391 can_issue_more = invoke_reorder_hooks (fence); |
4384 if (can_issue_more > 0) | 4392 if (can_issue_more > 0) |
4385 { | 4393 { |
4386 /* Try choosing the best insn until we find one that is could be | 4394 /* Try choosing the best insn until we find one that is could be |
4387 scheduled due to liveness restrictions on its destination register. | 4395 scheduled due to liveness restrictions on its destination register. |
4388 In the future, we'd like to choose once and then just probe insns | 4396 In the future, we'd like to choose once and then just probe insns |
4389 in the order of their priority. */ | 4397 in the order of their priority. */ |
4390 avail_n = invoke_dfa_lookahead_guard (); | 4398 invoke_dfa_lookahead_guard (); |
4391 privileged_n = calculate_privileged_insns (); | 4399 privileged_n = calculate_privileged_insns (); |
4392 can_issue_more = choose_best_insn (fence, privileged_n, &index); | 4400 can_issue_more = choose_best_insn (fence, privileged_n, &index); |
4393 if (can_issue_more) | 4401 if (can_issue_more) |
4394 best = find_expr_for_ready (index, true); | 4402 best = find_expr_for_ready (index, true); |
4395 } | 4403 } |
4404 | 4412 |
4405 if (best != NULL) | 4413 if (best != NULL) |
4406 { | 4414 { |
4407 can_issue_more = invoke_aftermath_hooks (fence, EXPR_INSN_RTX (best), | 4415 can_issue_more = invoke_aftermath_hooks (fence, EXPR_INSN_RTX (best), |
4408 can_issue_more); | 4416 can_issue_more); |
4409 if (can_issue_more == 0) | 4417 if (targetm.sched.variable_issue |
4418 && can_issue_more == 0) | |
4410 *pneed_stall = 1; | 4419 *pneed_stall = 1; |
4411 } | 4420 } |
4412 | 4421 |
4413 if (sched_verbose >= 2) | 4422 if (sched_verbose >= 2) |
4414 { | 4423 { |
4634 | 4643 |
4635 FOR_BB_INSNS (succ, insn) | 4644 FOR_BB_INSNS (succ, insn) |
4636 if (INSN_P (insn)) | 4645 if (INSN_P (insn)) |
4637 EXPR_ORIG_BB_INDEX (INSN_EXPR (insn)) = succ->index; | 4646 EXPR_ORIG_BB_INDEX (INSN_EXPR (insn)) = succ->index; |
4638 | 4647 |
4639 if (bitmap_bit_p (code_motion_visited_blocks, new_bb->index)) | 4648 if (bitmap_clear_bit (code_motion_visited_blocks, new_bb->index)) |
4640 { | 4649 bitmap_set_bit (code_motion_visited_blocks, succ->index); |
4641 bitmap_set_bit (code_motion_visited_blocks, succ->index); | |
4642 bitmap_clear_bit (code_motion_visited_blocks, new_bb->index); | |
4643 } | |
4644 | 4650 |
4645 gcc_assert (LABEL_P (BB_HEAD (new_bb)) | 4651 gcc_assert (LABEL_P (BB_HEAD (new_bb)) |
4646 && LABEL_P (BB_HEAD (succ))); | 4652 && LABEL_P (BB_HEAD (succ))); |
4647 | 4653 |
4648 if (sched_verbose >= 4) | 4654 if (sched_verbose >= 4) |
4880 */ | 4886 */ |
4881 static void | 4887 static void |
4882 move_cond_jump (rtx insn, bnd_t bnd) | 4888 move_cond_jump (rtx insn, bnd_t bnd) |
4883 { | 4889 { |
4884 edge ft_edge; | 4890 edge ft_edge; |
4885 basic_block block_from, block_next, block_new; | 4891 basic_block block_from, block_next, block_new, block_bnd, bb; |
4886 rtx next, prev, link; | 4892 rtx next, prev, link, head; |
4887 | 4893 |
4888 /* BLOCK_FROM holds basic block of the jump. */ | |
4889 block_from = BLOCK_FOR_INSN (insn); | 4894 block_from = BLOCK_FOR_INSN (insn); |
4890 | 4895 block_bnd = BLOCK_FOR_INSN (BND_TO (bnd)); |
4891 /* Moving of jump should not cross any other jumps or | 4896 prev = BND_TO (bnd); |
4892 beginnings of new basic blocks. */ | 4897 |
4893 gcc_assert (block_from == BLOCK_FOR_INSN (BND_TO (bnd))); | 4898 #ifdef ENABLE_CHECKING |
4899 /* Moving of jump should not cross any other jumps or beginnings of new | |
4900 basic blocks. The only exception is when we move a jump through | |
4901 mutually exclusive insns along fallthru edges. */ | |
4902 if (block_from != block_bnd) | |
4903 { | |
4904 bb = block_from; | |
4905 for (link = PREV_INSN (insn); link != PREV_INSN (prev); | |
4906 link = PREV_INSN (link)) | |
4907 { | |
4908 if (INSN_P (link)) | |
4909 gcc_assert (sched_insns_conditions_mutex_p (insn, link)); | |
4910 if (BLOCK_FOR_INSN (link) && BLOCK_FOR_INSN (link) != bb) | |
4911 { | |
4912 gcc_assert (single_pred (bb) == BLOCK_FOR_INSN (link)); | |
4913 bb = BLOCK_FOR_INSN (link); | |
4914 } | |
4915 } | |
4916 } | |
4917 #endif | |
4894 | 4918 |
4895 /* Jump is moved to the boundary. */ | 4919 /* Jump is moved to the boundary. */ |
4896 prev = BND_TO (bnd); | |
4897 next = PREV_INSN (insn); | 4920 next = PREV_INSN (insn); |
4898 BND_TO (bnd) = insn; | 4921 BND_TO (bnd) = insn; |
4899 | 4922 |
4900 ft_edge = find_fallthru_edge (block_from); | 4923 ft_edge = find_fallthru_edge_from (block_from); |
4901 block_next = ft_edge->dest; | 4924 block_next = ft_edge->dest; |
4902 /* There must be a fallthrough block (or where should go | 4925 /* There must be a fallthrough block (or where should go |
4903 control flow in case of false jump predicate otherwise?). */ | 4926 control flow in case of false jump predicate otherwise?). */ |
4904 gcc_assert (block_next); | 4927 gcc_assert (block_next); |
4905 | 4928 |
4906 /* Create new empty basic block after source block. */ | 4929 /* Create new empty basic block after source block. */ |
4907 block_new = sel_split_edge (ft_edge); | 4930 block_new = sel_split_edge (ft_edge); |
4908 gcc_assert (block_new->next_bb == block_next | 4931 gcc_assert (block_new->next_bb == block_next |
4909 && block_from->next_bb == block_new); | 4932 && block_from->next_bb == block_new); |
4910 | 4933 |
4911 gcc_assert (BB_END (block_from) == insn); | 4934 /* Move all instructions except INSN to BLOCK_NEW. */ |
4912 | 4935 bb = block_bnd; |
4913 /* Move all instructions except INSN from BLOCK_FROM to | 4936 head = BB_HEAD (block_new); |
4914 BLOCK_NEW. */ | 4937 while (bb != block_from->next_bb) |
4915 for (link = prev; link != insn; link = NEXT_INSN (link)) | 4938 { |
4916 { | 4939 rtx from, to; |
4917 EXPR_ORIG_BB_INDEX (INSN_EXPR (link)) = block_new->index; | 4940 from = bb == block_bnd ? prev : sel_bb_head (bb); |
4918 df_insn_change_bb (link, block_new); | 4941 to = bb == block_from ? next : sel_bb_end (bb); |
4919 } | 4942 |
4920 | 4943 /* The jump being moved can be the first insn in the block. |
4921 /* Set correct basic block and instructions properties. */ | 4944 In this case we don't have to move anything in this block. */ |
4922 BB_END (block_new) = PREV_INSN (insn); | 4945 if (NEXT_INSN (to) != from) |
4923 | 4946 { |
4924 NEXT_INSN (PREV_INSN (prev)) = insn; | 4947 reorder_insns (from, to, head); |
4925 PREV_INSN (insn) = PREV_INSN (prev); | 4948 |
4949 for (link = to; link != head; link = PREV_INSN (link)) | |
4950 EXPR_ORIG_BB_INDEX (INSN_EXPR (link)) = block_new->index; | |
4951 head = to; | |
4952 } | |
4953 | |
4954 /* Cleanup possibly empty blocks left. */ | |
4955 block_next = bb->next_bb; | |
4956 if (bb != block_from) | |
4957 tidy_control_flow (bb, false); | |
4958 bb = block_next; | |
4959 } | |
4926 | 4960 |
4927 /* Assert there is no jump to BLOCK_NEW, only fallthrough edge. */ | 4961 /* Assert there is no jump to BLOCK_NEW, only fallthrough edge. */ |
4928 gcc_assert (NOTE_INSN_BASIC_BLOCK_P (BB_HEAD (block_new))); | 4962 gcc_assert (NOTE_INSN_BASIC_BLOCK_P (BB_HEAD (block_new))); |
4929 PREV_INSN (prev) = BB_HEAD (block_new); | |
4930 NEXT_INSN (next) = NEXT_INSN (BB_HEAD (block_new)); | |
4931 NEXT_INSN (BB_HEAD (block_new)) = prev; | |
4932 PREV_INSN (NEXT_INSN (next)) = next; | |
4933 | 4963 |
4934 gcc_assert (!sel_bb_empty_p (block_from) | 4964 gcc_assert (!sel_bb_empty_p (block_from) |
4935 && !sel_bb_empty_p (block_new)); | 4965 && !sel_bb_empty_p (block_new)); |
4936 | 4966 |
4937 /* Update data sets for BLOCK_NEW to represent that INSN and | 4967 /* Update data sets for BLOCK_NEW to represent that INSN and |
4956 remove_temp_moveop_nops (bool full_tidying) | 4986 remove_temp_moveop_nops (bool full_tidying) |
4957 { | 4987 { |
4958 int i; | 4988 int i; |
4959 insn_t insn; | 4989 insn_t insn; |
4960 | 4990 |
4961 for (i = 0; VEC_iterate (insn_t, vec_temp_moveop_nops, i, insn); i++) | 4991 FOR_EACH_VEC_ELT (insn_t, vec_temp_moveop_nops, i, insn) |
4962 { | 4992 { |
4963 gcc_assert (INSN_NOP_P (insn)); | 4993 gcc_assert (INSN_NOP_P (insn)); |
4964 return_nop_to_pool (insn, full_tidying); | 4994 return_nop_to_pool (insn, full_tidying); |
4965 } | 4995 } |
4966 | 4996 |
5209 if (stat_bookkeeping_copies > n_bookkeeping_copies_before_moveop) | 5239 if (stat_bookkeeping_copies > n_bookkeeping_copies_before_moveop) |
5210 stat_insns_needed_bookkeeping++; | 5240 stat_insns_needed_bookkeeping++; |
5211 | 5241 |
5212 EXECUTE_IF_SET_IN_BITMAP (current_copies, 0, book_uid, bi) | 5242 EXECUTE_IF_SET_IN_BITMAP (current_copies, 0, book_uid, bi) |
5213 { | 5243 { |
5244 unsigned uid; | |
5245 bitmap_iterator bi; | |
5246 | |
5214 /* We allocate these bitmaps lazily. */ | 5247 /* We allocate these bitmaps lazily. */ |
5215 if (! INSN_ORIGINATORS_BY_UID (book_uid)) | 5248 if (! INSN_ORIGINATORS_BY_UID (book_uid)) |
5216 INSN_ORIGINATORS_BY_UID (book_uid) = BITMAP_ALLOC (NULL); | 5249 INSN_ORIGINATORS_BY_UID (book_uid) = BITMAP_ALLOC (NULL); |
5217 | 5250 |
5218 bitmap_copy (INSN_ORIGINATORS_BY_UID (book_uid), | 5251 bitmap_copy (INSN_ORIGINATORS_BY_UID (book_uid), |
5219 current_originators); | 5252 current_originators); |
5253 | |
5254 /* Transitively add all originators' originators. */ | |
5255 EXECUTE_IF_SET_IN_BITMAP (current_originators, 0, uid, bi) | |
5256 if (INSN_ORIGINATORS_BY_UID (uid)) | |
5257 bitmap_ior_into (INSN_ORIGINATORS_BY_UID (book_uid), | |
5258 INSN_ORIGINATORS_BY_UID (uid)); | |
5220 } | 5259 } |
5221 | 5260 |
5222 return should_move; | 5261 return should_move; |
5223 } | 5262 } |
5224 | 5263 |
5275 | 5314 |
5276 if (sched_verbose >= 2) | 5315 if (sched_verbose >= 2) |
5277 debug_state (FENCE_STATE (fence)); | 5316 debug_state (FENCE_STATE (fence)); |
5278 if (!DEBUG_INSN_P (insn)) | 5317 if (!DEBUG_INSN_P (insn)) |
5279 FENCE_STARTS_CYCLE_P (fence) = 0; | 5318 FENCE_STARTS_CYCLE_P (fence) = 0; |
5319 FENCE_ISSUE_MORE (fence) = can_issue_more; | |
5280 return asm_p; | 5320 return asm_p; |
5281 } | 5321 } |
5282 | 5322 |
5283 /* Update FENCE on which INSN was scheduled and this INSN, too. NEED_STALL | 5323 /* Update FENCE on which INSN was scheduled and this INSN, too. NEED_STALL |
5284 is nonzero if we need to stall after issuing INSN. */ | 5324 is nonzero if we need to stall after issuing INSN. */ |
5472 INSN_UID (insn), FENCE_CYCLE (fence)); | 5512 INSN_UID (insn), FENCE_CYCLE (fence)); |
5473 | 5513 |
5474 blist_add (&bnds, insn, NULL, FENCE_DC (fence)); | 5514 blist_add (&bnds, insn, NULL, FENCE_DC (fence)); |
5475 bnds_tailp = &BLIST_NEXT (bnds); | 5515 bnds_tailp = &BLIST_NEXT (bnds); |
5476 set_target_context (FENCE_TC (fence)); | 5516 set_target_context (FENCE_TC (fence)); |
5517 can_issue_more = FENCE_ISSUE_MORE (fence); | |
5477 target_bb = INSN_BB (insn); | 5518 target_bb = INSN_BB (insn); |
5478 | 5519 |
5479 /* Do while we can add any operation to the current group. */ | 5520 /* Do while we can add any operation to the current group. */ |
5480 do | 5521 do |
5481 { | 5522 { |
5482 blist_t *bnds_tailp1, *bndsp; | 5523 blist_t *bnds_tailp1, *bndsp; |
5483 expr_t expr_vliw; | 5524 expr_t expr_vliw; |
5484 int need_stall; | 5525 int need_stall; |
5485 int was_stall = 0, scheduled_insns = 0, stall_iterations = 0; | 5526 int was_stall = 0, scheduled_insns = 0; |
5486 int max_insns = pipelining_p ? issue_rate : 2 * issue_rate; | 5527 int max_insns = pipelining_p ? issue_rate : 2 * issue_rate; |
5487 int max_stall = pipelining_p ? 1 : 3; | 5528 int max_stall = pipelining_p ? 1 : 3; |
5488 bool last_insn_was_debug = false; | 5529 bool last_insn_was_debug = false; |
5489 bool was_debug_bb_end_p = false; | 5530 bool was_debug_bb_end_p = false; |
5490 | 5531 |
5499 /* Choose the best expression and, if needed, destination register | 5540 /* Choose the best expression and, if needed, destination register |
5500 for it. */ | 5541 for it. */ |
5501 do | 5542 do |
5502 { | 5543 { |
5503 expr_vliw = find_best_expr (&av_vliw, bnds, fence, &need_stall); | 5544 expr_vliw = find_best_expr (&av_vliw, bnds, fence, &need_stall); |
5504 if (!expr_vliw && need_stall) | 5545 if (! expr_vliw && need_stall) |
5505 { | 5546 { |
5506 /* All expressions required a stall. Do not recompute av sets | 5547 /* All expressions required a stall. Do not recompute av sets |
5507 as we'll get the same answer (modulo the insns between | 5548 as we'll get the same answer (modulo the insns between |
5508 the fence and its boundary, which will not be available for | 5549 the fence and its boundary, which will not be available for |
5509 pipelining). */ | 5550 pipelining). |
5510 gcc_assert (! expr_vliw && stall_iterations < 2); | 5551 If we are going to stall for too long, break to recompute av |
5552 sets and bring more insns for pipelining. */ | |
5511 was_stall++; | 5553 was_stall++; |
5512 /* If we are going to stall for too long, break to recompute av | |
5513 sets and bring more insns for pipelining. */ | |
5514 if (need_stall <= 3) | 5554 if (need_stall <= 3) |
5515 stall_for_cycles (fence, need_stall); | 5555 stall_for_cycles (fence, need_stall); |
5516 else | 5556 else |
5517 { | 5557 { |
5518 stall_for_cycles (fence, 1); | 5558 stall_for_cycles (fence, 1); |
5776 { | 5816 { |
5777 /* Even if this insn can be a copy that will be removed during current move_op, | 5817 /* Even if this insn can be a copy that will be removed during current move_op, |
5778 we still need to count it as an originator. */ | 5818 we still need to count it as an originator. */ |
5779 bitmap_set_bit (current_originators, INSN_UID (insn)); | 5819 bitmap_set_bit (current_originators, INSN_UID (insn)); |
5780 | 5820 |
5781 if (!bitmap_bit_p (current_copies, INSN_UID (insn))) | 5821 if (!bitmap_clear_bit (current_copies, INSN_UID (insn))) |
5782 { | 5822 { |
5783 /* Note that original block needs to be rescheduled, as we pulled an | 5823 /* Note that original block needs to be rescheduled, as we pulled an |
5784 instruction out of it. */ | 5824 instruction out of it. */ |
5785 if (INSN_SCHED_TIMES (insn) > 0) | 5825 if (INSN_SCHED_TIMES (insn) > 0) |
5786 bitmap_set_bit (blocks_to_reschedule, BLOCK_FOR_INSN (insn)->index); | 5826 bitmap_set_bit (blocks_to_reschedule, BLOCK_FOR_INSN (insn)->index); |
5787 else if (INSN_UID (insn) < first_emitted_uid && !DEBUG_INSN_P (insn)) | 5827 else if (INSN_UID (insn) < first_emitted_uid && !DEBUG_INSN_P (insn)) |
5788 num_insns_scheduled++; | 5828 num_insns_scheduled++; |
5789 } | 5829 } |
5790 else | |
5791 bitmap_clear_bit (current_copies, INSN_UID (insn)); | |
5792 | 5830 |
5793 /* For instructions we must immediately remove insn from the | 5831 /* For instructions we must immediately remove insn from the |
5794 stream, so subsequent update_data_sets () won't include this | 5832 stream, so subsequent update_data_sets () won't include this |
5795 insn into av_set. | 5833 insn into av_set. |
5796 For expr we must make insn look like "INSN_REG (insn) := c_expr". */ | 5834 For expr we must make insn look like "INSN_REG (insn) := c_expr". */ |
5803 static bool | 5841 static bool |
5804 maybe_emit_renaming_copy (rtx insn, | 5842 maybe_emit_renaming_copy (rtx insn, |
5805 moveop_static_params_p params) | 5843 moveop_static_params_p params) |
5806 { | 5844 { |
5807 bool insn_emitted = false; | 5845 bool insn_emitted = false; |
5808 rtx cur_reg = expr_dest_reg (params->c_expr); | 5846 rtx cur_reg; |
5809 | 5847 |
5810 gcc_assert (!cur_reg || (params->dest && REG_P (params->dest))); | 5848 /* Bail out early when expression can not be renamed at all. */ |
5849 if (!EXPR_SEPARABLE_P (params->c_expr)) | |
5850 return false; | |
5851 | |
5852 cur_reg = expr_dest_reg (params->c_expr); | |
5853 gcc_assert (cur_reg && params->dest && REG_P (params->dest)); | |
5811 | 5854 |
5812 /* If original operation has expr and the register chosen for | 5855 /* If original operation has expr and the register chosen for |
5813 that expr is not original operation's dest reg, substitute | 5856 that expr is not original operation's dest reg, substitute |
5814 operation's right hand side with the register chosen. */ | 5857 operation's right hand side with the register chosen. */ |
5815 if (cur_reg != NULL_RTX && REGNO (params->dest) != REGNO (cur_reg)) | 5858 if (REGNO (params->dest) != REGNO (cur_reg)) |
5816 { | 5859 { |
5817 insn_t reg_move_insn, reg_move_insn_rtx; | 5860 insn_t reg_move_insn, reg_move_insn_rtx; |
5818 | 5861 |
5819 reg_move_insn_rtx = create_insn_rtx_with_rhs (INSN_VINSN (insn), | 5862 reg_move_insn_rtx = create_insn_rtx_with_rhs (INSN_VINSN (insn), |
5820 params->dest); | 5863 params->dest); |
6336 not found below. In most cases, this situation is an error. | 6379 not found below. In most cases, this situation is an error. |
6337 The exception is when the original operation is blocked by | 6380 The exception is when the original operation is blocked by |
6338 bookkeeping generated for another fence or for another path in current | 6381 bookkeeping generated for another fence or for another path in current |
6339 move_op. */ | 6382 move_op. */ |
6340 gcc_assert (res == 1 | 6383 gcc_assert (res == 1 |
6341 || (res == 0 | 6384 || (res == 0 |
6342 && av_set_could_be_blocked_by_bookkeeping_p (orig_ops, | 6385 && av_set_could_be_blocked_by_bookkeeping_p (orig_ops, |
6343 static_params)) | 6386 static_params)) |
6344 || res == -1); | 6387 || res == -1); |
6345 #endif | 6388 #endif |
6346 | 6389 |
6347 /* Merge data, clean up, etc. */ | 6390 /* Merge data, clean up, etc. */ |
6348 if (res != -1 && code_motion_path_driver_info->after_merge_succs) | 6391 if (res != -1 && code_motion_path_driver_info->after_merge_succs) |
6349 code_motion_path_driver_info->after_merge_succs (&lparams, static_params); | 6392 code_motion_path_driver_info->after_merge_succs (&lparams, static_params); |
6678 { | 6721 { |
6679 gcc_assert (succ_bbi > bbi); | 6722 gcc_assert (succ_bbi > bbi); |
6680 | 6723 |
6681 init_seqno_1 (succ, visited_bbs, blocks_to_reschedule); | 6724 init_seqno_1 (succ, visited_bbs, blocks_to_reschedule); |
6682 } | 6725 } |
6726 else if (blocks_to_reschedule) | |
6727 bitmap_set_bit (forced_ebb_heads, succ->index); | |
6683 } | 6728 } |
6684 | 6729 |
6685 for (insn = BB_END (bb); insn != note; insn = PREV_INSN (insn)) | 6730 for (insn = BB_END (bb); insn != note; insn = PREV_INSN (insn)) |
6686 INSN_SEQNO (insn) = cur_seqno--; | 6731 INSN_SEQNO (insn) = cur_seqno--; |
6687 } | 6732 } |
6766 /* Check that we're starting with a valid information. */ | 6811 /* Check that we're starting with a valid information. */ |
6767 gcc_assert (loop_latch_edge (current_loop_nest)); | 6812 gcc_assert (loop_latch_edge (current_loop_nest)); |
6768 gcc_assert (LOOP_MARKED_FOR_PIPELINING_P (current_loop_nest)); | 6813 gcc_assert (LOOP_MARKED_FOR_PIPELINING_P (current_loop_nest)); |
6769 } | 6814 } |
6770 | 6815 |
6771 /* Purge meaningless empty blocks in the middle of a region. */ | |
6772 static void | |
6773 purge_empty_blocks (void) | |
6774 { | |
6775 /* Do not attempt to delete preheader. */ | |
6776 int i = sel_is_loop_preheader_p (BASIC_BLOCK (BB_TO_BLOCK (0))) ? 1 : 0; | |
6777 | |
6778 while (i < current_nr_blocks) | |
6779 { | |
6780 basic_block b = BASIC_BLOCK (BB_TO_BLOCK (i)); | |
6781 | |
6782 if (maybe_tidy_empty_bb (b)) | |
6783 continue; | |
6784 | |
6785 i++; | |
6786 } | |
6787 } | |
6788 | |
6789 /* Compute instruction priorities for current region. */ | 6816 /* Compute instruction priorities for current region. */ |
6790 static void | 6817 static void |
6791 sel_compute_priorities (int rgn) | 6818 sel_compute_priorities (int rgn) |
6792 { | 6819 { |
6793 sched_rgn_compute_dependencies (rgn); | 6820 sched_rgn_compute_dependencies (rgn); |
6866 } | 6893 } |
6867 | 6894 |
6868 /* Set hooks so that no newly generated insn will go out unnoticed. */ | 6895 /* Set hooks so that no newly generated insn will go out unnoticed. */ |
6869 sel_register_cfg_hooks (); | 6896 sel_register_cfg_hooks (); |
6870 | 6897 |
6871 /* !!! We call target.sched.md_init () for the whole region, but we invoke | 6898 /* !!! We call target.sched.init () for the whole region, but we invoke |
6872 targetm.sched.md_finish () for every ebb. */ | 6899 targetm.sched.finish () for every ebb. */ |
6873 if (targetm.sched.md_init) | 6900 if (targetm.sched.init) |
6874 /* None of the arguments are actually used in any target. */ | 6901 /* None of the arguments are actually used in any target. */ |
6875 targetm.sched.md_init (sched_dump, sched_verbose, -1); | 6902 targetm.sched.init (sched_dump, sched_verbose, -1); |
6876 | 6903 |
6877 first_emitted_uid = get_max_uid () + 1; | 6904 first_emitted_uid = get_max_uid () + 1; |
6878 preheader_removed = false; | 6905 preheader_removed = false; |
6879 | 6906 |
6880 /* Reset register allocation ticks array. */ | 6907 /* Reset register allocation ticks array. */ |
6950 reset_sched_cycles_in_current_ebb (void) | 6977 reset_sched_cycles_in_current_ebb (void) |
6951 { | 6978 { |
6952 int last_clock = 0; | 6979 int last_clock = 0; |
6953 int haifa_last_clock = -1; | 6980 int haifa_last_clock = -1; |
6954 int haifa_clock = 0; | 6981 int haifa_clock = 0; |
6982 int issued_insns = 0; | |
6955 insn_t insn; | 6983 insn_t insn; |
6956 | 6984 |
6957 if (targetm.sched.md_init) | 6985 if (targetm.sched.init) |
6958 { | 6986 { |
6959 /* None of the arguments are actually used in any target. | 6987 /* None of the arguments are actually used in any target. |
6960 NB: We should have md_reset () hook for cases like this. */ | 6988 NB: We should have md_reset () hook for cases like this. */ |
6961 targetm.sched.md_init (sched_dump, sched_verbose, -1); | 6989 targetm.sched.init (sched_dump, sched_verbose, -1); |
6962 } | 6990 } |
6963 | 6991 |
6964 state_reset (curr_state); | 6992 state_reset (curr_state); |
6965 advance_state (curr_state); | 6993 advance_state (curr_state); |
6966 | 6994 |
6968 insn != current_sched_info->next_tail; | 6996 insn != current_sched_info->next_tail; |
6969 insn = NEXT_INSN (insn)) | 6997 insn = NEXT_INSN (insn)) |
6970 { | 6998 { |
6971 int cost, haifa_cost; | 6999 int cost, haifa_cost; |
6972 int sort_p; | 7000 int sort_p; |
6973 bool asm_p, real_insn, after_stall; | 7001 bool asm_p, real_insn, after_stall, all_issued; |
6974 int clock; | 7002 int clock; |
6975 | 7003 |
6976 if (!INSN_P (insn)) | 7004 if (!INSN_P (insn)) |
6977 continue; | 7005 continue; |
6978 | 7006 |
7004 if (INSN_AFTER_STALL_P (insn) && cost > haifa_cost) | 7032 if (INSN_AFTER_STALL_P (insn) && cost > haifa_cost) |
7005 { | 7033 { |
7006 haifa_cost = cost; | 7034 haifa_cost = cost; |
7007 after_stall = 1; | 7035 after_stall = 1; |
7008 } | 7036 } |
7009 | 7037 all_issued = issued_insns == issue_rate; |
7038 if (haifa_cost == 0 && all_issued) | |
7039 haifa_cost = 1; | |
7010 if (haifa_cost > 0) | 7040 if (haifa_cost > 0) |
7011 { | 7041 { |
7012 int i = 0; | 7042 int i = 0; |
7013 | 7043 |
7014 while (haifa_cost--) | 7044 while (haifa_cost--) |
7015 { | 7045 { |
7016 advance_state (curr_state); | 7046 advance_state (curr_state); |
7047 issued_insns = 0; | |
7017 i++; | 7048 i++; |
7018 | 7049 |
7019 if (sched_verbose >= 2) | 7050 if (sched_verbose >= 2) |
7020 { | 7051 { |
7021 sel_print ("advance_state (state_transition)\n"); | 7052 sel_print ("advance_state (state_transition)\n"); |
7028 if (!after_stall | 7059 if (!after_stall |
7029 && real_insn | 7060 && real_insn |
7030 && haifa_cost > 0 | 7061 && haifa_cost > 0 |
7031 && estimate_insn_cost (insn, curr_state) == 0) | 7062 && estimate_insn_cost (insn, curr_state) == 0) |
7032 break; | 7063 break; |
7033 } | 7064 |
7065 /* When the data dependency stall is longer than the DFA stall, | |
7066 and when we have issued exactly issue_rate insns and stalled, | |
7067 it could be that after this longer stall the insn will again | |
7068 become unavailable to the DFA restrictions. Looks strange | |
7069 but happens e.g. on x86-64. So recheck DFA on the last | |
7070 iteration. */ | |
7071 if ((after_stall || all_issued) | |
7072 && real_insn | |
7073 && haifa_cost == 0) | |
7074 haifa_cost = estimate_insn_cost (insn, curr_state); | |
7075 } | |
7034 | 7076 |
7035 haifa_clock += i; | 7077 haifa_clock += i; |
7078 if (sched_verbose >= 2) | |
7079 sel_print ("haifa clock: %d\n", haifa_clock); | |
7036 } | 7080 } |
7037 else | 7081 else |
7038 gcc_assert (haifa_cost == 0); | 7082 gcc_assert (haifa_cost == 0); |
7039 | 7083 |
7040 if (sched_verbose >= 2) | 7084 if (sched_verbose >= 2) |
7044 while (targetm.sched.dfa_new_cycle (sched_dump, sched_verbose, insn, | 7088 while (targetm.sched.dfa_new_cycle (sched_dump, sched_verbose, insn, |
7045 haifa_last_clock, haifa_clock, | 7089 haifa_last_clock, haifa_clock, |
7046 &sort_p)) | 7090 &sort_p)) |
7047 { | 7091 { |
7048 advance_state (curr_state); | 7092 advance_state (curr_state); |
7093 issued_insns = 0; | |
7049 haifa_clock++; | 7094 haifa_clock++; |
7050 if (sched_verbose >= 2) | 7095 if (sched_verbose >= 2) |
7051 { | 7096 { |
7052 sel_print ("advance_state (dfa_new_cycle)\n"); | 7097 sel_print ("advance_state (dfa_new_cycle)\n"); |
7053 debug_state (curr_state); | 7098 debug_state (curr_state); |
7099 sel_print ("haifa clock: %d\n", haifa_clock + 1); | |
7054 } | 7100 } |
7055 } | 7101 } |
7056 | 7102 |
7057 if (real_insn) | 7103 if (real_insn) |
7058 { | 7104 { |
7059 cost = state_transition (curr_state, insn); | 7105 cost = state_transition (curr_state, insn); |
7106 issued_insns++; | |
7060 | 7107 |
7061 if (sched_verbose >= 2) | 7108 if (sched_verbose >= 2) |
7062 debug_state (curr_state); | 7109 { |
7063 | 7110 sel_print ("scheduled insn %d, clock %d\n", INSN_UID (insn), |
7111 haifa_clock + 1); | |
7112 debug_state (curr_state); | |
7113 } | |
7064 gcc_assert (cost < 0); | 7114 gcc_assert (cost < 0); |
7065 } | 7115 } |
7066 | 7116 |
7067 if (targetm.sched.variable_issue) | 7117 if (targetm.sched.variable_issue) |
7068 targetm.sched.variable_issue (sched_dump, sched_verbose, insn, 0); | 7118 targetm.sched.variable_issue (sched_dump, sched_verbose, insn, 0); |
7134 continue; | 7184 continue; |
7135 | 7185 |
7136 if (reset_sched_cycles_p) | 7186 if (reset_sched_cycles_p) |
7137 reset_sched_cycles_in_current_ebb (); | 7187 reset_sched_cycles_in_current_ebb (); |
7138 | 7188 |
7139 if (targetm.sched.md_init) | 7189 if (targetm.sched.init) |
7140 targetm.sched.md_init (sched_dump, sched_verbose, -1); | 7190 targetm.sched.init (sched_dump, sched_verbose, -1); |
7141 | 7191 |
7142 put_TImodes (); | 7192 put_TImodes (); |
7143 | 7193 |
7144 if (targetm.sched.md_finish) | 7194 if (targetm.sched.finish) |
7145 { | 7195 { |
7146 targetm.sched.md_finish (sched_dump, sched_verbose); | 7196 targetm.sched.finish (sched_dump, sched_verbose); |
7147 | 7197 |
7148 /* Extend luids so that insns generated by the target will | 7198 /* Extend luids so that insns generated by the target will |
7149 get zero luid. */ | 7199 get zero luid. */ |
7150 sched_init_luids (NULL, NULL, NULL, NULL); | 7200 sched_init_luids (NULL, NULL, NULL, NULL); |
7151 } | 7201 } |
7471 | 7521 |
7472 for (i = 0; i < current_nr_blocks; i++) | 7522 for (i = 0; i < current_nr_blocks; i++) |
7473 { | 7523 { |
7474 basic_block bb = EBB_FIRST_BB (i); | 7524 basic_block bb = EBB_FIRST_BB (i); |
7475 | 7525 |
7476 if (sel_bb_empty_p (bb)) | |
7477 { | |
7478 bitmap_clear_bit (blocks_to_reschedule, bb->index); | |
7479 continue; | |
7480 } | |
7481 | |
7482 if (bitmap_bit_p (blocks_to_reschedule, bb->index)) | 7526 if (bitmap_bit_p (blocks_to_reschedule, bb->index)) |
7483 { | 7527 { |
7528 if (! bb_ends_ebb_p (bb)) | |
7529 bitmap_set_bit (blocks_to_reschedule, bb_next_bb (bb)->index); | |
7530 if (sel_bb_empty_p (bb)) | |
7531 { | |
7532 bitmap_clear_bit (blocks_to_reschedule, bb->index); | |
7533 continue; | |
7534 } | |
7484 clear_outdated_rtx_info (bb); | 7535 clear_outdated_rtx_info (bb); |
7485 if (sel_insn_is_speculation_check (BB_END (bb)) | 7536 if (sel_insn_is_speculation_check (BB_END (bb)) |
7486 && JUMP_P (BB_END (bb))) | 7537 && JUMP_P (BB_END (bb))) |
7487 bitmap_set_bit (blocks_to_reschedule, | 7538 bitmap_set_bit (blocks_to_reschedule, |
7488 BRANCH_EDGE (bb)->dest->index); | 7539 BRANCH_EDGE (bb)->dest->index); |
7489 } | 7540 } |
7490 else if (INSN_SCHED_TIMES (sel_bb_head (bb)) <= 0) | 7541 else if (! sel_bb_empty_p (bb) |
7542 && INSN_SCHED_TIMES (sel_bb_head (bb)) <= 0) | |
7491 bitmap_set_bit (blocks_to_reschedule, bb->index); | 7543 bitmap_set_bit (blocks_to_reschedule, bb->index); |
7492 } | 7544 } |
7493 | 7545 |
7494 for (i = 0; i < current_nr_blocks; i++) | 7546 for (i = 0; i < current_nr_blocks; i++) |
7495 { | 7547 { |
7511 orig_max_seqno = init_seqno (0, blocks_to_reschedule, bb); | 7563 orig_max_seqno = init_seqno (0, blocks_to_reschedule, bb); |
7512 | 7564 |
7513 /* Mark BB as head of the new ebb. */ | 7565 /* Mark BB as head of the new ebb. */ |
7514 bitmap_set_bit (forced_ebb_heads, bb->index); | 7566 bitmap_set_bit (forced_ebb_heads, bb->index); |
7515 | 7567 |
7516 bitmap_clear_bit (blocks_to_reschedule, bb->index); | |
7517 | |
7518 gcc_assert (fences == NULL); | 7568 gcc_assert (fences == NULL); |
7519 | 7569 |
7520 init_fences (bb_note (bb)); | 7570 init_fences (bb_note (bb)); |
7521 | 7571 |
7522 sel_sched_region_2 (orig_max_seqno); | 7572 sel_sched_region_2 (orig_max_seqno); |