Message ID | VI1PR0801MB20140428B8AEB97CE5B7B750E0840@VI1PR0801MB2014.eurprd08.prod.outlook.com |
---|---|
State | New |
Headers | show |
Series | [RFC,Debug] Add new NOTE to be used for debugging. | expand |
Ping. (note -- when running the GDB testsuite ensuring that -fstack-protector-all is used for compiling each testcase, this patch fixes over 1500 FAIL's) On 10/01/19 13:28, Matthew Malcomson wrote: > At the moment NOTE_INSN_FUNCTION_BEG is used for three different purposes. > The first is as a marker just before the first insn coming from a > "source code statement" of the function. > Bug 88432 is due to the fact that the note does not accurately point to > this logical position in a function -- in that case the stack protect > prologue is directly after NOTE_INSN_FUNCTION_BEG. > > The second is (I believe) to make assumptions about what values are in the > parameter passing registers (in alias.c and calls.c). > (I'm not sure about this second use, if I am correctly reading this code then > it seems like a bug -- e.g. asan_emit_stack_protect inserts insns in the stream > that break the assumption that seems to be made.) > > The third is as a marker to determine where to put extra code later in > sjlj_emit_function_enter from except.c, where to insert profiling code for a > function in final.c, and where to insert variable expansion code in > pass_expand::execute from cfgexpand.c. > > These three uses seem to be at odds with each other -- insns that change the > values in the parameter passing registers store can come from automatically > inserted code like stack protection, and some requirements on where instructions > should get inserted have moved the position of this NOTE (e.g. see bugzilla bug > 81186). > > This patch splits the current note into two different notes, one to retain uses > 2 and 3 above, and one for use in genrating debug information. > > The first two uses are still attached to NOTE_INSN_FUNCTION_BEG, while the > debugging use is now implemented with NOTE_INSN_DEBUG_FUNCTION_BEG. > > These two notes are put into the functions' insn chain in different > places during the expand pass, and can hence satisfy their respective > uses. > > Bootstrapped and regtested on aarch64. > TODO -- Manual tests done on resulting debug information -- yet to be automated. > > gcc/ChangeLog: > > 2019-01-10 Matthew Malcomson <matthew.malcomson@arm.com> > > PR debug/88432 > * cfgexpand.c (pass_expand::execute): Insert > NOTE_INSN_DEBUG_FUNCTION_BEG. > * function.c (thread_prologue_and_epilogue_insns): Account > for NOTE_INSN_DEBUG_FUNCTION_BEG. > * cfgrtl.c (duplicate_insn_chain): Account for new NOTE. > * doc/rtl.texi: Document new NOTE. > * dwarf2out.c (dwarf2out_source_line): Change comment to > reference new NOTE. > * final.c (asm_show_source): As above. > (final_scan_insn_1): Split action on NOTE_INSN_FUNCTION_BEG into > two, and move debugging info action to trigger on > NOTE_INSN_DEBUG_FUNCTION_BEG. > * insn-notes.def (INSN_NOTE): Add new NOTE. > > > > ############### Attachment also inlined for ease of reply ############### > > > 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) > >
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)