diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1c66228e1955543daa5f95ed7aa1010d6ae5368e..bbe5a665f1d246478571c3c725dfdae92d8e0a9c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,4 +1,18 @@ -2013-02-01 Richard Henderson <rth@redhat.com> +2013-02-01 Jakub Jelinek <jakub@redhat.com> + + PR debug/54793 + * final.c (need_profile_function): New variable. + (final_start_function): Drop ATTRIBUTE_UNUSED from first argument. + If first of NOTE_INSN_BASIC_BLOCK or NOTE_INSN_FUNCTION_BEG + is only preceeded by NOTE_INSN_VAR_LOCATION or NOTE_INSN_DELETED + notes, targetm.asm_out.function_prologue doesn't emit anything, + HAVE_prologue and profiler should be emitted before prologue, + set need_profile_function instead of emitting it. + (final_scan_insn): If need_profile_function, emit + profile_function on the first NOTE_INSN_BASIC_BLOCK or + NOTE_INSN_FUNCTION_BEG note. + +2013-02-01 Richard Henderson <rth@redhat.com> * config/rs6000/rs6000.md (smulditi3): New. (umulditi3): New. diff --git a/gcc/final.c b/gcc/final.c index d5154db2c4288ddd1b3290c726c1fc5881c430b0..d25b8e0b7e4b9657ce34ad66ee8d4c6c25c368f7 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -200,6 +200,9 @@ rtx current_insn_predicate; /* True if printing into -fdump-final-insns= dump. */ bool final_insns_dump_p; +/* True if profile_function should be called, but hasn't been called yet. */ +static bool need_profile_function; + static int asm_insn_count (rtx); static void profile_function (FILE *); static void profile_after_prologue (FILE *); @@ -1668,13 +1671,15 @@ reemit_insn_block_notes (void) test and compare insns. */ void -final_start_function (rtx first ATTRIBUTE_UNUSED, FILE *file, +final_start_function (rtx first, FILE *file, int optimize_p ATTRIBUTE_UNUSED) { block_depth = 0; this_is_asm_operands = 0; + need_profile_function = false; + last_filename = LOCATION_FILE (prologue_location); last_linenum = LOCATION_LINE (prologue_location); last_discriminator = discriminator = 0; @@ -1695,7 +1700,41 @@ final_start_function (rtx first ATTRIBUTE_UNUSED, FILE *file, /* The Sun386i and perhaps other machines don't work right if the profiling code comes after the prologue. */ if (targetm.profile_before_prologue () && crtl->profile) - profile_function (file); + { + if (targetm.asm_out.function_prologue + == default_function_pro_epilogue +#ifdef HAVE_prologue + && HAVE_prologue +#endif + ) + { + rtx insn; + for (insn = first; insn; insn = NEXT_INSN (insn)) + if (!NOTE_P (insn)) + { + insn = NULL_RTX; + break; + } + else if (NOTE_KIND (insn) == NOTE_INSN_BASIC_BLOCK + || NOTE_KIND (insn) == NOTE_INSN_FUNCTION_BEG) + break; + else if (NOTE_KIND (insn) == NOTE_INSN_DELETED + || NOTE_KIND (insn) == NOTE_INSN_VAR_LOCATION) + continue; + else + { + insn = NULL_RTX; + break; + } + + if (insn) + need_profile_function = true; + else + profile_function (file); + } + else + profile_function (file); + } /* If debugging, assign block numbers to all of the blocks in this function. */ @@ -2075,6 +2114,12 @@ final_scan_insn (rtx insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED, break; case NOTE_INSN_BASIC_BLOCK: + if (need_profile_function) + { + profile_function (asm_out_file); + need_profile_function = false; + } + if (targetm.asm_out.unwind_emit) targetm.asm_out.unwind_emit (asm_out_file, insn); @@ -2130,6 +2175,12 @@ final_scan_insn (rtx insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED, break; case NOTE_INSN_FUNCTION_BEG: + if (need_profile_function) + { + profile_function (asm_out_file); + need_profile_function = false; + } + app_disable (); if (!DECL_IGNORED_P (current_function_decl)) debug_hooks->end_prologue (last_linenum, last_filename);