Mercurial > hg > CbC > CbC_gcc
comparison gcc/cfgrtl.c @ 132:d34655255c78
update gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 10:21:07 +0900 |
parents | 84e7813d76e9 |
children | 1830386684a0 |
comparison
equal
deleted
inserted
replaced
130:e108057fa461 | 132:d34655255c78 |
---|---|
1 /* Control flow graph manipulation code for GNU compiler. | 1 /* Control flow graph manipulation code for GNU compiler. |
2 Copyright (C) 1987-2017 Free Software Foundation, Inc. | 2 Copyright (C) 1987-2018 Free Software Foundation, Inc. |
3 | 3 |
4 This file is part of GCC. | 4 This file is part of GCC. |
5 | 5 |
6 GCC is free software; you can redistribute it and/or modify it under | 6 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 | 7 the terms of the GNU General Public License as published by the Free |
811 are already contiguous. */ | 811 are already contiguous. */ |
812 | 812 |
813 static void | 813 static void |
814 rtl_merge_blocks (basic_block a, basic_block b) | 814 rtl_merge_blocks (basic_block a, basic_block b) |
815 { | 815 { |
816 /* If B is a forwarder block whose outgoing edge has no location, we'll | |
817 propagate the locus of the edge between A and B onto it. */ | |
818 const bool forward_edge_locus | |
819 = (b->flags & BB_FORWARDER_BLOCK) != 0 | |
820 && LOCATION_LOCUS (EDGE_SUCC (b, 0)->goto_locus) == UNKNOWN_LOCATION; | |
816 rtx_insn *b_head = BB_HEAD (b), *b_end = BB_END (b), *a_end = BB_END (a); | 821 rtx_insn *b_head = BB_HEAD (b), *b_end = BB_END (b), *a_end = BB_END (a); |
817 rtx_insn *del_first = NULL, *del_last = NULL; | 822 rtx_insn *del_first = NULL, *del_last = NULL; |
818 rtx_insn *b_debug_start = b_end, *b_debug_end = b_end; | 823 rtx_insn *b_debug_start = b_end, *b_debug_end = b_end; |
819 bool forwarder_p = (b->flags & BB_FORWARDER_BLOCK) != 0; | |
820 int b_empty = 0; | 824 int b_empty = 0; |
821 | 825 |
822 if (dump_file) | 826 if (dump_file) |
823 fprintf (dump_file, "Merging block %d into block %d...\n", b->index, | 827 fprintf (dump_file, "Merging block %d into block %d...\n", b->index, |
824 a->index); | 828 a->index); |
885 hanging out between the two blocks. */ | 889 hanging out between the two blocks. */ |
886 BB_END (a) = a_end; | 890 BB_END (a) = a_end; |
887 BB_HEAD (b) = b_empty ? NULL : b_head; | 891 BB_HEAD (b) = b_empty ? NULL : b_head; |
888 delete_insn_chain (del_first, del_last, true); | 892 delete_insn_chain (del_first, del_last, true); |
889 | 893 |
890 /* When not optimizing and the edge is the only place in RTL which holds | 894 /* If not optimizing, preserve the locus of the single edge between |
891 some unique locus, emit a nop with that locus in between. */ | 895 blocks A and B if necessary by emitting a nop. */ |
892 if (!optimize) | 896 if (!optimize |
897 && !forward_edge_locus | |
898 && !DECL_IGNORED_P (current_function_decl)) | |
893 { | 899 { |
894 emit_nop_for_unique_locus_between (a, b); | 900 emit_nop_for_unique_locus_between (a, b); |
895 a_end = BB_END (a); | 901 a_end = BB_END (a); |
896 } | 902 } |
897 | 903 |
916 BB_END (a) = b_debug_end; | 922 BB_END (a) = b_debug_end; |
917 } | 923 } |
918 | 924 |
919 df_bb_delete (b->index); | 925 df_bb_delete (b->index); |
920 | 926 |
921 /* If B was a forwarder block, propagate the locus on the edge. */ | 927 if (forward_edge_locus) |
922 if (forwarder_p | |
923 && LOCATION_LOCUS (EDGE_SUCC (b, 0)->goto_locus) == UNKNOWN_LOCATION) | |
924 EDGE_SUCC (b, 0)->goto_locus = EDGE_SUCC (a, 0)->goto_locus; | 928 EDGE_SUCC (b, 0)->goto_locus = EDGE_SUCC (a, 0)->goto_locus; |
925 | 929 |
926 if (dump_file) | 930 if (dump_file) |
927 fprintf (dump_file, "Merged blocks %d and %d.\n", a->index, b->index); | 931 fprintf (dump_file, "Merged blocks %d and %d.\n", a->index, b->index); |
928 } | 932 } |
1115 simple jump and remove its associated CODE_LABEL | 1119 simple jump and remove its associated CODE_LABEL |
1116 and ADDR_VEC or ADDR_DIFF_VEC. */ | 1120 and ADDR_VEC or ADDR_DIFF_VEC. */ |
1117 if (tablejump_p (insn, &label, &table)) | 1121 if (tablejump_p (insn, &label, &table)) |
1118 delete_insn_chain (label, table, false); | 1122 delete_insn_chain (label, table, false); |
1119 | 1123 |
1120 barrier = next_nonnote_insn (BB_END (src)); | 1124 barrier = next_nonnote_nondebug_insn (BB_END (src)); |
1121 if (!barrier || !BARRIER_P (barrier)) | 1125 if (!barrier || !BARRIER_P (barrier)) |
1122 emit_barrier_after (BB_END (src)); | 1126 emit_barrier_after (BB_END (src)); |
1123 else | 1127 else |
1124 { | 1128 { |
1125 if (barrier != NEXT_INSN (BB_END (src))) | 1129 if (barrier != NEXT_INSN (BB_END (src))) |
1331 But make sure reg crossing note doesn't already exist before | 1335 But make sure reg crossing note doesn't already exist before |
1332 inserting. */ | 1336 inserting. */ |
1333 if (BB_PARTITION (e->src) != BB_PARTITION (e->dest)) | 1337 if (BB_PARTITION (e->src) != BB_PARTITION (e->dest)) |
1334 { | 1338 { |
1335 e->flags |= EDGE_CROSSING; | 1339 e->flags |= EDGE_CROSSING; |
1336 if (JUMP_P (BB_END (e->src)) | 1340 if (JUMP_P (BB_END (e->src))) |
1337 && !CROSSING_JUMP_P (BB_END (e->src))) | |
1338 CROSSING_JUMP_P (BB_END (e->src)) = 1; | 1341 CROSSING_JUMP_P (BB_END (e->src)) = 1; |
1339 } | 1342 } |
1340 else if (BB_PARTITION (e->src) == BB_PARTITION (e->dest)) | 1343 else if (BB_PARTITION (e->src) == BB_PARTITION (e->dest)) |
1341 { | 1344 { |
1342 e->flags &= ~EDGE_CROSSING; | 1345 e->flags &= ~EDGE_CROSSING; |
1531 edge_iterator ei; | 1534 edge_iterator ei; |
1532 bool found = false; | 1535 bool found = false; |
1533 | 1536 |
1534 basic_block bb = create_basic_block (BB_HEAD (e->dest), NULL, | 1537 basic_block bb = create_basic_block (BB_HEAD (e->dest), NULL, |
1535 ENTRY_BLOCK_PTR_FOR_FN (cfun)); | 1538 ENTRY_BLOCK_PTR_FOR_FN (cfun)); |
1539 bb->count = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count; | |
1540 | |
1541 /* Make sure new block ends up in correct hot/cold section. */ | |
1542 BB_COPY_PARTITION (bb, e->dest); | |
1536 | 1543 |
1537 /* Change the existing edge's source to be the new block, and add | 1544 /* Change the existing edge's source to be the new block, and add |
1538 a new edge from the entry block to the new block. */ | 1545 a new edge from the entry block to the new block. */ |
1539 e->src = bb; | 1546 e->src = bb; |
1540 for (ei = ei_start (ENTRY_BLOCK_PTR_FOR_FN (cfun)->succs); | 1547 for (ei = ei_start (ENTRY_BLOCK_PTR_FOR_FN (cfun)->succs); |
1626 new_head = BB_END (e->src); | 1633 new_head = BB_END (e->src); |
1627 new_head = NEXT_INSN (new_head); | 1634 new_head = NEXT_INSN (new_head); |
1628 | 1635 |
1629 jump_block = create_basic_block (new_head, NULL, e->src); | 1636 jump_block = create_basic_block (new_head, NULL, e->src); |
1630 jump_block->count = count; | 1637 jump_block->count = count; |
1631 jump_block->frequency = EDGE_FREQUENCY (e); | |
1632 | 1638 |
1633 /* Make sure new block ends up in correct hot/cold section. */ | 1639 /* Make sure new block ends up in correct hot/cold section. */ |
1634 | 1640 |
1635 BB_COPY_PARTITION (jump_block, e->src); | 1641 BB_COPY_PARTITION (jump_block, e->src); |
1636 | 1642 |
1650 add also edge from asm goto bb to target. */ | 1656 add also edge from asm goto bb to target. */ |
1651 if (asm_goto_edge) | 1657 if (asm_goto_edge) |
1652 { | 1658 { |
1653 new_edge->probability = new_edge->probability.apply_scale (1, 2); | 1659 new_edge->probability = new_edge->probability.apply_scale (1, 2); |
1654 jump_block->count = jump_block->count.apply_scale (1, 2); | 1660 jump_block->count = jump_block->count.apply_scale (1, 2); |
1655 jump_block->frequency /= 2; | |
1656 edge new_edge2 = make_edge (new_edge->src, target, | 1661 edge new_edge2 = make_edge (new_edge->src, target, |
1657 e->flags & ~EDGE_FALLTHRU); | 1662 e->flags & ~EDGE_FALLTHRU); |
1658 new_edge2->probability = probability - new_edge->probability; | 1663 new_edge2->probability = probability - new_edge->probability; |
1659 } | 1664 } |
1660 | 1665 |
1745 | 1750 |
1746 So search through a sequence of barriers, labels, and notes for | 1751 So search through a sequence of barriers, labels, and notes for |
1747 the head of block C and assert that we really do fall through. */ | 1752 the head of block C and assert that we really do fall through. */ |
1748 | 1753 |
1749 for (q = NEXT_INSN (BB_END (b)); q != BB_HEAD (c); q = NEXT_INSN (q)) | 1754 for (q = NEXT_INSN (BB_END (b)); q != BB_HEAD (c); q = NEXT_INSN (q)) |
1750 if (INSN_P (q)) | 1755 if (NONDEBUG_INSN_P (q)) |
1751 return; | 1756 return; |
1752 | 1757 |
1753 /* Remove what will soon cease being the jump insn from the source block. | 1758 /* Remove what will soon cease being the jump insn from the source block. |
1754 If block B consisted only of this single jump, turn it into a deleted | 1759 If block B consisted only of this single jump, turn it into a deleted |
1755 note. */ | 1760 note. */ |
2189 break; | 2194 break; |
2190 } | 2195 } |
2191 } | 2196 } |
2192 } | 2197 } |
2193 | 2198 |
2194 for (tmp_rtx = rtx_first; NULL != tmp_rtx; tmp_rtx = NEXT_INSN (tmp_rtx)) | 2199 for (tmp_rtx = rtx_first; tmp_rtx != NULL; tmp_rtx = NEXT_INSN (tmp_rtx)) |
2195 { | 2200 { |
2196 if (flags & TDF_BLOCKS) | 2201 if (flags & TDF_BLOCKS) |
2197 { | 2202 { |
2198 bb = start[INSN_UID (tmp_rtx)]; | 2203 bb = start[INSN_UID (tmp_rtx)]; |
2199 if (bb != NULL) | 2204 if (bb != NULL) |
2243 | 2248 |
2244 void | 2249 void |
2245 update_br_prob_note (basic_block bb) | 2250 update_br_prob_note (basic_block bb) |
2246 { | 2251 { |
2247 rtx note; | 2252 rtx note; |
2253 note = find_reg_note (BB_END (bb), REG_BR_PROB, NULL_RTX); | |
2248 if (!JUMP_P (BB_END (bb)) || !BRANCH_EDGE (bb)->probability.initialized_p ()) | 2254 if (!JUMP_P (BB_END (bb)) || !BRANCH_EDGE (bb)->probability.initialized_p ()) |
2249 return; | 2255 { |
2250 note = find_reg_note (BB_END (bb), REG_BR_PROB, NULL_RTX); | 2256 if (note) |
2257 { | |
2258 rtx *note_link, this_rtx; | |
2259 | |
2260 note_link = ®_NOTES (BB_END (bb)); | |
2261 for (this_rtx = *note_link; this_rtx; this_rtx = XEXP (this_rtx, 1)) | |
2262 if (this_rtx == note) | |
2263 { | |
2264 *note_link = XEXP (this_rtx, 1); | |
2265 break; | |
2266 } | |
2267 } | |
2268 return; | |
2269 } | |
2251 if (!note | 2270 if (!note |
2252 || XINT (note, 0) == BRANCH_EDGE (bb)->probability.to_reg_br_prob_note ()) | 2271 || XINT (note, 0) == BRANCH_EDGE (bb)->probability.to_reg_br_prob_note ()) |
2253 return; | 2272 return; |
2254 XINT (note, 0) = BRANCH_EDGE (bb)->probability.to_reg_br_prob_note (); | 2273 XINT (note, 0) = BRANCH_EDGE (bb)->probability.to_reg_br_prob_note (); |
2255 } | 2274 } |
2266 /* Include any jump table following the basic block. */ | 2285 /* Include any jump table following the basic block. */ |
2267 if (tablejump_p (end, NULL, &table)) | 2286 if (tablejump_p (end, NULL, &table)) |
2268 end = table; | 2287 end = table; |
2269 | 2288 |
2270 /* Include any barriers that may follow the basic block. */ | 2289 /* Include any barriers that may follow the basic block. */ |
2271 tmp = next_nonnote_insn_bb (end); | 2290 tmp = next_nonnote_nondebug_insn_bb (end); |
2272 while (tmp && BARRIER_P (tmp)) | 2291 while (tmp && BARRIER_P (tmp)) |
2273 { | 2292 { |
2274 end = tmp; | 2293 end = tmp; |
2275 tmp = next_nonnote_insn_bb (end); | 2294 tmp = next_nonnote_nondebug_insn_bb (end); |
2276 } | 2295 } |
2277 | 2296 |
2278 return end; | 2297 return end; |
2279 } | 2298 } |
2280 | 2299 |
2523 | 2542 |
2524 if (e->flags & EDGE_ABNORMAL) | 2543 if (e->flags & EDGE_ABNORMAL) |
2525 n_abnormal++; | 2544 n_abnormal++; |
2526 } | 2545 } |
2527 | 2546 |
2528 if (!has_crossing_edge | 2547 if (!has_crossing_edge |
2529 && JUMP_P (BB_END (bb)) | 2548 && JUMP_P (BB_END (bb)) |
2530 && CROSSING_JUMP_P (BB_END (bb))) | 2549 && CROSSING_JUMP_P (BB_END (bb))) |
2531 { | 2550 { |
2532 print_rtl_with_bb (stderr, get_insns (), TDF_BLOCKS | TDF_DETAILS); | 2551 print_rtl_with_bb (stderr, get_insns (), TDF_BLOCKS | TDF_DETAILS); |
2533 error ("Region crossing jump across same section in bb %i", | 2552 error ("Region crossing jump across same section in bb %i", |
2534 bb->index); | 2553 bb->index); |
2535 err = 1; | 2554 err = 1; |
2536 } | 2555 } |
2537 | 2556 |
2538 if (n_eh && !find_reg_note (BB_END (bb), REG_EH_REGION, NULL_RTX)) | 2557 if (n_eh && !find_reg_note (BB_END (bb), REG_EH_REGION, NULL_RTX)) |
2539 { | 2558 { |
2540 error ("missing REG_EH_REGION note at the end of bb %i", bb->index); | 2559 error ("missing REG_EH_REGION note at the end of bb %i", bb->index); |
2541 err = 1; | 2560 err = 1; |
2589 || any_uncondjump_p (BB_END (bb)))) | 2608 || any_uncondjump_p (BB_END (bb)))) |
2590 { | 2609 { |
2591 error ("abnormal edges for no purpose in bb %i", bb->index); | 2610 error ("abnormal edges for no purpose in bb %i", bb->index); |
2592 err = 1; | 2611 err = 1; |
2593 } | 2612 } |
2613 | |
2614 int has_eh = -1; | |
2615 FOR_EACH_EDGE (e, ei, bb->preds) | |
2616 { | |
2617 if (has_eh == -1) | |
2618 has_eh = (e->flags & EDGE_EH); | |
2619 if ((e->flags & EDGE_EH) == has_eh) | |
2620 continue; | |
2621 error ("EH incoming edge mixed with non-EH incoming edges " | |
2622 "in bb %i", bb->index); | |
2623 err = 1; | |
2624 break; | |
2625 } | |
2594 } | 2626 } |
2595 | 2627 |
2596 /* If there are partitions, do a sanity check on them: A basic block in | 2628 /* If there are partitions, do a sanity check on them: A basic block in |
2597 a cold partition cannot dominate a basic block in a hot partition. */ | 2629 a cold partition cannot dominate a basic block in a hot partition. */ |
2598 if (crtl->has_bb_partition && !err) | 2630 if (crtl->has_bb_partition && !err |
2631 && current_ir_type () == IR_RTL_CFGLAYOUT) | |
2599 { | 2632 { |
2600 vec<basic_block> bbs_to_fix = find_partition_fixes (true); | 2633 vec<basic_block> bbs_to_fix = find_partition_fixes (true); |
2601 err = !bbs_to_fix.is_empty (); | 2634 err = !bbs_to_fix.is_empty (); |
2602 } | 2635 } |
2603 | 2636 |
2886 err = 1; | 2919 err = 1; |
2887 } | 2920 } |
2888 else | 2921 else |
2889 for (insn = NEXT_INSN (BB_END (e->src)); insn != BB_HEAD (e->dest); | 2922 for (insn = NEXT_INSN (BB_END (e->src)); insn != BB_HEAD (e->dest); |
2890 insn = NEXT_INSN (insn)) | 2923 insn = NEXT_INSN (insn)) |
2891 if (BARRIER_P (insn) || INSN_P (insn)) | 2924 if (BARRIER_P (insn) || NONDEBUG_INSN_P (insn)) |
2892 { | 2925 { |
2893 error ("verify_flow_info: Incorrect fallthru %i->%i", | 2926 error ("verify_flow_info: Incorrect fallthru %i->%i", |
2894 e->src->index, e->dest->index); | 2927 e->src->index, e->dest->index); |
2895 fatal_insn ("wrong insn in the fallthru edge", insn); | 2928 fatal_insn ("wrong insn in the fallthru edge", insn); |
2896 err = 1; | 2929 err = 1; |
2908 static int | 2941 static int |
2909 rtl_verify_bb_layout (void) | 2942 rtl_verify_bb_layout (void) |
2910 { | 2943 { |
2911 basic_block bb; | 2944 basic_block bb; |
2912 int err = 0; | 2945 int err = 0; |
2913 rtx_insn *x; | 2946 rtx_insn *x, *y; |
2914 int num_bb_notes; | 2947 int num_bb_notes; |
2915 rtx_insn * const rtx_first = get_insns (); | 2948 rtx_insn * const rtx_first = get_insns (); |
2916 basic_block last_bb_seen = ENTRY_BLOCK_PTR_FOR_FN (cfun), curr_bb = NULL; | 2949 basic_block last_bb_seen = ENTRY_BLOCK_PTR_FOR_FN (cfun), curr_bb = NULL; |
2917 | 2950 |
2918 num_bb_notes = 0; | 2951 num_bb_notes = 0; |
2953 } | 2986 } |
2954 } | 2987 } |
2955 | 2988 |
2956 if (JUMP_P (x) | 2989 if (JUMP_P (x) |
2957 && returnjump_p (x) && ! condjump_p (x) | 2990 && returnjump_p (x) && ! condjump_p (x) |
2958 && ! (next_nonnote_insn (x) && BARRIER_P (next_nonnote_insn (x)))) | 2991 && ! ((y = next_nonnote_nondebug_insn (x)) |
2992 && BARRIER_P (y))) | |
2959 fatal_insn ("return not followed by barrier", x); | 2993 fatal_insn ("return not followed by barrier", x); |
2960 | 2994 |
2961 if (curr_bb && x == BB_END (curr_bb)) | 2995 if (curr_bb && x == BB_END (curr_bb)) |
2962 curr_bb = NULL; | 2996 curr_bb = NULL; |
2963 } | 2997 } |
3621 else if (forwarder_block_p (bb) | 3655 else if (forwarder_block_p (bb) |
3622 && !LABEL_P (BB_HEAD (bb))) | 3656 && !LABEL_P (BB_HEAD (bb))) |
3623 fprintf (dump_file, "compensation "); | 3657 fprintf (dump_file, "compensation "); |
3624 else | 3658 else |
3625 fprintf (dump_file, "bb %i ", bb->index); | 3659 fprintf (dump_file, "bb %i ", bb->index); |
3626 fprintf (dump_file, " [%i]\n", bb->frequency); | |
3627 } | 3660 } |
3628 } | 3661 } |
3629 | 3662 |
3630 /* Now reorder the blocks. */ | 3663 /* Now reorder the blocks. */ |
3631 prev_bb = ENTRY_BLOCK_PTR_FOR_FN (cfun); | 3664 prev_bb = ENTRY_BLOCK_PTR_FOR_FN (cfun); |
3885 | 3918 |
3886 if (e && !can_fallthru (e->src, e->dest)) | 3919 if (e && !can_fallthru (e->src, e->dest)) |
3887 force_nonfallthru (e); | 3920 force_nonfallthru (e); |
3888 } | 3921 } |
3889 | 3922 |
3890 /* Ensure goto_locus from edges has some instructions with that locus | 3923 /* Ensure goto_locus from edges has some instructions with that locus in RTL |
3891 in RTL. */ | 3924 when not optimizing. */ |
3892 if (!optimize) | 3925 if (!optimize && !DECL_IGNORED_P (current_function_decl)) |
3893 FOR_EACH_BB_FN (bb, cfun) | 3926 FOR_EACH_BB_FN (bb, cfun) |
3894 { | 3927 { |
3895 edge e; | 3928 edge e; |
3896 edge_iterator ei; | 3929 edge_iterator ei; |
3897 | 3930 |
4123 { | 4156 { |
4124 switch (GET_CODE (insn)) | 4157 switch (GET_CODE (insn)) |
4125 { | 4158 { |
4126 case DEBUG_INSN: | 4159 case DEBUG_INSN: |
4127 /* Don't duplicate label debug insns. */ | 4160 /* Don't duplicate label debug insns. */ |
4128 if (TREE_CODE (INSN_VAR_LOCATION_DECL (insn)) == LABEL_DECL) | 4161 if (DEBUG_BIND_INSN_P (insn) |
4162 && TREE_CODE (INSN_VAR_LOCATION_DECL (insn)) == LABEL_DECL) | |
4129 break; | 4163 break; |
4130 /* FALLTHRU */ | 4164 /* FALLTHRU */ |
4131 case INSN: | 4165 case INSN: |
4132 case CALL_INSN: | 4166 case CALL_INSN: |
4133 case JUMP_INSN: | 4167 case JUMP_INSN: |
4299 by aux pointers, enter compensation code, rebuild scope forest. */ | 4333 by aux pointers, enter compensation code, rebuild scope forest. */ |
4300 | 4334 |
4301 void | 4335 void |
4302 cfg_layout_finalize (void) | 4336 cfg_layout_finalize (void) |
4303 { | 4337 { |
4304 checking_verify_flow_info (); | |
4305 free_dominance_info (CDI_DOMINATORS); | 4338 free_dominance_info (CDI_DOMINATORS); |
4306 force_one_exit_fallthru (); | 4339 force_one_exit_fallthru (); |
4307 rtl_register_cfg_hooks (); | 4340 rtl_register_cfg_hooks (); |
4308 if (reload_completed && !targetm.have_epilogue ()) | 4341 if (reload_completed && !targetm.have_epilogue ()) |
4309 fixup_fallthru_exit_predecessor (); | 4342 fixup_fallthru_exit_predecessor (); |
4342 if (e->flags & (EDGE_ABNORMAL_CALL | EDGE_EH)) | 4375 if (e->flags & (EDGE_ABNORMAL_CALL | EDGE_EH)) |
4343 return NULL; | 4376 return NULL; |
4344 | 4377 |
4345 if (e->dest == dest) | 4378 if (e->dest == dest) |
4346 return e; | 4379 return e; |
4380 | |
4381 if (e->flags & EDGE_CROSSING | |
4382 && BB_PARTITION (e->src) == BB_PARTITION (dest) | |
4383 && simplejump_p (BB_END (src))) | |
4384 { | |
4385 if (dump_file) | |
4386 fprintf (dump_file, | |
4387 "Removing crossing jump while redirecting edge form %i to %i\n", | |
4388 e->src->index, dest->index); | |
4389 delete_insn (BB_END (src)); | |
4390 e->flags |= EDGE_FALLTHRU; | |
4391 } | |
4347 | 4392 |
4348 if (e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun) | 4393 if (e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun) |
4349 && (ret = try_redirect_by_replacing_jump (e, dest, true))) | 4394 && (ret = try_redirect_by_replacing_jump (e, dest, true))) |
4350 { | 4395 { |
4351 df_set_bb_dirty (src); | 4396 df_set_bb_dirty (src); |
4406 ret = redirect_edge_succ_nodup (e, dest); | 4451 ret = redirect_edge_succ_nodup (e, dest); |
4407 } | 4452 } |
4408 else | 4453 else |
4409 ret = redirect_branch_edge (e, dest); | 4454 ret = redirect_branch_edge (e, dest); |
4410 | 4455 |
4456 fixup_partition_crossing (ret); | |
4411 /* We don't want simplejumps in the insn stream during cfglayout. */ | 4457 /* We don't want simplejumps in the insn stream during cfglayout. */ |
4412 gcc_assert (!simplejump_p (BB_END (src))); | 4458 gcc_assert (!simplejump_p (BB_END (src)) || CROSSING_JUMP_P (BB_END (src))); |
4413 | 4459 |
4414 df_set_bb_dirty (src); | 4460 df_set_bb_dirty (src); |
4415 return ret; | 4461 return ret; |
4416 } | 4462 } |
4417 | 4463 |
4561 /* Merge block A and B. The blocks must be mergeable. */ | 4607 /* Merge block A and B. The blocks must be mergeable. */ |
4562 | 4608 |
4563 static void | 4609 static void |
4564 cfg_layout_merge_blocks (basic_block a, basic_block b) | 4610 cfg_layout_merge_blocks (basic_block a, basic_block b) |
4565 { | 4611 { |
4566 bool forwarder_p = (b->flags & BB_FORWARDER_BLOCK) != 0; | 4612 /* If B is a forwarder block whose outgoing edge has no location, we'll |
4613 propagate the locus of the edge between A and B onto it. */ | |
4614 const bool forward_edge_locus | |
4615 = (b->flags & BB_FORWARDER_BLOCK) != 0 | |
4616 && LOCATION_LOCUS (EDGE_SUCC (b, 0)->goto_locus) == UNKNOWN_LOCATION; | |
4567 rtx_insn *insn; | 4617 rtx_insn *insn; |
4568 | 4618 |
4569 gcc_checking_assert (cfg_layout_can_merge_blocks_p (a, b)); | 4619 gcc_checking_assert (cfg_layout_can_merge_blocks_p (a, b)); |
4570 | 4620 |
4571 if (dump_file) | 4621 if (dump_file) |
4582 it cleaned up. */ | 4632 it cleaned up. */ |
4583 if (JUMP_P (BB_END (a))) | 4633 if (JUMP_P (BB_END (a))) |
4584 try_redirect_by_replacing_jump (EDGE_SUCC (a, 0), b, true); | 4634 try_redirect_by_replacing_jump (EDGE_SUCC (a, 0), b, true); |
4585 gcc_assert (!JUMP_P (BB_END (a))); | 4635 gcc_assert (!JUMP_P (BB_END (a))); |
4586 | 4636 |
4587 /* When not optimizing and the edge is the only place in RTL which holds | 4637 /* If not optimizing, preserve the locus of the single edge between |
4588 some unique locus, emit a nop with that locus in between. */ | 4638 blocks A and B if necessary by emitting a nop. */ |
4589 if (!optimize) | 4639 if (!optimize |
4640 && !forward_edge_locus | |
4641 && !DECL_IGNORED_P (current_function_decl)) | |
4590 emit_nop_for_unique_locus_between (a, b); | 4642 emit_nop_for_unique_locus_between (a, b); |
4591 | 4643 |
4592 /* Move things from b->footer after a->footer. */ | 4644 /* Move things from b->footer after a->footer. */ |
4593 if (BB_FOOTER (b)) | 4645 if (BB_FOOTER (b)) |
4594 { | 4646 { |
4651 BB_HEAD (b) = BB_END (b) = NULL; | 4703 BB_HEAD (b) = BB_END (b) = NULL; |
4652 delete_insn (insn); | 4704 delete_insn (insn); |
4653 | 4705 |
4654 df_bb_delete (b->index); | 4706 df_bb_delete (b->index); |
4655 | 4707 |
4656 /* If B was a forwarder block, propagate the locus on the edge. */ | 4708 if (forward_edge_locus) |
4657 if (forwarder_p | |
4658 && LOCATION_LOCUS (EDGE_SUCC (b, 0)->goto_locus) == UNKNOWN_LOCATION) | |
4659 EDGE_SUCC (b, 0)->goto_locus = EDGE_SUCC (a, 0)->goto_locus; | 4709 EDGE_SUCC (b, 0)->goto_locus = EDGE_SUCC (a, 0)->goto_locus; |
4660 | 4710 |
4661 if (dump_file) | 4711 if (dump_file) |
4662 fprintf (dump_file, "Merged blocks %d and %d.\n", a->index, b->index); | 4712 fprintf (dump_file, "Merged blocks %d and %d.\n", a->index, b->index); |
4663 } | 4713 } |
5032 if (bb->count.initialized_p ()) | 5082 if (bb->count.initialized_p ()) |
5033 record->time[after_pass] | 5083 record->time[after_pass] |
5034 += insn_cost (insn, true) * bb->count.to_gcov_type (); | 5084 += insn_cost (insn, true) * bb->count.to_gcov_type (); |
5035 else if (profile_status_for_fn (cfun) == PROFILE_GUESSED) | 5085 else if (profile_status_for_fn (cfun) == PROFILE_GUESSED) |
5036 record->time[after_pass] | 5086 record->time[after_pass] |
5037 += insn_cost (insn, true) * bb->frequency; | 5087 += insn_cost (insn, true) * bb->count.to_frequency (cfun); |
5038 } | 5088 } |
5039 } | 5089 } |
5040 | 5090 |
5041 /* Implementation of CFG manipulation for linearized RTL. */ | 5091 /* Implementation of CFG manipulation for linearized RTL. */ |
5042 struct cfg_hooks rtl_cfg_hooks = { | 5092 struct cfg_hooks rtl_cfg_hooks = { |