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 = &REG_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 = {