diff mbox

RFA: Enhance information recorded by -frecord-gcc-switches

Message ID 8737baq1g2.fsf@redhat.com
State New
Headers show

Commit Message

Nick Clifton June 8, 2017, 9:21 a.m. UTC
Hi Guys,

  The -frecord-gcc-switches option records the gcc command line.  It
  does not however expand options like -O2 into the optimizations that
  this enables.  Thus if a user wants to know if a specific optimization
  was used when creating an object file, (or library or executable),
  they will have to reverse engineer the compilation process.  Which may
  or may not be possible.

  The attached patch is a proposal to address this problem by making
  -frecord-gcc-switches also record all the enabled options.  This does
  make object files bigger, but this cannot be helped.  The enhancement
  is not enabled by default however, instead a second command line
  option must be used.  In a possibly contentious move I chose to reuse
  the -fverbose-asm option, rather than creating a new one.  I did this
  because a) it simplifies the patch, b) we have more than enough switch
  recording options already, c) it does not conflict with the current
  use of -fverbose-asm and d) it ties in nicely with the name of the
  option.

  Tested, with no regressions on an x86_64-pc-linux-gnu target, and
  built for a variety of other targets.

  OK to apply ?

Cheers
  Nick

gcc/ChangeLog
2017-06-08  Nick Clifton  <nickc@redhat.com>

	* varasm.c (dump_enabled_to_asm_out_file): New function.  Prints
	enabled options to the asm_out_file.
	(elf_record_gcc_switches): If verbose-asm is set then also dump
	all enabled options to the asm file.
	* toplec.c (print_switch_values): Convert from static to global.
	* doc/invoke.texi (-fverbose-asm): Mention its effect on the
	-frecord-gcc-switches option.
	(-frecord-gcc-switches): Refactor the description and add details
	of how -fverbose-asm modifies its behaviour.

Comments

Richard Biener June 8, 2017, 9:43 a.m. UTC | #1
On Thu, Jun 8, 2017 at 11:21 AM, Nick Clifton <nickc@redhat.com> wrote:
> Hi Guys,
>
>   The -frecord-gcc-switches option records the gcc command line.  It
>   does not however expand options like -O2 into the optimizations that
>   this enables.  Thus if a user wants to know if a specific optimization
>   was used when creating an object file, (or library or executable),
>   they will have to reverse engineer the compilation process.  Which may
>   or may not be possible.
>
>   The attached patch is a proposal to address this problem by making
>   -frecord-gcc-switches also record all the enabled options.  This does
>   make object files bigger, but this cannot be helped.  The enhancement
>   is not enabled by default however, instead a second command line
>   option must be used.  In a possibly contentious move I chose to reuse
>   the -fverbose-asm option, rather than creating a new one.  I did this
>   because a) it simplifies the patch, b) we have more than enough switch
>   recording options already, c) it does not conflict with the current
>   use of -fverbose-asm and d) it ties in nicely with the name of the
>   option.
>
>   Tested, with no regressions on an x86_64-pc-linux-gnu target, and
>   built for a variety of other targets.
>
>   OK to apply ?

I think individually enabled passes by -On are not really useful information
as you generally cannot replace -On by a set of other switches on the
command-line.

Richard.

> Cheers
>   Nick
>
> gcc/ChangeLog
> 2017-06-08  Nick Clifton  <nickc@redhat.com>
>
>         * varasm.c (dump_enabled_to_asm_out_file): New function.  Prints
>         enabled options to the asm_out_file.
>         (elf_record_gcc_switches): If verbose-asm is set then also dump
>         all enabled options to the asm file.
>         * toplec.c (print_switch_values): Convert from static to global.
>         * doc/invoke.texi (-fverbose-asm): Mention its effect on the
>         -frecord-gcc-switches option.
>         (-frecord-gcc-switches): Refactor the description and add details
>         of how -fverbose-asm modifies its behaviour.
>
Nick Clifton June 8, 2017, 2:30 p.m. UTC | #2
Hi Richard,

>>    The -frecord-gcc-switches option records the gcc command line.  It
>>    does not however expand options like -O2 into the optimizations that
>>    this enables.

> 
> I think individually enabled passes by -On are not really useful information
> as you generally cannot replace -On by a set of other switches on the
> command-line.

Is that true ?  I always thought that -O2 could be duplicated by using a (very
long) set of individual command line options.

