-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.
/* 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 *);
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;
/* 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. */
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);
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);