comparison gcc/cfgrtl.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 04ced10e8804
comparison
equal deleted inserted replaced
65:65488c3d617d 67:f6334be47118
40 #include "config.h" 40 #include "config.h"
41 #include "system.h" 41 #include "system.h"
42 #include "coretypes.h" 42 #include "coretypes.h"
43 #include "tm.h" 43 #include "tm.h"
44 #include "tree.h" 44 #include "tree.h"
45 #include "rtl.h"
46 #include "hard-reg-set.h" 45 #include "hard-reg-set.h"
47 #include "basic-block.h" 46 #include "basic-block.h"
48 #include "regs.h" 47 #include "regs.h"
49 #include "flags.h" 48 #include "flags.h"
50 #include "output.h" 49 #include "output.h"
51 #include "function.h" 50 #include "function.h"
52 #include "except.h" 51 #include "except.h"
53 #include "toplev.h" 52 #include "rtl-error.h"
54 #include "tm_p.h" 53 #include "tm_p.h"
55 #include "obstack.h" 54 #include "obstack.h"
56 #include "insn-attr.h" 55 #include "insn-attr.h"
57 #include "insn-config.h" 56 #include "insn-config.h"
58 #include "cfglayout.h" 57 #include "cfglayout.h"
420 { 419 {
421 #ifdef DELAY_SLOTS 420 #ifdef DELAY_SLOTS
422 /* The resource.c machinery uses DF but the CFG isn't guaranteed to be 421 /* The resource.c machinery uses DF but the CFG isn't guaranteed to be
423 valid at that point so it would be too late to call df_analyze. */ 422 valid at that point so it would be too late to call df_analyze. */
424 if (optimize > 0 && flag_delayed_branch) 423 if (optimize > 0 && flag_delayed_branch)
425 df_analyze (); 424 {
425 df_note_add_problem ();
426 df_analyze ();
427 }
426 #endif 428 #endif
427 429
428 free_bb_for_insn (); 430 free_bb_for_insn ();
429 return 0; 431 return 0;
430 } 432 }
584 rtl_merge_blocks (basic_block a, basic_block b) 586 rtl_merge_blocks (basic_block a, basic_block b)
585 { 587 {
586 rtx b_head = BB_HEAD (b), b_end = BB_END (b), a_end = BB_END (a); 588 rtx b_head = BB_HEAD (b), b_end = BB_END (b), a_end = BB_END (a);
587 rtx del_first = NULL_RTX, del_last = NULL_RTX; 589 rtx del_first = NULL_RTX, del_last = NULL_RTX;
588 rtx b_debug_start = b_end, b_debug_end = b_end; 590 rtx b_debug_start = b_end, b_debug_end = b_end;
591 bool forwarder_p = (b->flags & BB_FORWARDER_BLOCK) != 0;
589 int b_empty = 0; 592 int b_empty = 0;
590 593
591 if (dump_file) 594 if (dump_file)
592 fprintf (dump_file, "merging block %d into block %d\n", b->index, a->index); 595 fprintf (dump_file, "Merging block %d into block %d...\n", b->index,
596 a->index);
593 597
594 while (DEBUG_INSN_P (b_end)) 598 while (DEBUG_INSN_P (b_end))
595 b_end = PREV_INSN (b_debug_start = b_end); 599 b_end = PREV_INSN (b_debug_start = b_end);
596 600
597 /* If there was a CODE_LABEL beginning B, delete it. */ 601 /* If there was a CODE_LABEL beginning B, delete it. */
676 a_end = b_debug_end; 680 a_end = b_debug_end;
677 } 681 }
678 682
679 df_bb_delete (b->index); 683 df_bb_delete (b->index);
680 BB_END (a) = a_end; 684 BB_END (a) = a_end;
685
686 /* If B was a forwarder block, propagate the locus on the edge. */
687 if (forwarder_p && !EDGE_SUCC (b, 0)->goto_locus)
688 EDGE_SUCC (b, 0)->goto_locus = EDGE_SUCC (a, 0)->goto_locus;
689
690 if (dump_file)
691 fprintf (dump_file, "Merged blocks %d and %d.\n", a->index, b->index);
681 } 692 }
682 693
683 694
684 /* Return true when block A and B can be merged. */ 695 /* Return true when block A and B can be merged. */
685 696
1049 } 1060 }
1050 else 1061 else
1051 /* When expanding this BB might actually contain multiple 1062 /* When expanding this BB might actually contain multiple
1052 jumps (i.e. not yet split by find_many_sub_basic_blocks). 1063 jumps (i.e. not yet split by find_many_sub_basic_blocks).
1053 Redirect all of those that match our label. */ 1064 Redirect all of those that match our label. */
1054 for (insn = BB_HEAD (src); insn != NEXT_INSN (BB_END (src)); 1065 FOR_BB_INSNS (src, insn)
1055 insn = NEXT_INSN (insn))
1056 if (JUMP_P (insn) && !patch_jump_insn (insn, old_label, target)) 1066 if (JUMP_P (insn) && !patch_jump_insn (insn, old_label, target))
1057 return NULL; 1067 return NULL;
1058 1068
1059 if (dump_file) 1069 if (dump_file)
1060 fprintf (dump_file, "Edge %i->%i redirected to %i\n", 1070 fprintf (dump_file, "Edge %i->%i redirected to %i\n",
1366 1376
1367 /* We are going to place the new block in front of edge destination. 1377 /* We are going to place the new block in front of edge destination.
1368 Avoid existence of fallthru predecessors. */ 1378 Avoid existence of fallthru predecessors. */
1369 if ((edge_in->flags & EDGE_FALLTHRU) == 0) 1379 if ((edge_in->flags & EDGE_FALLTHRU) == 0)
1370 { 1380 {
1371 edge e; 1381 edge e = find_fallthru_edge (edge_in->dest->preds);
1372 edge_iterator ei;
1373
1374 FOR_EACH_EDGE (e, ei, edge_in->dest->preds)
1375 if (e->flags & EDGE_FALLTHRU)
1376 break;
1377 1382
1378 if (e) 1383 if (e)
1379 force_nonfallthru (e); 1384 force_nonfallthru (e);
1380 } 1385 }
1381 1386
2064 bb_info = XCNEWVEC (basic_block, max_uid); 2069 bb_info = XCNEWVEC (basic_block, max_uid);
2065 2070
2066 FOR_EACH_BB_REVERSE (bb) 2071 FOR_EACH_BB_REVERSE (bb)
2067 { 2072 {
2068 edge e; 2073 edge e;
2069 edge_iterator ei;
2070 rtx head = BB_HEAD (bb); 2074 rtx head = BB_HEAD (bb);
2071 rtx end = BB_END (bb); 2075 rtx end = BB_END (bb);
2072 2076
2073 for (x = last_head; x != NULL_RTX; x = PREV_INSN (x)) 2077 for (x = last_head; x != NULL_RTX; x = PREV_INSN (x))
2074 { 2078 {
2118 err = 1; 2122 err = 1;
2119 } 2123 }
2120 2124
2121 last_head = PREV_INSN (x); 2125 last_head = PREV_INSN (x);
2122 2126
2123 FOR_EACH_EDGE (e, ei, bb->succs) 2127 e = find_fallthru_edge (bb->succs);
2124 if (e->flags & EDGE_FALLTHRU)
2125 break;
2126 if (!e) 2128 if (!e)
2127 { 2129 {
2128 rtx insn; 2130 rtx insn;
2129 2131
2130 /* Ensure existence of barrier in BB with no fallthru edges. */ 2132 /* Ensure existence of barrier in BB with no fallthru edges. */
2696 /* Merge block A and B. The blocks must be mergeable. */ 2698 /* Merge block A and B. The blocks must be mergeable. */
2697 2699
2698 static void 2700 static void
2699 cfg_layout_merge_blocks (basic_block a, basic_block b) 2701 cfg_layout_merge_blocks (basic_block a, basic_block b)
2700 { 2702 {
2701 #ifdef ENABLE_CHECKING 2703 bool forwarder_p = (b->flags & BB_FORWARDER_BLOCK) != 0;
2702 gcc_assert (cfg_layout_can_merge_blocks_p (a, b)); 2704
2703 #endif 2705 gcc_checking_assert (cfg_layout_can_merge_blocks_p (a, b));
2704 2706
2705 if (dump_file) 2707 if (dump_file)
2706 fprintf (dump_file, "merging block %d into block %d\n", b->index, a->index); 2708 fprintf (dump_file, "Merging block %d into block %d...\n", b->index,
2709 a->index);
2707 2710
2708 /* If there was a CODE_LABEL beginning B, delete it. */ 2711 /* If there was a CODE_LABEL beginning B, delete it. */
2709 if (LABEL_P (BB_HEAD (b))) 2712 if (LABEL_P (BB_HEAD (b)))
2710 { 2713 {
2711 delete_insn (BB_HEAD (b)); 2714 delete_insn (BB_HEAD (b));
2809 PREV_INSN (b->il.rtl->footer) = last; 2812 PREV_INSN (b->il.rtl->footer) = last;
2810 } 2813 }
2811 b->il.rtl->footer = NULL; 2814 b->il.rtl->footer = NULL;
2812 } 2815 }
2813 2816
2817 /* If B was a forwarder block, propagate the locus on the edge. */
2818 if (forwarder_p && !EDGE_SUCC (b, 0)->goto_locus)
2819 EDGE_SUCC (b, 0)->goto_locus = EDGE_SUCC (a, 0)->goto_locus;
2820
2814 if (dump_file) 2821 if (dump_file)
2815 fprintf (dump_file, "Merged blocks %d and %d.\n", 2822 fprintf (dump_file, "Merged blocks %d and %d.\n", a->index, b->index);
2816 a->index, b->index);
2817 } 2823 }
2818 2824
2819 /* Split edge E. */ 2825 /* Split edge E. */
2820 2826
2821 static basic_block 2827 static basic_block
3078 3084
3079 void 3085 void
3080 init_rtl_bb_info (basic_block bb) 3086 init_rtl_bb_info (basic_block bb)
3081 { 3087 {
3082 gcc_assert (!bb->il.rtl); 3088 gcc_assert (!bb->il.rtl);
3083 bb->il.rtl = GGC_CNEW (struct rtl_bb_info); 3089 bb->il.rtl = ggc_alloc_cleared_rtl_bb_info ();
3084 }
3085
3086
3087 /* Add EXPR to the end of basic block BB. */
3088
3089 rtx
3090 insert_insn_end_bb_new (rtx pat, basic_block bb)
3091 {
3092 rtx insn = BB_END (bb);
3093 rtx new_insn;
3094 rtx pat_end = pat;
3095
3096 while (NEXT_INSN (pat_end) != NULL_RTX)
3097 pat_end = NEXT_INSN (pat_end);
3098
3099 /* If the last insn is a jump, insert EXPR in front [taking care to
3100 handle cc0, etc. properly]. Similarly we need to care trapping
3101 instructions in presence of non-call exceptions. */
3102
3103 if (JUMP_P (insn)
3104 || (NONJUMP_INSN_P (insn)
3105 && (!single_succ_p (bb)
3106 || single_succ_edge (bb)->flags & EDGE_ABNORMAL)))
3107 {
3108 #ifdef HAVE_cc0
3109 rtx note;
3110 #endif
3111 /* If this is a jump table, then we can't insert stuff here. Since
3112 we know the previous real insn must be the tablejump, we insert
3113 the new instruction just before the tablejump. */
3114 if (GET_CODE (PATTERN (insn)) == ADDR_VEC
3115 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
3116 insn = prev_real_insn (insn);
3117
3118 #ifdef HAVE_cc0
3119 /* FIXME: 'twould be nice to call prev_cc0_setter here but it aborts
3120 if cc0 isn't set. */
3121 note = find_reg_note (insn, REG_CC_SETTER, NULL_RTX);
3122 if (note)
3123 insn = XEXP (note, 0);
3124 else
3125 {
3126 rtx maybe_cc0_setter = prev_nonnote_insn (insn);
3127 if (maybe_cc0_setter
3128 && INSN_P (maybe_cc0_setter)
3129 && sets_cc0_p (PATTERN (maybe_cc0_setter)))
3130 insn = maybe_cc0_setter;
3131 }
3132 #endif
3133 /* FIXME: What if something in cc0/jump uses value set in new
3134 insn? */
3135 new_insn = emit_insn_before_noloc (pat, insn, bb);
3136 }
3137
3138 /* Likewise if the last insn is a call, as will happen in the presence
3139 of exception handling. */
3140 else if (CALL_P (insn)
3141 && (!single_succ_p (bb)
3142 || single_succ_edge (bb)->flags & EDGE_ABNORMAL))
3143 {
3144 /* Keeping in mind targets with small register classes and parameters
3145 in registers, we search backward and place the instructions before
3146 the first parameter is loaded. Do this for everyone for consistency
3147 and a presumption that we'll get better code elsewhere as well. */
3148
3149 /* Since different machines initialize their parameter registers
3150 in different orders, assume nothing. Collect the set of all
3151 parameter registers. */
3152 insn = find_first_parameter_load (insn, BB_HEAD (bb));
3153
3154 /* If we found all the parameter loads, then we want to insert
3155 before the first parameter load.
3156
3157 If we did not find all the parameter loads, then we might have
3158 stopped on the head of the block, which could be a CODE_LABEL.
3159 If we inserted before the CODE_LABEL, then we would be putting
3160 the insn in the wrong basic block. In that case, put the insn
3161 after the CODE_LABEL. Also, respect NOTE_INSN_BASIC_BLOCK. */
3162 while (LABEL_P (insn)
3163 || NOTE_INSN_BASIC_BLOCK_P (insn))
3164 insn = NEXT_INSN (insn);
3165
3166 new_insn = emit_insn_before_noloc (pat, insn, bb);
3167 }
3168 else
3169 new_insn = emit_insn_after_noloc (pat, insn, bb);
3170
3171 return new_insn;
3172 } 3090 }
3173 3091
3174 /* Returns true if it is possible to remove edge E by redirecting 3092 /* Returns true if it is possible to remove edge E by redirecting
3175 it to the destination of the other edge from E->src. */ 3093 it to the destination of the other edge from E->src. */
3176 3094