diff options
author | Jan Hubicka <jh@suse.cz> | 2001-07-26 22:36:01 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2001-07-26 20:36:01 +0000 |
commit | 01f62f016bb811b0010a36d058c660882a92ca1c (patch) | |
tree | 4d6e8197e32e92b663df66e7f3d07be1ccf41202 /gcc | |
parent | aa069f77b2591aed51274befe68aeef5c903f45c (diff) | |
download | gcc-01f62f016bb811b0010a36d058c660882a92ca1c.zip gcc-01f62f016bb811b0010a36d058c660882a92ca1c.tar.gz gcc-01f62f016bb811b0010a36d058c660882a92ca1c.tar.bz2 |
rtl.h (cleanup_barriers): Declare.
* rtl.h (cleanup_barriers): Declare.
* jump.c (cleanup_barriers): New function.
* toplev.c (rest_of_compilation): Call cleanup_barriers
before loop optimizer and after bb_reorder.
* flow.c (back_edge_of_syntactic_loop_p): New.
(split_edge): Use it.
From-SVN: r44409
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/flow.c | 28 | ||||
-rw-r--r-- | gcc/jump.c | 26 | ||||
-rw-r--r-- | gcc/rtl.h | 1 | ||||
-rw-r--r-- | gcc/toplev.c | 4 |
5 files changed, 68 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0ab4a10..fddead1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +Thu Jul 26 22:30:22 CEST 2001 Jan Hubicka <jh@suse.cz> + + * rtl.h (cleanup_barriers): Declare. + * jump.c (cleanup_barriers): New function. + * toplev.c (rest_of_compilation): Call cleanup_barriers + before loop optimizer and after bb_reorder. + + * flow.c (back_edge_of_syntactic_loop_p): New. + (split_edge): Use it. + 2001-07-26 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE> * glimits.h (_MACH_MACHLIMITS_H_): Delete. @@ -482,6 +482,7 @@ static void flow_loops_tree_build PARAMS ((struct loops *)); static int flow_loop_level_compute PARAMS ((struct loop *, int)); static int flow_loops_level_compute PARAMS ((struct loops *)); static void delete_dead_jumptables PARAMS ((void)); +static bool back_edge_of_syntactic_loop_p PARAMS ((basic_block, basic_block)); /* Find basic blocks of the current function. F is the first insn of the function and NREGS the number of register @@ -1968,6 +1969,30 @@ redirect_edge_and_branch_force (e, target) return new_bb; } +/* Helper function for split_edge. Return true in case edge BB2 to BB1 + is back edge of syntactic loop. */ +static bool +back_edge_of_syntactic_loop_p (bb1, bb2) + basic_block bb1, bb2; +{ + rtx insn; + int count; + if (bb1->index > bb2->index) + return false; + if (bb1->index == bb2->index) + return true; + for (insn = bb1->end; insn != bb2->head && count >= 0; + insn = NEXT_INSN (insn)) + if (GET_CODE (insn) == NOTE) + { + if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG) + count++; + if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END) + count--; + } + return count >= 0; +} + /* Split a (typically critical) edge. Return the new block. Abort on abnormal edges. @@ -2115,7 +2140,8 @@ split_edge (edge_in) if (old_succ != EXIT_BLOCK_PTR && PREV_INSN (old_succ->head) && GET_CODE (PREV_INSN (old_succ->head)) == NOTE - && NOTE_LINE_NUMBER (PREV_INSN (old_succ->head)) == NOTE_INSN_LOOP_BEG) + && NOTE_LINE_NUMBER (PREV_INSN (old_succ->head)) == NOTE_INSN_LOOP_BEG + && !back_edge_of_syntactic_loop_p (old_succ, old_pred)) bb_note = emit_note_before (NOTE_INSN_BASIC_BLOCK, PREV_INSN (old_succ->head)); else if (old_succ != EXIT_BLOCK_PTR) @@ -100,6 +100,32 @@ rebuild_jump_labels (f) LABEL_NUSES (XEXP (insn, 0))++; } +/* Some old code expects exactly one BARRIER as the NEXT_INSN of a + non-fallthru insn. This is not generally true, as multiple barriers + may have crept in, or the BARRIER may be separated from the last + real insn by one or more NOTEs. + + This simple pass moves barriers and removes duplicates so that the + old code is happy. + */ +void +cleanup_barriers () +{ + rtx insn, next, prev; + for (insn = get_insns (); insn; insn = next) + { + next = NEXT_INSN (insn); + if (GET_CODE (insn) == BARRIER) + { + prev = prev_nonnote_insn (insn); + if (GET_CODE (prev) == BARRIER) + delete_barrier (insn); + else if (prev != PREV_INSN (insn)) + reorder_insns (insn, insn, prev); + } + } +} + void copy_loop_headers (f) rtx f; @@ -1286,6 +1286,7 @@ extern enum rtx_code swap_condition PARAMS ((enum rtx_code)); extern enum rtx_code unsigned_condition PARAMS ((enum rtx_code)); extern enum rtx_code signed_condition PARAMS ((enum rtx_code)); extern void mark_jump_label PARAMS ((rtx, rtx, int)); +extern void cleanup_barriers PARAMS ((void)); /* In jump.c */ extern rtx squeeze_notes PARAMS ((rtx, rtx)); diff --git a/gcc/toplev.c b/gcc/toplev.c index a28b38e..21d4fbb 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -3096,6 +3096,8 @@ rest_of_compilation (decl) if (flag_rerun_loop_opt) { + cleanup_barriers (); + /* We only want to perform unrolling once. */ loop_optimize (insns, rtl_dump_file, 0); @@ -3110,6 +3112,7 @@ rest_of_compilation (decl) analysis code depends on this information. */ reg_scan (insns, max_reg_num (), 1); } + cleanup_barriers (); loop_optimize (insns, rtl_dump_file, (flag_unroll_loops ? LOOP_UNROLL : 0) | LOOP_BCT); @@ -3614,6 +3617,7 @@ rest_of_compilation (decl) /* CFG no longer kept up to date. */ purge_line_number_notes (insns); + cleanup_barriers (); /* If a scheduling pass for delayed branches is to be done, call the scheduling code. */ |