diff options
author | Richard Henderson <rth@cygnus.com> | 2000-05-29 01:18:30 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2000-05-29 01:18:30 -0700 |
commit | 86c82654129e4b57713498ef3e5c88fc1bb2f1aa (patch) | |
tree | 110df981e31562ec8e459f9059bebb34f553d4d0 /gcc | |
parent | 8f4773eae70e9869bcb5869c7073a0b8e6bc18f2 (diff) | |
download | gcc-86c82654129e4b57713498ef3e5c88fc1bb2f1aa.zip gcc-86c82654129e4b57713498ef3e5c88fc1bb2f1aa.tar.gz gcc-86c82654129e4b57713498ef3e5c88fc1bb2f1aa.tar.bz2 |
function.c (emit_return_into_block): New line_note arg; emit it.
* function.c (emit_return_into_block): New line_note arg; emit it.
(thread_prologue_and_epilogue_insns): Attempt to locate a line note
for the close brace to accompany HAVE_return. Move all line notes
following the epilogue to before the NOTE_INSN_EPILOGUE_BEG.
From-SVN: r34251
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/function.c | 71 |
2 files changed, 55 insertions, 23 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 220fa68..f425de9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,12 @@ 2000-05-29 Richard Henderson <rth@cygnus.com> + * function.c (emit_return_into_block): New line_note arg; emit it. + (thread_prologue_and_epilogue_insns): Attempt to locate a line note + for the close brace to accompany HAVE_return. Move all line notes + following the epilogue to before the NOTE_INSN_EPILOGUE_BEG. + +2000-05-29 Richard Henderson <rth@cygnus.com> + * longlong.h [__alpha] (count_leading_zeros): New. (count_trailing_zeros): New. (COUNT_LEADING_ZEROS_0): New. diff --git a/gcc/function.c b/gcc/function.c index 07f58d5..1c67eec 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -290,7 +290,7 @@ static tree *get_block_vector PARAMS ((tree, int *)); static void record_insns PARAMS ((rtx, varray_type *)) ATTRIBUTE_UNUSED; static int contains PARAMS ((rtx, varray_type)); #ifdef HAVE_return -static void emit_return_into_block PARAMS ((basic_block)); +static void emit_return_into_block PARAMS ((basic_block, rtx)); #endif static void put_addressof_into_stack PARAMS ((rtx, struct hash_table *)); static boolean purge_addressof_1 PARAMS ((rtx *, rtx, int, int, @@ -6798,19 +6798,24 @@ sibcall_epilogue_contains (insn) block_for_insn appropriately. */ static void -emit_return_into_block (bb) +emit_return_into_block (bb, line_note) basic_block bb; + rtx line_note; { rtx p, end; - end = emit_jump_insn_after (gen_return (), bb->end); p = NEXT_INSN (bb->end); + end = emit_jump_insn_after (gen_return (), bb->end); + if (line_note) + emit_line_note_after (NOTE_SOURCE_FILE (line_note), + NOTE_LINE_NUMBER (line_note), bb->end); + while (1) { set_block_for_insn (p, bb); - if (p == end) + if (p == bb->end) break; - p = NEXT_INSN (p); + p = PREV_INSN (p); } bb->end = end; } @@ -6830,6 +6835,9 @@ thread_prologue_and_epilogue_insns (f) #ifdef HAVE_prologue rtx prologue_end = NULL_RTX; #endif +#if defined (HAVE_epilogue) || defined(HAVE_return) + rtx epilogue_end = NULL_RTX; +#endif #ifdef HAVE_prologue if (HAVE_prologue) @@ -6902,6 +6910,19 @@ thread_prologue_and_epilogue_insns (f) if (last->head == label && GET_CODE (label) == CODE_LABEL) { + rtx epilogue_line_note = NULL_RTX; + + /* Locate the line number associated with the closing brace, + if we can find one. */ + for (seq = get_last_insn (); + seq && ! active_insn_p (seq); + seq = PREV_INSN (seq)) + if (GET_CODE (seq) == NOTE && NOTE_LINE_NUMBER (seq) > 0) + { + epilogue_line_note = seq; + break; + } + for (e = last->pred; e ; e = e_next) { basic_block bb = e->src; @@ -6919,7 +6940,7 @@ thread_prologue_and_epilogue_insns (f) with a simple return instruction. */ if (simplejump_p (jump)) { - emit_return_into_block (bb); + emit_return_into_block (bb, epilogue_line_note); flow_delete_insn (jump); } @@ -6951,29 +6972,17 @@ thread_prologue_and_epilogue_insns (f) continue; /* Fix up the CFG for the successful change we just made. */ - remove_edge (e); - make_edge (NULL, bb, EXIT_BLOCK_PTR, 0); + redirect_edge_succ (e, EXIT_BLOCK_PTR); } /* Emit a return insn for the exit fallthru block. Whether this is still reachable will be determined later. */ emit_barrier_after (last->end); - emit_return_into_block (last); - } - else - { - /* The exit block wasn't empty. We have to use insert_insn_on_edge, - as it may be the exit block can go elsewhere as well - as exiting. */ - start_sequence (); - emit_jump_insn (gen_return ()); - seq = gen_sequence (); - end_sequence (); - insert_insn_on_edge (seq, e); - inserted = 1; + emit_return_into_block (last, epilogue_line_note); + epilogue_end = last->end; + goto epilogue_done; } - goto epilogue_done; } #endif #ifdef HAVE_epilogue @@ -6991,7 +7000,7 @@ thread_prologue_and_epilogue_insns (f) goto epilogue_done; start_sequence (); - emit_note (NULL, NOTE_INSN_EPILOGUE_BEG); + epilogue_end = emit_note (NULL, NOTE_INSN_EPILOGUE_BEG); seq = gen_epilogue (); emit_jump_insn (seq); @@ -7094,6 +7103,22 @@ epilogue_done: } } #endif +#ifdef HAVE_epilogue + if (epilogue_end) + { + rtx insn, next; + + /* Similarly, move any line notes that appear after the epilogue. + There is no need, however, to be quite so anal about the existance + of such a note. */ + for (insn = epilogue_end; insn ; insn = next) + { + next = NEXT_INSN (insn); + if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > 0) + reorder_insns (insn, insn, PREV_INSN (epilogue_end)); + } + } +#endif } /* Reposition the prologue-end and epilogue-begin notes after instruction |