From patchwork Fri Aug 12 19:13:30 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Malcolm X-Patchwork-Id: 658795 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3s9v2R29v3z9sR8 for ; Sat, 13 Aug 2016 04:45:02 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=UAx1nlDr; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:in-reply-to:references; q=dns; s= default; b=AImbcxTJW/3qByzzYGhqQFQ4MTw8GwQTwjxJAPRBpxp5H0e6ygexq bLEkUW6NAvtoznDAXxhNXBurW8k136lr5lPjqVmJizWPY/BYHwP330TQnFwp58jf XN5jWwo1e4ZA2+SXyd8/wCWg2Ibp3J4IN5xvf+VEpTjhCB00fT1ht4= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:in-reply-to:references; s= default; bh=6L95AzzCpeW7l6VmG0pQ2p3azaI=; b=UAx1nlDrZl6/Fy1wwWDR h/Py8Bi+3IbdWdlPLT+qdBdPWdUW4fCIoBuVTHksEytqUp6EeP5CW71hCQurv8zA IHyzFcjdfe9U+vafHWyQZCcIVwPscgIdLmUp/NUJntwrlPvmrjLRYQvTTn3JanMA s+CWWFXf0sr0gABb18GN5Fg= Received: (qmail 21267 invoked by alias); 12 Aug 2016 18:44:55 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 21250 invoked by uid 89); 12 Aug 2016 18:44:54 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=humans, highlevel, high-level, C11 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 12 Aug 2016 18:44:51 +0000 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 76BC19B0FA; Fri, 12 Aug 2016 18:44:50 +0000 (UTC) Received: from c64.redhat.com (vpn-228-250.phx2.redhat.com [10.3.228.250]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u7CIinBZ010830; Fri, 12 Aug 2016 14:44:49 -0400 From: David Malcolm To: Sandra Loosemore , gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [PATCH] Add source information to -fverbose-asm Date: Fri, 12 Aug 2016 15:13:30 -0400 Message-Id: <1471029210-47845-1-git-send-email-dmalcolm@redhat.com> In-Reply-To: <57AD2DC5.9000008@codesourcery.com> References: <57AD2DC5.9000008@codesourcery.com> X-IsSubscribed: yes On Thu, 2016-08-11 at 20:00 -0600, Sandra Loosemore wrote: > On 08/11/2016 02:34 PM, David Malcolm 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. > > > > 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? > > Why not extend the existing -fverbose-asm to do this? E.g. > -fverbose-asm=source, or something like that. Otherwise you need to > cross-reference the documentation for the two options and explain how > they interact (or don't interact, as the case may be). > > -Sandra Thanks. With the patch as-is, if I pass both -fverbose-asm and -fasm-show-source, I get the following: # test.c:7: int total = 0; xorl %eax, %eax # # test.c:9: for (i = 0; i < n; i++) xorl %edx, %edx # i .L2: # test.c:9: for (i = 0; i < n; i++) cmpl %edi, %edx # n, i jge .L5 #, # test.c:10: total += i * i; movl %edx, %ecx # i, tmp92 imull %edx, %ecx # i, tmp92 # test.c:9: for (i = 0; i < n; i++) incl %edx # i # test.c:10: total += i * i; addl %ecx, %eax # tmp92, jmp .L2 # .L5: # test.c:13: } ret .cfi_endproc I find the above pleasing, as it shows both the source, and the variable names associated with the asm insn arguments. The source line information works well with jump-to-source, in Emacs, at least. -fverbose-asm also adds some metadata to the top of the dump, that I wasn't interested in from a see-the-source point of view, but I can live with that. Currently -fverbose-asm is documented in common.opt as: "Add extra commentary to assembler output" and in invoke.texi as: @opindex fverbose-asm Put extra commentary information in the generated assembly code to make it more readable. This option is generally only of use to those who actually need to read the generated assembly code (perhaps while debugging the compiler itself). @option{-fno-verbose-asm}, the default, causes the extra information to be omitted and is useful when comparing two assembler files. Given that the precise output format for -fverbose-asm isn't documented, and it already can be thought of as our option for "make the asm readable please", my preference would be to extend it to print the source lines, without adding any "=source" complications: if the user was interested in the relationship of ins arguments to source expressions, they're likely also interested in seeing the corresponding source lines. Following is a rewritten version of the patch that does this, adding a description of the output to invoke.texi (along with a caveat that one should not try to parse the comments). OK for trunk if it survives bootstrap®ression testing? As mentioned before, I'd also like to make this more discoverable, by automatically adding the option in the driver if the user has specified asm output (via -S or via "-o something.s") - is this latter idea also reasonable? Dave gcc/ChangeLog: * doc/invoke.texi (fverbose-asm): Note that source code lines are emitted, and provide an example. * final.c (asm_show_source): New function. (final_scan_insn): Call asm_show_source. gcc/testsuite/ChangeLog: * gcc.dg/verbose-asm-2.c: New test case. --- gcc/doc/invoke.texi | 83 ++++++++++++++++++++++++++++++++++++ gcc/final.c | 28 +++++++++++- gcc/testsuite/gcc.dg/verbose-asm-2.c | 15 +++++++ 3 files changed, 124 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/verbose-asm-2.c diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 22001f9..f2f8931 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -11414,6 +11414,89 @@ debugging the compiler itself). extra information to be omitted and is useful when comparing two assembler files. +The added comments include: + +@itemize @bullet + +@item +information on the compiler version and command-line options, + +@item +the source code lines associated with the assembly instructions, +in the form FILENAME:LINENUMBER:CONTENT OF LINE, + +@item +hints on which high-level expressions correspond to +the various assembly instruction operands. + +@end itemize + +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 -fverbose-asm -Os -o - +@end smallexample + +gives output similar to this: + +@smallexample + .file "test.c" +# GNU C11 (GCC) version 7.0.0 20160809 (experimental) (x86_64-pc-linux-gnu) + [...snip...] +# options passed: + [...snip...] + + .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 # i +.L2: +# test.c:6: for (i = 0; i < n; i++) + cmpl %edi, %edx # n, i + jge .L5 #, +# test.c:7: total += i * i; + movl %edx, %ecx # i, tmp92 + imull %edx, %ecx # i, tmp92 +# test.c:6: for (i = 0; i < n; i++) + incl %edx # i +# test.c:7: total += i * i; + addl %ecx, %eax # tmp92, + 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 + +The comments are intended for humans rather than machines and hence the +precise format of the comments is subject to change. + @item -frecord-gcc-switches @opindex frecord-gcc-switches This switch causes the command line used to invoke the diff --git a/gcc/final.c b/gcc/final.c index 5b04311..eccc3d8 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -2140,6 +2140,26 @@ call_from_call_insn (rtx_call_insn *insn) return x; } +/* 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 +2583,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_verbose_asm) + 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/verbose-asm-2.c b/gcc/testsuite/gcc.dg/verbose-asm-2.c new file mode 100644 index 0000000..747bff1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/verbose-asm-2.c @@ -0,0 +1,15 @@ +/* Ensure that the -fverbose-asm leads to source code information in the generated asm. */ +/* { dg-options "-fverbose-asm" } */ + +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" } } */