diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 60c1cfb4556e1a659db19f6719adccc1dab0fe46..491f441d01de226ba5aff2af8c71680b78648a12 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -6476,6 +6476,12 @@ pass_expand::execute (function *fun) if (crtl->stack_protect_guard && targetm.stack_protect_runtime_enabled_p ()) stack_protect_prologue (); + /* Insert a NOTE that marks the end of "generated code" and the start of code + that comes from the user. This is the point which dwarf2out.c will treat + as the beginning of the users code in this function. e.g. GDB will stop + just after this note when breaking on entry to the function. */ + emit_note (NOTE_INSN_DEBUG_FUNCTION_BEG); + expand_phi_nodes (&SA); /* Release any stale SSA redirection data. */ diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c index 172bdf585d036e27bcf53dba89c1ffc1b6cb84c7..d0cbca84aa3f14002a568a65e70016c3e15d6b9c 100644 --- a/gcc/cfgrtl.c +++ b/gcc/cfgrtl.c @@ -4215,6 +4215,7 @@ duplicate_insn_chain (rtx_insn *from, rtx_insn *to) case NOTE_INSN_DELETED_DEBUG_LABEL: /* No problem to strip these. */ case NOTE_INSN_FUNCTION_BEG: + case NOTE_INSN_DEBUG_FUNCTION_BEG: /* There is always just single entry to function. */ case NOTE_INSN_BASIC_BLOCK: /* We should only switch text sections once. */ diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi index 583291018538722a19a9baf8c46c87cbdfe34216..a50d08483de0db84378e48c9334b48ff12548190 100644 --- a/gcc/doc/rtl.texi +++ b/gcc/doc/rtl.texi @@ -3954,6 +3954,18 @@ identifies which region is associated with these notes. Appears at the start of the function body, after the function prologue. +@findex NOTE_INSN_DEBUG_FUNCTION_BEG +@item NOTE_INSN_DEBUG_FUNCTION_BEG +This NOTE is inserted at the start of a function during RTL expansion. +It is inserted at the point in a function where code coming directly from the +"users source" starts. i.e. the first insn that appears after this note should +be generated from the user code (and not from automatic code generation to +support compiler features). +This NOTE is used to ensure the first debug line number after the start of any +function is the line number of the first source code statement in that +function. GDB typically determines where to first stop in a function based on +this first line number entry. + @findex NOTE_INSN_VAR_LOCATION @findex NOTE_VAR_LOCATION @item NOTE_INSN_VAR_LOCATION diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 8d9a3849fa4289e246a10a66252667dd4c6e0f75..10d05cd51fc679cb4acfc85f76df415d1d9b1f0d 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -27807,7 +27807,7 @@ dwarf2out_source_line (unsigned int line, unsigned int column, as the end_prologue debug hook. The NOTE_INSN_PROLOGUE_END note, to which the hook corresponds, follows the last insn that was emitted by gen_prologue. What we need is to precede the first insn - that had been emitted after NOTE_INSN_FUNCTION_BEG, i.e. the first + that had been emitted after NOTE_INSN_DEBUG_FUNCTION_BEG, i.e. the first insn that corresponds to something the user wrote. These may be very different locations once scheduling is enabled. */ diff --git a/gcc/final.c b/gcc/final.c index 6dc1cd1b0c8c4bd764a7a77cd4ed6a1fe95603c0..c80e5878feae21696d26b69c9f3013ac186b7231 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -2165,7 +2165,7 @@ asm_show_source (const char *filename, int linenum) SEEN is used to track the end of the prologue, for emitting debug information. We force the emission of a line note after - both NOTE_INSN_PROLOGUE_END and NOTE_INSN_FUNCTION_BEG. */ + both NOTE_INSN_PROLOGUE_END and NOTE_INSN_DEBUG_FUNCTION_BEG. */ static rtx_insn * final_scan_insn_1 (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED, @@ -2299,6 +2299,9 @@ final_scan_insn_1 (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED, need_profile_function = false; } + break; + + case NOTE_INSN_DEBUG_FUNCTION_BEG: app_disable (); if (!DECL_IGNORED_P (current_function_decl)) debug_hooks->end_prologue (last_linenum, last_filename); diff --git a/gcc/function.c b/gcc/function.c index cec344bdac8cd59ebca0364a165147d25f1e95cf..9e5950d712b9cf3142ddb0fc24b1188ee28539a7 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -6069,7 +6069,8 @@ thread_prologue_and_epilogue_insns (void) { next = NEXT_INSN (insn); if (NOTE_P (insn) - && (NOTE_KIND (insn) == NOTE_INSN_FUNCTION_BEG)) + && ((NOTE_KIND (insn) == NOTE_INSN_FUNCTION_BEG) + || (NOTE_KIND (insn) == NOTE_INSN_DEBUG_FUNCTION_BEG))) reorder_insns (insn, insn, PREV_INSN (epilogue_seq)); } } diff --git a/gcc/insn-notes.def b/gcc/insn-notes.def index 337e9df8a75659cb73e4a9934842fa504b56a12e..2cb7f792fa45554b1379c265fabd86285da594a5 100644 --- a/gcc/insn-notes.def +++ b/gcc/insn-notes.def @@ -51,6 +51,12 @@ INSN_NOTE (BLOCK_END) their homes, etc. */ INSN_NOTE (FUNCTION_BEG) +/* This note indicates the start of user code. + This is different to FUNCTION_BEG above as FUNCTION_BEG is put before the + stack protection prologue, the code saving the stack location for nonlocal + gotos, and the code profiling code. */ +INSN_NOTE (DEBUG_FUNCTION_BEG) + /* This marks the point immediately after the last prologue insn. */ INSN_NOTE (PROLOGUE_END)