Regardless, the point of this patch is to record which options were enabled, via
whatever route, in the binaries.  This can be useful to users, or distributors,
who want to check that, for example, a specific security option was enabled, or
that a particular a particular optimization was run.

Cheers
  Nick
Jakub Jelinek June 8, 2017, 3:19 p.m. UTC | #3
On Thu, Jun 08, 2017 at 03:30:07PM +0100, Nick Clifton wrote:
> Hi Richard,
> 
> >>    The -frecord-gcc-switches option records the gcc command line.  It
> >>    does not however expand options like -O2 into the optimizations that
> >>    this enables.
> 
> > 
> > I think individually enabled passes by -On are not really useful information
> > as you generally cannot replace -On by a set of other switches on the
> > command-line.
> 
> Is that true ?  I always thought that -O2 could be duplicated by using a (very
> long) set of individual command line options.

It can't.  Various decisions in the compiler are based on the optimize
argument itself, the most important is of course that for optimize == 0 or
optimize_debug the pass queue is significantly different, with hundreds of
optimization passes not being run even if they are enabled, but there are
also optimize >= 2 or optimize >= 3 or optimize_size etc. guarded decisions
in many places.  So, with -O0 + all options that appear to be enabled by -O1
you still get something that is significantly closer to -O0 than -O1.
And even with -O1 + all options that appear to be enabled by -O2 but not
-O1, you still get something very different from -O2, etc.

> Regardless, the point of this patch is to record which options were enabled, via
> whatever route, in the binaries.  This can be useful to users, or distributors,
> who want to check that, for example, a specific security option was enabled, or
> that a particular a particular optimization was run.

And that again doesn't tell you whether the particular optimization pass was
run, just that some flag variable was zero or non-zero or had some other
value.  The decisions in the compiler are more complex and keep changing
between compiler versions.  For one particular compiler version, -O2 vs. -O1
if that is what was originally used to compile something is all you need,
that implies a particular behavior, set of options and their interactions.
For comparisons between different compiler versions, some of the options
are ignored, others are added, others change meaning, and expanding the list
of guarded options isn't really useful.

	Jakub
Nick Clifton June 8, 2017, 4:05 p.m. UTC | #4
Hi Jakub,


>> Regardless, the point of this patch is to record which options were enabled, via
>> whatever route, in the binaries.  This can be useful to users, or distributors,
>> who want to check that, for example, a specific security option was enabled, or
>> that a particular a particular optimization was run.
> 
> And that again doesn't tell you whether the particular optimization pass was
> run, just that some flag variable was zero or non-zero or had some other
> value.  The decisions in the compiler are more complex and keep changing
> between compiler versions.  For one particular compiler version, -O2 vs. -O1
> if that is what was originally used to compile something is all you need,
> that implies a particular behavior, set of options and their interactions.
> For comparisons between different compiler versions, some of the options
> are ignored, others are added, others change meaning, and expanding the list
> of guarded options isn't really useful.

OK -so we need some other way of recording what optimization passes were actually 
run.  Fortunately I have something in mind.

Patch withdrawn.

Cheers
  Nick
Jakub Jelinek June 9, 2017, 9:03 a.m. UTC | #5
On Thu, Jun 08, 2017 at 05:05:15PM +0100, Nick Clifton wrote:
> >> Regardless, the point of this patch is to record which options were enabled, via
> >> whatever route, in the binaries.  This can be useful to users, or distributors,
> >> who want to check that, for example, a specific security option was enabled, or
> >> that a particular a particular optimization was run.
> > 
> > And that again doesn't tell you whether the particular optimization pass was
> > run, just that some flag variable was zero or non-zero or had some other
> > value.  The decisions in the compiler are more complex and keep changing
> > between compiler versions.  For one particular compiler version, -O2 vs. -O1
> > if that is what was originally used to compile something is all you need,
> > that implies a particular behavior, set of options and their interactions.
> > For comparisons between different compiler versions, some of the options
> > are ignored, others are added, others change meaning, and expanding the list
> > of guarded options isn't really useful.
> 
> OK -so we need some other way of recording what optimization passes were actually 
> run.  Fortunately I have something in mind.
> 
> Patch withdrawn.

Then there is the question of what it means an optimization pass was
actually run?  Some passes have all the checks in gate, but other passes
perform further early checks and bail out early in the execute method, or
the pass only operates on selected kind of statements that might be missing
from the IL in certain functions.  So it really would be nice to see what
information the reporter is looking for and what they want to use it for.

	Jakub
