Mercurial > hg > CbC > CbC_gcc
comparison gcc/cfglayout.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children |
comparison
equal
deleted
inserted
replaced
65:65488c3d617d | 67:f6334be47118 |
---|---|
37 #include "alloc-pool.h" | 37 #include "alloc-pool.h" |
38 #include "flags.h" | 38 #include "flags.h" |
39 #include "tree-pass.h" | 39 #include "tree-pass.h" |
40 #include "df.h" | 40 #include "df.h" |
41 #include "vecprim.h" | 41 #include "vecprim.h" |
42 #include "emit-rtl.h" | |
42 | 43 |
43 /* Holds the interesting trailing notes for the function. */ | 44 /* Holds the interesting trailing notes for the function. */ |
44 rtx cfg_layout_function_footer; | 45 rtx cfg_layout_function_footer; |
45 rtx cfg_layout_function_header; | 46 rtx cfg_layout_function_header; |
46 | 47 |
371 NULL, /* gate */ | 372 NULL, /* gate */ |
372 into_cfg_layout_mode, /* execute */ | 373 into_cfg_layout_mode, /* execute */ |
373 NULL, /* sub */ | 374 NULL, /* sub */ |
374 NULL, /* next */ | 375 NULL, /* next */ |
375 0, /* static_pass_number */ | 376 0, /* static_pass_number */ |
376 TV_NONE, /* tv_id */ | 377 TV_CFG, /* tv_id */ |
377 0, /* properties_required */ | 378 0, /* properties_required */ |
378 PROP_cfglayout, /* properties_provided */ | 379 PROP_cfglayout, /* properties_provided */ |
379 0, /* properties_destroyed */ | 380 0, /* properties_destroyed */ |
380 0, /* todo_flags_start */ | 381 0, /* todo_flags_start */ |
381 TODO_dump_func, /* todo_flags_finish */ | 382 TODO_dump_func, /* todo_flags_finish */ |
390 NULL, /* gate */ | 391 NULL, /* gate */ |
391 outof_cfg_layout_mode, /* execute */ | 392 outof_cfg_layout_mode, /* execute */ |
392 NULL, /* sub */ | 393 NULL, /* sub */ |
393 NULL, /* next */ | 394 NULL, /* next */ |
394 0, /* static_pass_number */ | 395 0, /* static_pass_number */ |
395 TV_NONE, /* tv_id */ | 396 TV_CFG, /* tv_id */ |
396 0, /* properties_required */ | 397 0, /* properties_required */ |
397 0, /* properties_provided */ | 398 0, /* properties_provided */ |
398 PROP_cfglayout, /* properties_destroyed */ | 399 PROP_cfglayout, /* properties_destroyed */ |
399 0, /* todo_flags_start */ | 400 0, /* todo_flags_start */ |
400 TODO_dump_func, /* todo_flags_finish */ | 401 TODO_dump_func, /* todo_flags_finish */ |
825 (e_fall->dest == EXIT_BLOCK_PTR | 826 (e_fall->dest == EXIT_BLOCK_PTR |
826 ? NULL_RTX | 827 ? NULL_RTX |
827 : label_for_bb (e_fall->dest)), 0)) | 828 : label_for_bb (e_fall->dest)), 0)) |
828 { | 829 { |
829 e_fall->flags &= ~EDGE_FALLTHRU; | 830 e_fall->flags &= ~EDGE_FALLTHRU; |
830 #ifdef ENABLE_CHECKING | 831 gcc_checking_assert (could_fall_through |
831 gcc_assert (could_fall_through | 832 (e_taken->src, e_taken->dest)); |
832 (e_taken->src, e_taken->dest)); | |
833 #endif | |
834 e_taken->flags |= EDGE_FALLTHRU; | 833 e_taken->flags |= EDGE_FALLTHRU; |
835 update_br_prob_note (bb); | 834 update_br_prob_note (bb); |
836 e = e_fall, e_fall = e_taken, e_taken = e; | 835 e = e_fall, e_fall = e_taken, e_taken = e; |
837 } | 836 } |
838 } | 837 } |
849 (e_fall->dest == EXIT_BLOCK_PTR | 848 (e_fall->dest == EXIT_BLOCK_PTR |
850 ? NULL_RTX | 849 ? NULL_RTX |
851 : label_for_bb (e_fall->dest)), 0)) | 850 : label_for_bb (e_fall->dest)), 0)) |
852 { | 851 { |
853 e_fall->flags &= ~EDGE_FALLTHRU; | 852 e_fall->flags &= ~EDGE_FALLTHRU; |
854 #ifdef ENABLE_CHECKING | 853 gcc_checking_assert (could_fall_through |
855 gcc_assert (could_fall_through | 854 (e_taken->src, e_taken->dest)); |
856 (e_taken->src, e_taken->dest)); | |
857 #endif | |
858 e_taken->flags |= EDGE_FALLTHRU; | 855 e_taken->flags |= EDGE_FALLTHRU; |
859 update_br_prob_note (bb); | 856 update_br_prob_note (bb); |
860 continue; | 857 continue; |
861 } | 858 } |
862 } | 859 } |
924 relink_block_chain (/*stay_in_cfglayout_mode=*/false); | 921 relink_block_chain (/*stay_in_cfglayout_mode=*/false); |
925 | 922 |
926 /* Annoying special case - jump around dead jumptables left in the code. */ | 923 /* Annoying special case - jump around dead jumptables left in the code. */ |
927 FOR_EACH_BB (bb) | 924 FOR_EACH_BB (bb) |
928 { | 925 { |
929 edge e; | 926 edge e = find_fallthru_edge (bb->succs); |
930 edge_iterator ei; | |
931 | |
932 FOR_EACH_EDGE (e, ei, bb->succs) | |
933 if (e->flags & EDGE_FALLTHRU) | |
934 break; | |
935 | 927 |
936 if (e && !can_fallthru (e->src, e->dest)) | 928 if (e && !can_fallthru (e->src, e->dest)) |
937 force_nonfallthru (e); | 929 force_nonfallthru (e); |
938 } | 930 } |
939 | 931 |
946 edge_iterator ei; | 938 edge_iterator ei; |
947 | 939 |
948 FOR_EACH_EDGE (e, ei, bb->succs) | 940 FOR_EACH_EDGE (e, ei, bb->succs) |
949 if (e->goto_locus && !(e->flags & EDGE_ABNORMAL)) | 941 if (e->goto_locus && !(e->flags & EDGE_ABNORMAL)) |
950 { | 942 { |
951 basic_block nb; | 943 edge e2; |
944 edge_iterator ei2; | |
945 basic_block dest, nb; | |
952 rtx end; | 946 rtx end; |
953 | 947 |
954 insn = BB_END (e->src); | 948 insn = BB_END (e->src); |
955 end = PREV_INSN (BB_HEAD (e->src)); | 949 end = PREV_INSN (BB_HEAD (e->src)); |
956 while (insn != end | 950 while (insn != end |
957 && (!INSN_P (insn) || INSN_LOCATOR (insn) == 0)) | 951 && (!NONDEBUG_INSN_P (insn) || INSN_LOCATOR (insn) == 0)) |
958 insn = PREV_INSN (insn); | 952 insn = PREV_INSN (insn); |
959 if (insn != end | 953 if (insn != end |
960 && locator_eq (INSN_LOCATOR (insn), (int) e->goto_locus)) | 954 && locator_eq (INSN_LOCATOR (insn), (int) e->goto_locus)) |
961 continue; | 955 continue; |
962 if (simplejump_p (BB_END (e->src)) | 956 if (simplejump_p (BB_END (e->src)) |
963 && INSN_LOCATOR (BB_END (e->src)) == 0) | 957 && INSN_LOCATOR (BB_END (e->src)) == 0) |
964 { | 958 { |
965 INSN_LOCATOR (BB_END (e->src)) = e->goto_locus; | 959 INSN_LOCATOR (BB_END (e->src)) = e->goto_locus; |
966 continue; | 960 continue; |
967 } | 961 } |
968 if (e->dest != EXIT_BLOCK_PTR) | 962 dest = e->dest; |
963 if (dest == EXIT_BLOCK_PTR) | |
969 { | 964 { |
970 insn = BB_HEAD (e->dest); | 965 /* Non-fallthru edges to the exit block cannot be split. */ |
971 end = NEXT_INSN (BB_END (e->dest)); | 966 if (!(e->flags & EDGE_FALLTHRU)) |
972 while (insn != end && !INSN_P (insn)) | 967 continue; |
968 } | |
969 else | |
970 { | |
971 insn = BB_HEAD (dest); | |
972 end = NEXT_INSN (BB_END (dest)); | |
973 while (insn != end && !NONDEBUG_INSN_P (insn)) | |
973 insn = NEXT_INSN (insn); | 974 insn = NEXT_INSN (insn); |
974 if (insn != end && INSN_LOCATOR (insn) | 975 if (insn != end && INSN_LOCATOR (insn) |
975 && locator_eq (INSN_LOCATOR (insn), (int) e->goto_locus)) | 976 && locator_eq (INSN_LOCATOR (insn), (int) e->goto_locus)) |
976 continue; | 977 continue; |
977 } | 978 } |
978 nb = split_edge (e); | 979 nb = split_edge (e); |
979 if (!INSN_P (BB_END (nb))) | 980 if (!INSN_P (BB_END (nb))) |
980 BB_END (nb) = emit_insn_after_noloc (gen_nop (), BB_END (nb), | 981 BB_END (nb) = emit_insn_after_noloc (gen_nop (), BB_END (nb), |
981 nb); | 982 nb); |
982 INSN_LOCATOR (BB_END (nb)) = e->goto_locus; | 983 INSN_LOCATOR (BB_END (nb)) = e->goto_locus; |
984 | |
985 /* If there are other incoming edges to the destination block | |
986 with the same goto locus, redirect them to the new block as | |
987 well, this can prevent other such blocks from being created | |
988 in subsequent iterations of the loop. */ | |
989 for (ei2 = ei_start (dest->preds); (e2 = ei_safe_edge (ei2)); ) | |
990 if (e2->goto_locus | |
991 && !(e2->flags & (EDGE_ABNORMAL | EDGE_FALLTHRU)) | |
992 && locator_eq (e->goto_locus, e2->goto_locus)) | |
993 redirect_edge_and_branch (e2, nb); | |
994 else | |
995 ei_next (&ei2); | |
983 } | 996 } |
984 } | 997 } |
985 } | 998 } |
986 | 999 |
987 /* Perform sanity checks on the insn chain. | 1000 /* Perform sanity checks on the insn chain. |
988 1. Check that next/prev pointers are consistent in both the forward and | 1001 1. Check that next/prev pointers are consistent in both the forward and |
989 reverse direction. | 1002 reverse direction. |
990 2. Count insns in chain, going both directions, and check if equal. | 1003 2. Count insns in chain, going both directions, and check if equal. |
991 3. Check that get_last_insn () returns the actual end of chain. */ | 1004 3. Check that get_last_insn () returns the actual end of chain. */ |
992 | 1005 |
993 void | 1006 DEBUG_FUNCTION void |
994 verify_insn_chain (void) | 1007 verify_insn_chain (void) |
995 { | 1008 { |
996 rtx x, prevx, nextx; | 1009 rtx x, prevx, nextx; |
997 int insn_cnt1, insn_cnt2; | 1010 int insn_cnt1, insn_cnt2; |
998 | 1011 |
1016 that this condition is met. */ | 1029 that this condition is met. */ |
1017 static void | 1030 static void |
1018 fixup_fallthru_exit_predecessor (void) | 1031 fixup_fallthru_exit_predecessor (void) |
1019 { | 1032 { |
1020 edge e; | 1033 edge e; |
1021 edge_iterator ei; | |
1022 basic_block bb = NULL; | 1034 basic_block bb = NULL; |
1023 | 1035 |
1024 /* This transformation is not valid before reload, because we might | 1036 /* This transformation is not valid before reload, because we might |
1025 separate a call from the instruction that copies the return | 1037 separate a call from the instruction that copies the return |
1026 value. */ | 1038 value. */ |
1027 gcc_assert (reload_completed); | 1039 gcc_assert (reload_completed); |
1028 | 1040 |
1029 FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds) | 1041 e = find_fallthru_edge (EXIT_BLOCK_PTR->preds); |
1030 if (e->flags & EDGE_FALLTHRU) | 1042 if (e) |
1031 bb = e->src; | 1043 bb = e->src; |
1032 | 1044 |
1033 if (bb && bb->aux) | 1045 if (bb && bb->aux) |
1034 { | 1046 { |
1035 basic_block c = ENTRY_BLOCK_PTR->next_bb; | 1047 basic_block c = ENTRY_BLOCK_PTR->next_bb; |
1036 | 1048 |
1163 /* Avoid copying of dispatch tables. We never duplicate | 1175 /* Avoid copying of dispatch tables. We never duplicate |
1164 tablejumps, so this can hit only in case the table got | 1176 tablejumps, so this can hit only in case the table got |
1165 moved far from original jump. */ | 1177 moved far from original jump. */ |
1166 if (GET_CODE (PATTERN (insn)) == ADDR_VEC | 1178 if (GET_CODE (PATTERN (insn)) == ADDR_VEC |
1167 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC) | 1179 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC) |
1168 break; | 1180 { |
1181 /* Avoid copying following barrier as well if any | |
1182 (and debug insns in between). */ | |
1183 rtx next; | |
1184 | |
1185 for (next = NEXT_INSN (insn); | |
1186 next != NEXT_INSN (to); | |
1187 next = NEXT_INSN (next)) | |
1188 if (!DEBUG_INSN_P (next)) | |
1189 break; | |
1190 if (next != NEXT_INSN (to) && BARRIER_P (next)) | |
1191 insn = next; | |
1192 break; | |
1193 } | |
1169 copy = emit_copy_of_insn_after (insn, get_last_insn ()); | 1194 copy = emit_copy_of_insn_after (insn, get_last_insn ()); |
1170 maybe_copy_epilogue_insn (insn, copy); | 1195 maybe_copy_prologue_epilogue_insn (insn, copy); |
1171 break; | 1196 break; |
1172 | 1197 |
1173 case CODE_LABEL: | 1198 case CODE_LABEL: |
1174 break; | 1199 break; |
1175 | 1200 |