On Fri, 2016-08-12 at 11:00 +0530, Prathamesh Kulkarni wrote: > On 12 August 2016 at 02:04, David Malcolm <dmalc...@redhat.com> > wrote: > > I sometimes find myself scouring assembler output from the compiler > > and trying to figure out which instructions correspond to which > > lines of source code; I believe this is a common activity for some > > end-users. > Hi David, > I usually use gcc -g -Wa,-adhln to trace C source from the assembly.
If I'm reading that right, you're using the GNU assembler to emit a listing file ("-a"), parsing the debuginfo with: "d": omit debugging directives "h": include high-level source "l": include assembly "n": omit forms processing > I tried your example and it gave more or less a similar output > (attached). Thanks. > However the source mapping with your patch looks better. One specific goal of the patch is that the source information is in a format that can be parsed by Emacs, and it can jump to the corresponding location in the source file. The do-it-in-gcc approach also doesn't rely on any smarts in the assembler. As Sandra noted, we already have -fverbose-asm, so I've posted an updated patch to add the source-printing to that option, rather than as a standalone option. Dave > Thanks, > Prathamesh > > > > The following patch adds a new -fasm-show-source option, which > > emits comments into the generated asm showing the pertinent > > line of source code, whenever it changes. It uses the same logic > > as debug_hooks->source_line for tracking this (for handling > > line-based breakpoints). > > > > An example can be seen in the invoke.texi part of the patch. As > > noted there, it's aimed at end-users, rather than gcc developers. > > The example shows a relatively short function; the option is > > likely to be much more useful for longer functions. > > > > I think it would further improve usability if this option were > > enabled > > by default when the final output is .s (either via -S, or by "-o > > foo.s"). > > Ideas on how to implement that (in the driver) would be welcome - I > > started looking at the spec-handling code, but thought I'd post the > > idea here first, before diving in too deeply. > > > > Successfully bootstrapped®rtested on x86_64-pc-linux-gnu; adds > > 2 PASS results to gcc.sum. > > > > Thoughts? OK for trunk as-is? > > > > gcc/ChangeLog: > > * common.opt (fasm-show-source): New option. > > * doc/invoke.texi (Code Generation Options): Add > > -fasm-show-source. > > (-fasm-show-source): New item. > > * final.c (asm_show_source): New function. > > (final_scan_insn): Call asm_show_source. > > > > gcc/testsuite/ChangeLog: > > * gcc.dg/fasm-show-source-1.c: New test case. > > --- > > gcc/common.opt | 5 +++ > > gcc/doc/invoke.texi | 71 > > ++++++++++++++++++++++++++++++- > > gcc/final.c | 29 ++++++++++++- > > gcc/testsuite/gcc.dg/fasm-show-source-1.c | 15 +++++++ > > 4 files changed, 117 insertions(+), 3 deletions(-) > > create mode 100644 gcc/testsuite/gcc.dg/fasm-show-source-1.c > > > > diff --git a/gcc/common.opt b/gcc/common.opt > > index 8a292ed..56ce513 100644 > > --- a/gcc/common.opt > > +++ b/gcc/common.opt > > @@ -939,6 +939,11 @@ fargument-noalias-anything > > Common Ignore > > Does nothing. Preserved for backward compatibility. > > > > +fasm-show-source > > +Common Var(flag_asm_show_source) > > +Emit comments in the generated assembly code to show the source > > code > > +lines associated with the assembly instructions. > > + > > fsanitize= > > Common Driver Report Joined > > Select what to sanitize. > > diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi > > index 22001f9..dc3d3ad 100644 > > --- a/gcc/doc/invoke.texi > > +++ b/gcc/doc/invoke.texi > > @@ -486,7 +486,8 @@ Objective-C and Objective-C++ Dialects}. > > > > @item Code Generation Options > > @xref{Code Gen Options,,Options for Code Generation Conventions}. > > -@gccoptlist{-fcall-saved-@var{reg} -fcall-used-@var{reg} @gol > > +@gccoptlist{-fasm-show-source @gol > > +-fcall-saved-@var{reg} -fcall-used-@var{reg} @gol > > -ffixed-@var{reg} -fexceptions @gol > > -fnon-call-exceptions -fdelete-dead-exceptions -funwind-tables > > @gol > > -fasynchronous-unwind-tables @gol > > @@ -11153,6 +11154,74 @@ can figure out the other form by either > > removing @samp{no-} or adding > > it. > > > > @table @gcctabopt > > +@item -fasm-show-source > > +@opindex fasm-show-source > > +Emit comments in the generated assembly code to show the source > > code > > +lines associated with the assembly instructions. This option is > > +aimed at end-users who wish to better understand the relationship > > +between their source code and the generated machine code. > > + > > +The comments are of the form FILENAME:LINENUMBER:CONTENT OF LINE. > > + > > +For example, given this C source file: > > + > > +@smallexample > > +int test (int n) > > +@{ > > + int i; > > + int total = 0; > > + > > + for (i = 0; i < n; i++) > > + total += i * i; > > + > > + return total; > > +@} > > +@end smallexample > > + > > +compiling to (x86_64) assembly via @option{-S} and emitting the > > result > > +direct to stdout via @option{-o} @option{-} > > + > > +@smallexample > > +gcc -S test.c -fasm-show-source -Os -o - > > +@end smallexample > > + > > +gives output similar to this, highlighting which instructions > > correspond > > +to the various parts of the loop: > > + > > +@smallexample > > + .file "test.c" > > + .text > > + .globl test > > + .type test, @@function > > +test: > > +.LFB0: > > + .cfi_startproc > > +# test.c:4: int total = 0; > > + xorl %eax, %eax > > +# test.c:6: for (i = 0; i < n; i++) > > + xorl %edx, %edx > > +.L2: > > +# test.c:6: for (i = 0; i < n; i++) > > + cmpl %edi, %edx > > + jge .L5 > > +# test.c:7: total += i * i; > > + movl %edx, %ecx > > + imull %edx, %ecx > > +# test.c:6: for (i = 0; i < n; i++) > > + incl %edx > > +# test.c:7: total += i * i; > > + addl %ecx, %eax > > + jmp .L2 > > +.L5: > > +# test.c:10: @} > > + ret > > + .cfi_endproc > > +.LFE0: > > + .size test, .-test > > + .ident "GCC: (GNU) 7.0.0 20160809 (experimental)" > > + .section .note.GNU-stack,"",@@progbits > > +@end smallexample > > + > > @item -fstack-reuse=@var{reuse-level} > > @opindex fstack_reuse > > This option controls stack space reuse for user declared > > local/auto variables > > diff --git a/gcc/final.c b/gcc/final.c > > index 5b04311..09bf0b7 100644 > > --- a/gcc/final.c > > +++ b/gcc/final.c > > @@ -2140,6 +2140,27 @@ call_from_call_insn (rtx_call_insn *insn) > > return x; > > } > > > > +/* Implementation of -fasm-show-source. > > + Print a comment into the asm showing FILENAME, LINENUM, and the > > + corresponding source line, if available. */ > > + > > +static void > > +asm_show_source (const char *filename, int linenum) > > +{ > > + if (!filename) > > + return; > > + > > + int line_size; > > + const char *line = location_get_source_line (filename, linenum, > > &line_size); > > + if (!line) > > + return; > > + > > + fprintf (asm_out_file, "%s %s:%i: ", ASM_COMMENT_START, > > filename, linenum); > > + /* "line" is not 0-terminated, so we must use line_size. */ > > + fwrite (line, 1, line_size, asm_out_file); > > + fputc ('\n', asm_out_file); > > +} > > + > > /* The final scan for one insn, INSN. > > Args are same as in `final', except that INSN > > is the insn being scanned. > > @@ -2563,8 +2584,12 @@ final_scan_insn (rtx_insn *insn, FILE *file, > > int optimize_p ATTRIBUTE_UNUSED, > > note in a row. */ > > if (!DECL_IGNORED_P (current_function_decl) > > && notice_source_line (insn, &is_stmt)) > > - (*debug_hooks->source_line) (last_linenum, last_filename, > > - last_discriminator, > > is_stmt); > > + { > > + if (flag_asm_show_source) > > + asm_show_source (last_filename, last_linenum); > > + (*debug_hooks->source_line) (last_linenum, > > last_filename, > > + last_discriminator, > > is_stmt); > > + } > > > > if (GET_CODE (body) == PARALLEL > > && GET_CODE (XVECEXP (body, 0, 0)) == ASM_INPUT) > > diff --git a/gcc/testsuite/gcc.dg/fasm-show-source-1.c > > b/gcc/testsuite/gcc.dg/fasm-show-source-1.c > > new file mode 100644 > > index 0000000..3dd49e0 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.dg/fasm-show-source-1.c > > @@ -0,0 +1,15 @@ > > +/* Ensure that the generated asm contains FIXME */ > > +/* { dg-options "-fasm-show-source" } */ > > + > > +int test (int n) > > +{ > > + int i; > > + int total = 0; > > + > > + for (i = 0; i < n; i++) > > + total += i * i; > > + > > + return total; > > +} > > + > > +/* { dg-final { scan-assembler "total = 0" } } */ > > -- > > 1.8.5.3 > >