diff mbox

Patch

Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi	(revision 249007)
+++ gcc/doc/invoke.texi	(working copy)
@@ -12281,10 +12281,13 @@ 
 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.
+This switch can also be used to modify the behaviour of the
+@option{-frecord-gcc-switches} switch, making it record extra
+information in the object file.
 
+@option{-fno-verbose-asm}, the default, causes the extra information
+to be omitted and is useful when comparing two assembler files.
+
 The added comments include:
 
 @itemize @bullet
@@ -12370,17 +12373,26 @@ 
 
 @item -frecord-gcc-switches
 @opindex frecord-gcc-switches
-This switch causes the command line used to invoke the
-compiler to be recorded into the object file that is being created.
-This switch is only implemented on some targets and the exact format
-of the recording is target and binary file format dependent, but it
-usually takes the form of a section containing ASCII text.  This
-switch is related to the @option{-fverbose-asm} switch, but that
-switch only records information in the assembler output file as
-comments, so it never reaches the object file.
-See also @option{-grecord-gcc-switches} for another
-way of storing compiler options into the object file.
+This switch causes the command line used to invoke the compiler to be
+recorded into the object file that is being created.  This switch is
+only implemented on some targets and the exact format of the recording
+is target and binary file format dependent, but it usually takes the
+form of a section containing ASCII text.
 
+The related switch @option{-fverbose-asm} switch performs a similar
+task but it only records the information in the assembler output file
+as comments, so it never reaches the object file.
+
+If both @option{-fverbose-asm} and @option{-frecord-gcc-switches} are
+enabled together then @option{-frecord-gcc-switches} will record all
+enabled switches, not just those specified on the command line.  Thus
+if the command line includes @option{-O2} then all optimizations
+enabled by that switch will be recorded in the object file, along with
+the presence of @option{-O2} itself.
+
+See also @option{-grecord-gcc-switches} for another way of storing
+compiler options into an object file.
+
 @item -fpic
 @opindex fpic
 @cindex global offset table
Index: gcc/toplev.c
===================================================================
--- gcc/toplev.c	(revision 249007)
+++ gcc/toplev.c	(working copy)
@@ -809,7 +809,9 @@ 
    Each line begins with INDENT and ends with TERM.
    Each switch is separated from the next by SEP.  */
 
-static void
+void print_switch_values (print_switch_fn_type);
+
+void
 print_switch_values (print_switch_fn_type print_fn)
 {
   int pos = 0;
Index: gcc/varasm.c
===================================================================
--- gcc/varasm.c	(revision 249007)
+++ gcc/varasm.c	(working copy)
@@ -7545,6 +7545,32 @@ 
   v.release ();
 }
 
+/* Print TEXT to asm_out_file if TYPE is an enabled switch.
+   Returns the number of characters printed or -1 upon failure.  */
+
+static int
+dump_enabled_to_asm_out_file (print_switch_type type, const char * text)
+{
+  switch (type)
+    {
+    case SWITCH_TYPE_LINE_END:
+    case SWITCH_TYPE_LINE_START:
+    case SWITCH_TYPE_DESCRIPTIVE:
+      return 0;
+
+    case SWITCH_TYPE_PASSED:
+    case SWITCH_TYPE_ENABLED:
+      ASM_OUTPUT_ASCII (asm_out_file, text, strlen (text));
+      ASM_OUTPUT_SKIP (asm_out_file, (unsigned HOST_WIDE_INT) 1);
+       /* No need to return the length here as
+	 print_single_switch has already done it.  */
+      return strlen (text) + 1;
+
+    default:
+      return -1;
+    }
+}
+
 /* This function provides a possible implementation of the
    TARGET_ASM_RECORD_GCC_SWITCHES target hook for ELF targets.  When triggered
    by -frecord-gcc-switches it creates a new mergeable, string section in the
@@ -7586,6 +7612,14 @@ 
 				 NULL);
 	      switch_to_section (sec);
 	      started = true;
+
+	      if (flag_verbose_asm)
+		{
+		  extern void print_switch_values (print_switch_fn_type);
+
+		  print_switch_values (dump_enabled_to_asm_out_file);
+		  putc ('\n', asm_out_file);
+		}
 	    }
 	}