Mercurial > hg > CbC > CbC_gcc
comparison gcc/cfgrtl.c @ 55:77e2b8dfacca gcc-4.4.5
update it from 4.4.3 to 4.5.0
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:39:51 +0900 |
parents | 58ad6c70ea60 |
children | b7f97abdc517 |
comparison
equal
deleted
inserted
replaced
52:c156f1bd5cd9 | 55:77e2b8dfacca |
---|---|
1 /* Control flow graph manipulation code for GNU compiler. | 1 /* Control flow graph manipulation code for GNU compiler. |
2 Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, | 2 Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, |
3 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 | 3 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 |
4 Free Software Foundation, Inc. | 4 Free Software Foundation, Inc. |
5 | 5 |
6 This file is part of GCC. | 6 This file is part of GCC. |
7 | 7 |
8 GCC is free software; you can redistribute it and/or modify it under | 8 GCC is free software; you can redistribute it and/or modify it under |
63 #include "tree-pass.h" | 63 #include "tree-pass.h" |
64 #include "df.h" | 64 #include "df.h" |
65 | 65 |
66 static int can_delete_note_p (const_rtx); | 66 static int can_delete_note_p (const_rtx); |
67 static int can_delete_label_p (const_rtx); | 67 static int can_delete_label_p (const_rtx); |
68 static void commit_one_edge_insertion (edge); | |
69 static basic_block rtl_split_edge (edge); | 68 static basic_block rtl_split_edge (edge); |
70 static bool rtl_move_block_after (basic_block, basic_block); | 69 static bool rtl_move_block_after (basic_block, basic_block); |
71 static int rtl_verify_flow_info (void); | 70 static int rtl_verify_flow_info (void); |
72 static basic_block cfg_layout_split_block (basic_block, void *); | 71 static basic_block cfg_layout_split_block (basic_block, void *); |
73 static edge cfg_layout_redirect_edge_and_branch (edge, basic_block); | 72 static edge cfg_layout_redirect_edge_and_branch (edge, basic_block); |
85 so that we may simply delete it. */ | 84 so that we may simply delete it. */ |
86 | 85 |
87 static int | 86 static int |
88 can_delete_note_p (const_rtx note) | 87 can_delete_note_p (const_rtx note) |
89 { | 88 { |
90 return (NOTE_KIND (note) == NOTE_INSN_DELETED | 89 switch (NOTE_KIND (note)) |
91 || NOTE_KIND (note) == NOTE_INSN_BASIC_BLOCK); | 90 { |
91 case NOTE_INSN_DELETED: | |
92 case NOTE_INSN_BASIC_BLOCK: | |
93 case NOTE_INSN_EPILOGUE_BEG: | |
94 return true; | |
95 | |
96 default: | |
97 return false; | |
98 } | |
92 } | 99 } |
93 | 100 |
94 /* True if a given label can be deleted. */ | 101 /* True if a given label can be deleted. */ |
95 | 102 |
96 static int | 103 static int |
161 { | 168 { |
162 LABEL_NUSES (XEXP (note, 0))--; | 169 LABEL_NUSES (XEXP (note, 0))--; |
163 remove_note (insn, note); | 170 remove_note (insn, note); |
164 } | 171 } |
165 | 172 |
166 if (JUMP_P (insn) | 173 if (JUMP_TABLE_DATA_P (insn)) |
167 && (GET_CODE (PATTERN (insn)) == ADDR_VEC | |
168 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)) | |
169 { | 174 { |
170 rtx pat = PATTERN (insn); | 175 rtx pat = PATTERN (insn); |
171 int diff_vec_p = GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC; | 176 int diff_vec_p = GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC; |
172 int len = XVECLEN (pat, diff_vec_p); | 177 int len = XVECLEN (pat, diff_vec_p); |
173 int i; | 178 int i; |
230 | 235 |
231 if (start == finish) | 236 if (start == finish) |
232 break; | 237 break; |
233 start = next; | 238 start = next; |
234 } | 239 } |
235 } | |
236 | |
237 /* Like delete_insn_chain but also purge dead edges from BB. */ | |
238 | |
239 void | |
240 delete_insn_chain_and_edges (rtx first, rtx last) | |
241 { | |
242 bool purge = false; | |
243 | |
244 if (INSN_P (last) | |
245 && BLOCK_FOR_INSN (last) | |
246 && BB_END (BLOCK_FOR_INSN (last)) == last) | |
247 purge = true; | |
248 delete_insn_chain (first, last, false); | |
249 if (purge) | |
250 purge_dead_edges (BLOCK_FOR_INSN (last)); | |
251 } | 240 } |
252 | 241 |
253 /* Create a new basic block consisting of the instructions between HEAD and END | 242 /* Create a new basic block consisting of the instructions between HEAD and END |
254 inclusive. This function is designed to allow fast BB construction - reuses | 243 inclusive. This function is designed to allow fast BB construction - reuses |
255 the note and basic block struct in BB_NOTE, if any and do not grow | 244 the note and basic block struct in BB_NOTE, if any and do not grow |
378 | 367 |
379 /* If the head of this block is a CODE_LABEL, then it might be the | 368 /* If the head of this block is a CODE_LABEL, then it might be the |
380 label for an exception handler which can't be reached. We need | 369 label for an exception handler which can't be reached. We need |
381 to remove the label from the exception_handler_label list. */ | 370 to remove the label from the exception_handler_label list. */ |
382 insn = BB_HEAD (b); | 371 insn = BB_HEAD (b); |
383 if (LABEL_P (insn)) | |
384 maybe_remove_eh_handler (insn); | |
385 | 372 |
386 end = get_last_bb_insn (b); | 373 end = get_last_bb_insn (b); |
387 | 374 |
388 /* Selectively delete the entire chain. */ | 375 /* Selectively delete the entire chain. */ |
389 BB_HEAD (b) = NULL; | 376 BB_HEAD (b) = NULL; |
444 | 431 |
445 struct rtl_opt_pass pass_free_cfg = | 432 struct rtl_opt_pass pass_free_cfg = |
446 { | 433 { |
447 { | 434 { |
448 RTL_PASS, | 435 RTL_PASS, |
449 NULL, /* name */ | 436 "*free_cfg", /* name */ |
450 NULL, /* gate */ | 437 NULL, /* gate */ |
451 rest_of_pass_free_cfg, /* execute */ | 438 rest_of_pass_free_cfg, /* execute */ |
452 NULL, /* sub */ | 439 NULL, /* sub */ |
453 NULL, /* next */ | 440 NULL, /* next */ |
454 0, /* static_pass_number */ | 441 0, /* static_pass_number */ |
455 0, /* tv_id */ | 442 TV_NONE, /* tv_id */ |
456 0, /* properties_required */ | 443 0, /* properties_required */ |
457 0, /* properties_provided */ | 444 0, /* properties_provided */ |
458 PROP_cfg, /* properties_destroyed */ | 445 PROP_cfg, /* properties_destroyed */ |
459 0, /* todo_flags_start */ | 446 0, /* todo_flags_start */ |
460 0, /* todo_flags_finish */ | 447 0, /* todo_flags_finish */ |
481 insert_insn_on_edge (insn, e); | 468 insert_insn_on_edge (insn, e); |
482 commit_edge_insertions (); | 469 commit_edge_insertions (); |
483 } | 470 } |
484 | 471 |
485 /* Update BLOCK_FOR_INSN of insns between BEGIN and END | 472 /* Update BLOCK_FOR_INSN of insns between BEGIN and END |
486 (or BARRIER if found) and notify df of the bb change. | 473 (or BARRIER if found) and notify df of the bb change. |
487 The insn chain range is inclusive | 474 The insn chain range is inclusive |
488 (i.e. both BEGIN and END will be updated. */ | 475 (i.e. both BEGIN and END will be updated. */ |
489 | 476 |
490 static void | 477 static void |
491 update_bb_for_insn_chain (rtx begin, rtx end, basic_block bb) | 478 update_bb_for_insn_chain (rtx begin, rtx end, basic_block bb) |
542 if (!insn) | 529 if (!insn) |
543 { | 530 { |
544 insn = first_insn_after_basic_block_note (bb); | 531 insn = first_insn_after_basic_block_note (bb); |
545 | 532 |
546 if (insn) | 533 if (insn) |
547 insn = PREV_INSN (insn); | 534 { |
535 rtx next = insn; | |
536 | |
537 insn = PREV_INSN (insn); | |
538 | |
539 /* If the block contains only debug insns, insn would have | |
540 been NULL in a non-debug compilation, and then we'd end | |
541 up emitting a DELETED note. For -fcompare-debug | |
542 stability, emit the note too. */ | |
543 if (insn != BB_END (bb) | |
544 && DEBUG_INSN_P (next) | |
545 && DEBUG_INSN_P (BB_END (bb))) | |
546 { | |
547 while (next != BB_END (bb) && DEBUG_INSN_P (next)) | |
548 next = NEXT_INSN (next); | |
549 | |
550 if (next == BB_END (bb)) | |
551 emit_note_after (NOTE_INSN_DELETED, next); | |
552 } | |
553 } | |
548 else | 554 else |
549 insn = get_last_insn (); | 555 insn = get_last_insn (); |
550 } | 556 } |
551 | 557 |
552 /* We probably should check type of the insn so that we do not create | 558 /* We probably should check type of the insn so that we do not create |
577 static void | 583 static void |
578 rtl_merge_blocks (basic_block a, basic_block b) | 584 rtl_merge_blocks (basic_block a, basic_block b) |
579 { | 585 { |
580 rtx b_head = BB_HEAD (b), b_end = BB_END (b), a_end = BB_END (a); | 586 rtx b_head = BB_HEAD (b), b_end = BB_END (b), a_end = BB_END (a); |
581 rtx del_first = NULL_RTX, del_last = NULL_RTX; | 587 rtx del_first = NULL_RTX, del_last = NULL_RTX; |
588 rtx b_debug_start = b_end, b_debug_end = b_end; | |
582 int b_empty = 0; | 589 int b_empty = 0; |
583 | 590 |
584 if (dump_file) | 591 if (dump_file) |
585 fprintf (dump_file, "merging block %d into block %d\n", b->index, a->index); | 592 fprintf (dump_file, "merging block %d into block %d\n", b->index, a->index); |
586 | 593 |
594 while (DEBUG_INSN_P (b_end)) | |
595 b_end = PREV_INSN (b_debug_start = b_end); | |
596 | |
587 /* If there was a CODE_LABEL beginning B, delete it. */ | 597 /* If there was a CODE_LABEL beginning B, delete it. */ |
588 if (LABEL_P (b_head)) | 598 if (LABEL_P (b_head)) |
589 { | 599 { |
590 /* This might have been an EH label that no longer has incoming | |
591 EH edges. Update data structures to match. */ | |
592 maybe_remove_eh_handler (b_head); | |
593 | |
594 /* Detect basic blocks with nothing but a label. This can happen | 600 /* Detect basic blocks with nothing but a label. This can happen |
595 in particular at the end of a function. */ | 601 in particular at the end of a function. */ |
596 if (b_head == b_end) | 602 if (b_head == b_end) |
597 b_empty = 1; | 603 b_empty = 1; |
598 | 604 |
651 delete_insn_chain (del_first, del_last, true); | 657 delete_insn_chain (del_first, del_last, true); |
652 | 658 |
653 /* Reassociate the insns of B with A. */ | 659 /* Reassociate the insns of B with A. */ |
654 if (!b_empty) | 660 if (!b_empty) |
655 { | 661 { |
656 update_bb_for_insn_chain (a_end, b_end, a); | 662 update_bb_for_insn_chain (a_end, b_debug_end, a); |
657 | 663 |
658 a_end = b_end; | 664 a_end = b_debug_end; |
665 } | |
666 else if (b_end != b_debug_end) | |
667 { | |
668 /* Move any deleted labels and other notes between the end of A | |
669 and the debug insns that make up B after the debug insns, | |
670 bringing the debug insns into A while keeping the notes after | |
671 the end of A. */ | |
672 if (NEXT_INSN (a_end) != b_debug_start) | |
673 reorder_insns_nobb (NEXT_INSN (a_end), PREV_INSN (b_debug_start), | |
674 b_debug_end); | |
675 update_bb_for_insn_chain (b_debug_start, b_debug_end, a); | |
676 a_end = b_debug_end; | |
659 } | 677 } |
660 | 678 |
661 df_bb_delete (b->index); | 679 df_bb_delete (b->index); |
662 BB_END (a) = a_end; | 680 BB_END (a) = a_end; |
663 } | 681 } |
891 if (e->dest != target) | 909 if (e->dest != target) |
892 redirect_edge_succ (e, target); | 910 redirect_edge_succ (e, target); |
893 return e; | 911 return e; |
894 } | 912 } |
895 | 913 |
896 /* Redirect edge representing branch of (un)conditional jump or tablejump, | 914 /* Subroutine of redirect_branch_edge that tries to patch the jump |
897 NULL on failure */ | 915 instruction INSN so that it reaches block NEW. Do this |
898 static edge | 916 only when it originally reached block OLD. Return true if this |
899 redirect_branch_edge (edge e, basic_block target) | 917 worked or the original target wasn't OLD, return false if redirection |
918 doesn't work. */ | |
919 | |
920 static bool | |
921 patch_jump_insn (rtx insn, rtx old_label, basic_block new_bb) | |
900 { | 922 { |
901 rtx tmp; | 923 rtx tmp; |
902 rtx old_label = BB_HEAD (e->dest); | |
903 basic_block src = e->src; | |
904 rtx insn = BB_END (src); | |
905 | |
906 /* We can only redirect non-fallthru edges of jump insn. */ | |
907 if (e->flags & EDGE_FALLTHRU) | |
908 return NULL; | |
909 else if (!JUMP_P (insn)) | |
910 return NULL; | |
911 | |
912 /* Recognize a tablejump and adjust all matching cases. */ | 924 /* Recognize a tablejump and adjust all matching cases. */ |
913 if (tablejump_p (insn, NULL, &tmp)) | 925 if (tablejump_p (insn, NULL, &tmp)) |
914 { | 926 { |
915 rtvec vec; | 927 rtvec vec; |
916 int j; | 928 int j; |
917 rtx new_label = block_label (target); | 929 rtx new_label = block_label (new_bb); |
918 | 930 |
919 if (target == EXIT_BLOCK_PTR) | 931 if (new_bb == EXIT_BLOCK_PTR) |
920 return NULL; | 932 return false; |
921 if (GET_CODE (PATTERN (tmp)) == ADDR_VEC) | 933 if (GET_CODE (PATTERN (tmp)) == ADDR_VEC) |
922 vec = XVEC (PATTERN (tmp), 0); | 934 vec = XVEC (PATTERN (tmp), 0); |
923 else | 935 else |
924 vec = XVEC (PATTERN (tmp), 1); | 936 vec = XVEC (PATTERN (tmp), 1); |
925 | 937 |
942 new_label); | 954 new_label); |
943 --LABEL_NUSES (old_label); | 955 --LABEL_NUSES (old_label); |
944 ++LABEL_NUSES (new_label); | 956 ++LABEL_NUSES (new_label); |
945 } | 957 } |
946 } | 958 } |
959 else if ((tmp = extract_asm_operands (PATTERN (insn))) != NULL) | |
960 { | |
961 int i, n = ASM_OPERANDS_LABEL_LENGTH (tmp); | |
962 rtx new_label, note; | |
963 | |
964 if (new_bb == EXIT_BLOCK_PTR) | |
965 return false; | |
966 new_label = block_label (new_bb); | |
967 | |
968 for (i = 0; i < n; ++i) | |
969 { | |
970 rtx old_ref = ASM_OPERANDS_LABEL (tmp, i); | |
971 gcc_assert (GET_CODE (old_ref) == LABEL_REF); | |
972 if (XEXP (old_ref, 0) == old_label) | |
973 { | |
974 ASM_OPERANDS_LABEL (tmp, i) | |
975 = gen_rtx_LABEL_REF (Pmode, new_label); | |
976 --LABEL_NUSES (old_label); | |
977 ++LABEL_NUSES (new_label); | |
978 } | |
979 } | |
980 | |
981 if (JUMP_LABEL (insn) == old_label) | |
982 { | |
983 JUMP_LABEL (insn) = new_label; | |
984 note = find_reg_note (insn, REG_LABEL_TARGET, new_label); | |
985 if (note) | |
986 remove_note (insn, note); | |
987 } | |
988 else | |
989 { | |
990 note = find_reg_note (insn, REG_LABEL_TARGET, old_label); | |
991 if (note) | |
992 remove_note (insn, note); | |
993 if (JUMP_LABEL (insn) != new_label | |
994 && !find_reg_note (insn, REG_LABEL_TARGET, new_label)) | |
995 add_reg_note (insn, REG_LABEL_TARGET, new_label); | |
996 } | |
997 } | |
947 else | 998 else |
948 { | 999 { |
949 /* ?? We may play the games with moving the named labels from | 1000 /* ?? We may play the games with moving the named labels from |
950 one basic block to the other in case only one computed_jump is | 1001 one basic block to the other in case only one computed_jump is |
951 available. */ | 1002 available. */ |
952 if (computed_jump_p (insn) | 1003 if (computed_jump_p (insn) |
953 /* A return instruction can't be redirected. */ | 1004 /* A return instruction can't be redirected. */ |
954 || returnjump_p (insn)) | 1005 || returnjump_p (insn)) |
1006 return false; | |
1007 | |
1008 if (!currently_expanding_to_rtl || JUMP_LABEL (insn) == old_label) | |
1009 { | |
1010 /* If the insn doesn't go where we think, we're confused. */ | |
1011 gcc_assert (JUMP_LABEL (insn) == old_label); | |
1012 | |
1013 /* If the substitution doesn't succeed, die. This can happen | |
1014 if the back end emitted unrecognizable instructions or if | |
1015 target is exit block on some arches. */ | |
1016 if (!redirect_jump (insn, block_label (new_bb), 0)) | |
1017 { | |
1018 gcc_assert (new_bb == EXIT_BLOCK_PTR); | |
1019 return false; | |
1020 } | |
1021 } | |
1022 } | |
1023 return true; | |
1024 } | |
1025 | |
1026 | |
1027 /* Redirect edge representing branch of (un)conditional jump or tablejump, | |
1028 NULL on failure */ | |
1029 static edge | |
1030 redirect_branch_edge (edge e, basic_block target) | |
1031 { | |
1032 rtx old_label = BB_HEAD (e->dest); | |
1033 basic_block src = e->src; | |
1034 rtx insn = BB_END (src); | |
1035 | |
1036 /* We can only redirect non-fallthru edges of jump insn. */ | |
1037 if (e->flags & EDGE_FALLTHRU) | |
1038 return NULL; | |
1039 else if (!JUMP_P (insn) && !currently_expanding_to_rtl) | |
1040 return NULL; | |
1041 | |
1042 if (!currently_expanding_to_rtl) | |
1043 { | |
1044 if (!patch_jump_insn (insn, old_label, target)) | |
955 return NULL; | 1045 return NULL; |
956 | 1046 } |
957 /* If the insn doesn't go where we think, we're confused. */ | 1047 else |
958 gcc_assert (JUMP_LABEL (insn) == old_label); | 1048 /* When expanding this BB might actually contain multiple |
959 | 1049 jumps (i.e. not yet split by find_many_sub_basic_blocks). |
960 /* If the substitution doesn't succeed, die. This can happen | 1050 Redirect all of those that match our label. */ |
961 if the back end emitted unrecognizable instructions or if | 1051 for (insn = BB_HEAD (src); insn != NEXT_INSN (BB_END (src)); |
962 target is exit block on some arches. */ | 1052 insn = NEXT_INSN (insn)) |
963 if (!redirect_jump (insn, block_label (target), 0)) | 1053 if (JUMP_P (insn) && !patch_jump_insn (insn, old_label, target)) |
964 { | 1054 return NULL; |
965 gcc_assert (target == EXIT_BLOCK_PTR); | |
966 return NULL; | |
967 } | |
968 } | |
969 | 1055 |
970 if (dump_file) | 1056 if (dump_file) |
971 fprintf (dump_file, "Edge %i->%i redirected to %i\n", | 1057 fprintf (dump_file, "Edge %i->%i redirected to %i\n", |
972 e->src->index, e->dest->index, target->index); | 1058 e->src->index, e->dest->index, target->index); |
973 | 1059 |
1168 redirect_edge_succ_nodup (e, target); | 1254 redirect_edge_succ_nodup (e, target); |
1169 | 1255 |
1170 if (abnormal_edge_flags) | 1256 if (abnormal_edge_flags) |
1171 make_edge (src, target, abnormal_edge_flags); | 1257 make_edge (src, target, abnormal_edge_flags); |
1172 | 1258 |
1173 df_mark_solutions_dirty (); | 1259 df_mark_solutions_dirty (); |
1174 return new_bb; | 1260 return new_bb; |
1175 } | 1261 } |
1176 | 1262 |
1177 /* Edge E is assumed to be fallthru edge. Emit needed jump instruction | 1263 /* Edge E is assumed to be fallthru edge. Emit needed jump instruction |
1178 (and possibly create new basic block) to make edge non-fallthru. | 1264 (and possibly create new basic block) to make edge non-fallthru. |
1348 end_sequence (); | 1434 end_sequence (); |
1349 } | 1435 } |
1350 | 1436 |
1351 /* Update the CFG for the instructions queued on edge E. */ | 1437 /* Update the CFG for the instructions queued on edge E. */ |
1352 | 1438 |
1353 static void | 1439 void |
1354 commit_one_edge_insertion (edge e) | 1440 commit_one_edge_insertion (edge e) |
1355 { | 1441 { |
1356 rtx before = NULL_RTX, after = NULL_RTX, insns, tmp, last; | 1442 rtx before = NULL_RTX, after = NULL_RTX, insns, tmp, last; |
1357 basic_block bb = NULL; | 1443 basic_block bb = NULL; |
1358 | 1444 |
1416 | 1502 |
1417 if (flag_reorder_blocks_and_partition | 1503 if (flag_reorder_blocks_and_partition |
1418 && targetm.have_named_sections | 1504 && targetm.have_named_sections |
1419 && e->src != ENTRY_BLOCK_PTR | 1505 && e->src != ENTRY_BLOCK_PTR |
1420 && BB_PARTITION (e->src) == BB_COLD_PARTITION | 1506 && BB_PARTITION (e->src) == BB_COLD_PARTITION |
1421 && !(e->flags & EDGE_CROSSING)) | 1507 && !(e->flags & EDGE_CROSSING) |
1422 { | 1508 && JUMP_P (after) |
1423 rtx bb_note, cur_insn; | 1509 && !any_condjump_p (after) |
1424 | 1510 && (single_succ_edge (bb)->flags & EDGE_CROSSING)) |
1425 bb_note = NULL_RTX; | 1511 add_reg_note (after, REG_CROSSING_JUMP, NULL_RTX); |
1426 for (cur_insn = BB_HEAD (bb); cur_insn != NEXT_INSN (BB_END (bb)); | |
1427 cur_insn = NEXT_INSN (cur_insn)) | |
1428 if (NOTE_INSN_BASIC_BLOCK_P (cur_insn)) | |
1429 { | |
1430 bb_note = cur_insn; | |
1431 break; | |
1432 } | |
1433 | |
1434 if (JUMP_P (BB_END (bb)) | |
1435 && !any_condjump_p (BB_END (bb)) | |
1436 && (single_succ_edge (bb)->flags & EDGE_CROSSING)) | |
1437 add_reg_note (BB_END (bb), REG_CROSSING_JUMP, NULL_RTX); | |
1438 } | |
1439 } | 1512 } |
1440 } | 1513 } |
1441 | 1514 |
1442 /* Now that we've found the spot, do the insertion. */ | 1515 /* Now that we've found the spot, do the insertion. */ |
1443 | 1516 |
1537 char *s_indent; | 1610 char *s_indent; |
1538 | 1611 |
1539 s_indent = (char *) alloca ((size_t) indent + 1); | 1612 s_indent = (char *) alloca ((size_t) indent + 1); |
1540 memset (s_indent, ' ', (size_t) indent); | 1613 memset (s_indent, ' ', (size_t) indent); |
1541 s_indent[indent] = '\0'; | 1614 s_indent[indent] = '\0'; |
1542 | 1615 |
1543 if (df) | 1616 if (df) |
1544 { | 1617 { |
1545 df_dump_top (bb, outf); | 1618 df_dump_top (bb, outf); |
1546 putc ('\n', outf); | 1619 putc ('\n', outf); |
1547 } | 1620 } |
1604 int did_output; | 1677 int did_output; |
1605 if ((bb = start[INSN_UID (tmp_rtx)]) != NULL) | 1678 if ((bb = start[INSN_UID (tmp_rtx)]) != NULL) |
1606 { | 1679 { |
1607 edge e; | 1680 edge e; |
1608 edge_iterator ei; | 1681 edge_iterator ei; |
1609 | 1682 |
1610 fprintf (outf, ";; Start of basic block ("); | 1683 fprintf (outf, ";; Start of basic block ("); |
1611 FOR_EACH_EDGE (e, ei, bb->preds) | 1684 FOR_EACH_EDGE (e, ei, bb->preds) |
1612 fprintf (outf, " %d", e->src->index); | 1685 fprintf (outf, " %d", e->src->index); |
1613 fprintf (outf, ") -> %d\n", bb->index); | 1686 fprintf (outf, ") -> %d\n", bb->index); |
1614 | 1687 |
1698 /* Include any jump table following the basic block. */ | 1771 /* Include any jump table following the basic block. */ |
1699 if (tablejump_p (end, NULL, &tmp)) | 1772 if (tablejump_p (end, NULL, &tmp)) |
1700 end = tmp; | 1773 end = tmp; |
1701 | 1774 |
1702 /* Include any barriers that may follow the basic block. */ | 1775 /* Include any barriers that may follow the basic block. */ |
1703 tmp = next_nonnote_insn (end); | 1776 tmp = next_nonnote_insn_bb (end); |
1704 while (tmp && BARRIER_P (tmp)) | 1777 while (tmp && BARRIER_P (tmp)) |
1705 { | 1778 { |
1706 end = tmp; | 1779 end = tmp; |
1707 tmp = next_nonnote_insn (end); | 1780 tmp = next_nonnote_insn_bb (end); |
1708 } | 1781 } |
1709 | 1782 |
1710 return end; | 1783 return end; |
1711 } | 1784 } |
1712 | 1785 |
1824 n_eh++; | 1897 n_eh++; |
1825 else if (e->flags & EDGE_ABNORMAL) | 1898 else if (e->flags & EDGE_ABNORMAL) |
1826 n_abnormal++; | 1899 n_abnormal++; |
1827 } | 1900 } |
1828 | 1901 |
1829 if (n_eh && GET_CODE (PATTERN (BB_END (bb))) != RESX | 1902 if (n_eh && !find_reg_note (BB_END (bb), REG_EH_REGION, NULL_RTX)) |
1830 && !find_reg_note (BB_END (bb), REG_EH_REGION, NULL_RTX)) | |
1831 { | 1903 { |
1832 error ("missing REG_EH_REGION note in the end of bb %i", bb->index); | 1904 error ("missing REG_EH_REGION note in the end of bb %i", bb->index); |
1905 err = 1; | |
1906 } | |
1907 if (n_eh > 1) | |
1908 { | |
1909 error ("too many eh edges %i", bb->index); | |
1833 err = 1; | 1910 err = 1; |
1834 } | 1911 } |
1835 if (n_branch | 1912 if (n_branch |
1836 && (!JUMP_P (BB_END (bb)) | 1913 && (!JUMP_P (BB_END (bb)) |
1837 || (n_branch > 1 && (any_uncondjump_p (BB_END (bb)) | 1914 || (n_branch > 1 && (any_uncondjump_p (BB_END (bb)) |
1845 error ("fallthru edge after unconditional jump %i", bb->index); | 1922 error ("fallthru edge after unconditional jump %i", bb->index); |
1846 err = 1; | 1923 err = 1; |
1847 } | 1924 } |
1848 if (n_branch != 1 && any_uncondjump_p (BB_END (bb))) | 1925 if (n_branch != 1 && any_uncondjump_p (BB_END (bb))) |
1849 { | 1926 { |
1850 error ("wrong amount of branch edges after unconditional jump %i", bb->index); | 1927 error ("wrong number of branch edges after unconditional jump %i", |
1928 bb->index); | |
1851 err = 1; | 1929 err = 1; |
1852 } | 1930 } |
1853 if (n_branch != 1 && any_condjump_p (BB_END (bb)) | 1931 if (n_branch != 1 && any_condjump_p (BB_END (bb)) |
1854 && JUMP_LABEL (BB_END (bb)) != BB_HEAD (fallthru->dest)) | 1932 && JUMP_LABEL (BB_END (bb)) != BB_HEAD (fallthru->dest)) |
1855 { | 1933 { |
2030 if (!e) | 2108 if (!e) |
2031 { | 2109 { |
2032 rtx insn; | 2110 rtx insn; |
2033 | 2111 |
2034 /* Ensure existence of barrier in BB with no fallthru edges. */ | 2112 /* Ensure existence of barrier in BB with no fallthru edges. */ |
2035 for (insn = BB_END (bb); !insn || !BARRIER_P (insn); | 2113 for (insn = NEXT_INSN (BB_END (bb)); ; insn = NEXT_INSN (insn)) |
2036 insn = NEXT_INSN (insn)) | 2114 { |
2037 if (!insn | 2115 if (!insn || NOTE_INSN_BASIC_BLOCK_P (insn)) |
2038 || NOTE_INSN_BASIC_BLOCK_P (insn)) | |
2039 { | 2116 { |
2040 error ("missing barrier after block %i", bb->index); | 2117 error ("missing barrier after block %i", bb->index); |
2041 err = 1; | 2118 err = 1; |
2042 break; | 2119 break; |
2043 } | 2120 } |
2121 if (BARRIER_P (insn)) | |
2122 break; | |
2123 } | |
2044 } | 2124 } |
2045 else if (e->src != ENTRY_BLOCK_PTR | 2125 else if (e->src != ENTRY_BLOCK_PTR |
2046 && e->dest != EXIT_BLOCK_PTR) | 2126 && e->dest != EXIT_BLOCK_PTR) |
2047 { | 2127 { |
2048 rtx insn; | 2128 rtx insn; |
2106 break; | 2186 break; |
2107 | 2187 |
2108 case CODE_LABEL: | 2188 case CODE_LABEL: |
2109 /* An addr_vec is placed outside any basic block. */ | 2189 /* An addr_vec is placed outside any basic block. */ |
2110 if (NEXT_INSN (x) | 2190 if (NEXT_INSN (x) |
2111 && JUMP_P (NEXT_INSN (x)) | 2191 && JUMP_TABLE_DATA_P (NEXT_INSN (x))) |
2112 && (GET_CODE (PATTERN (NEXT_INSN (x))) == ADDR_DIFF_VEC | |
2113 || GET_CODE (PATTERN (NEXT_INSN (x))) == ADDR_VEC)) | |
2114 x = NEXT_INSN (x); | 2192 x = NEXT_INSN (x); |
2115 | 2193 |
2116 /* But in any case, non-deletable labels can appear anywhere. */ | 2194 /* But in any case, non-deletable labels can appear anywhere. */ |
2117 break; | 2195 break; |
2118 | 2196 |
2148 rtx insn = BB_END (bb), note; | 2226 rtx insn = BB_END (bb), note; |
2149 bool purged = false; | 2227 bool purged = false; |
2150 bool found; | 2228 bool found; |
2151 edge_iterator ei; | 2229 edge_iterator ei; |
2152 | 2230 |
2231 if (DEBUG_INSN_P (insn) && insn != BB_HEAD (bb)) | |
2232 do | |
2233 insn = PREV_INSN (insn); | |
2234 while ((DEBUG_INSN_P (insn) || NOTE_P (insn)) && insn != BB_HEAD (bb)); | |
2235 | |
2153 /* If this instruction cannot trap, remove REG_EH_REGION notes. */ | 2236 /* If this instruction cannot trap, remove REG_EH_REGION notes. */ |
2154 if (NONJUMP_INSN_P (insn) | 2237 if (NONJUMP_INSN_P (insn) |
2155 && (note = find_reg_note (insn, REG_EH_REGION, NULL))) | 2238 && (note = find_reg_note (insn, REG_EH_REGION, NULL))) |
2156 { | 2239 { |
2157 rtx eqnote; | 2240 rtx eqnote; |
2163 } | 2246 } |
2164 | 2247 |
2165 /* Cleanup abnormal edges caused by exceptions or non-local gotos. */ | 2248 /* Cleanup abnormal edges caused by exceptions or non-local gotos. */ |
2166 for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); ) | 2249 for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); ) |
2167 { | 2250 { |
2251 bool remove = false; | |
2252 | |
2168 /* There are three types of edges we need to handle correctly here: EH | 2253 /* There are three types of edges we need to handle correctly here: EH |
2169 edges, abnormal call EH edges, and abnormal call non-EH edges. The | 2254 edges, abnormal call EH edges, and abnormal call non-EH edges. The |
2170 latter can appear when nonlocal gotos are used. */ | 2255 latter can appear when nonlocal gotos are used. */ |
2171 if (e->flags & EDGE_EH) | 2256 if (e->flags & EDGE_ABNORMAL_CALL) |
2172 { | 2257 { |
2173 if (can_throw_internal (BB_END (bb)) | 2258 if (!CALL_P (insn)) |
2174 /* If this is a call edge, verify that this is a call insn. */ | 2259 remove = true; |
2175 && (! (e->flags & EDGE_ABNORMAL_CALL) | 2260 else if (can_nonlocal_goto (insn)) |
2176 || CALL_P (BB_END (bb)))) | 2261 ; |
2177 { | 2262 else if ((e->flags & EDGE_EH) && can_throw_internal (insn)) |
2178 ei_next (&ei); | 2263 ; |
2179 continue; | 2264 else |
2180 } | 2265 remove = true; |
2181 } | 2266 } |
2182 else if (e->flags & EDGE_ABNORMAL_CALL) | 2267 else if (e->flags & EDGE_EH) |
2183 { | 2268 remove = !can_throw_internal (insn); |
2184 if (CALL_P (BB_END (bb)) | 2269 |
2185 && (! (note = find_reg_note (insn, REG_EH_REGION, NULL)) | 2270 if (remove) |
2186 || INTVAL (XEXP (note, 0)) >= 0)) | 2271 { |
2187 { | 2272 remove_edge (e); |
2188 ei_next (&ei); | 2273 df_set_bb_dirty (bb); |
2189 continue; | 2274 purged = true; |
2190 } | |
2191 } | 2275 } |
2192 else | 2276 else |
2193 { | 2277 ei_next (&ei); |
2194 ei_next (&ei); | |
2195 continue; | |
2196 } | |
2197 | |
2198 remove_edge (e); | |
2199 df_set_bb_dirty (bb); | |
2200 purged = true; | |
2201 } | 2278 } |
2202 | 2279 |
2203 if (JUMP_P (insn)) | 2280 if (JUMP_P (insn)) |
2204 { | 2281 { |
2205 rtx note; | 2282 rtx note; |
2611 fprintf (dump_file, "merging block %d into block %d\n", b->index, a->index); | 2688 fprintf (dump_file, "merging block %d into block %d\n", b->index, a->index); |
2612 | 2689 |
2613 /* If there was a CODE_LABEL beginning B, delete it. */ | 2690 /* If there was a CODE_LABEL beginning B, delete it. */ |
2614 if (LABEL_P (BB_HEAD (b))) | 2691 if (LABEL_P (BB_HEAD (b))) |
2615 { | 2692 { |
2616 /* This might have been an EH label that no longer has incoming | |
2617 EH edges. Update data structures to match. */ | |
2618 maybe_remove_eh_handler (BB_HEAD (b)); | |
2619 | |
2620 delete_insn (BB_HEAD (b)); | 2693 delete_insn (BB_HEAD (b)); |
2621 } | 2694 } |
2622 | 2695 |
2623 /* We should have fallthru edge in a, or we can do dummy redirection to get | 2696 /* We should have fallthru edge in a, or we can do dummy redirection to get |
2624 it cleaned up. */ | 2697 it cleaned up. */ |
2761 rtx insn = BB_END (bb); | 2834 rtx insn = BB_END (bb); |
2762 | 2835 |
2763 while (!CALL_P (insn) | 2836 while (!CALL_P (insn) |
2764 && insn != BB_HEAD (bb) | 2837 && insn != BB_HEAD (bb) |
2765 && (keep_with_call_p (insn) | 2838 && (keep_with_call_p (insn) |
2766 || NOTE_P (insn))) | 2839 || NOTE_P (insn) |
2840 || DEBUG_INSN_P (insn))) | |
2767 insn = PREV_INSN (insn); | 2841 insn = PREV_INSN (insn); |
2768 return (CALL_P (insn)); | 2842 return (CALL_P (insn)); |
2769 } | 2843 } |
2770 | 2844 |
2771 /* Return 1 if BB ends with a conditional branch, 0 otherwise. */ | 2845 /* Return 1 if BB ends with a conditional branch, 0 otherwise. */ |