On 11/20/20 10:49 AM, Richard Biener wrote:
On Fri, Apr 3, 2020 at 8:15 PM Egeyar Bagcioglu
<egeyar.bagcio...@oracle.com> wrote:
On 3/18/20 10:05 AM, Martin Liška wrote:
On 3/17/20 7:43 PM, Egeyar Bagcioglu wrote:
Hi Martin,
I like the patch. It definitely serves our purposes at Oracle and
provides another way to do what my previous patches did as well.
1) It keeps the backwards compatibility regarding
-frecord-gcc-switches; therefore, removes my related doubts about
your previous patch.
2) It still makes use of -frecord-gcc-switches. The new option is
only to control the format. This addresses some previous objections
to having a new option doing something similar. Now the new option
controls the behaviour of the existing one and that behaviour can be
further extended.
3) It uses an environment variable as Jakub suggested.
The patch looks good and I confirm that it works for our purposes.
Hello.
Thank you for the support.
Having said that, I have to ask for recognition in this patch for my
and my company's contributions. Can you please keep my name and my
work email in the changelog and in the commit message?
Sure, sorry I forgot.
Hi Martin,
I noticed that some comments in the patch were still referring to
--record-gcc-command-line, the option I suggested earlier. I updated
those comments to mention -frecord-gcc-switches-format instead and also
added my name to the patch as you agreed above. I attached the updated
patch. We are starting to use this patch in the specific domain where we
need its functionality.
So while I like the addition of -frecord-gcc-switches-format to preserve
backward compatibility there are IMHO several issues with the patch.
Hey.
For one, the target hook change to a void(void) hook makes it need to
duplicate too much internals. Please make it take a const char *
argument, the actual text to output.
Agree with that, nice improvement.
For second, I see no good reason to have different handling of
-grecord-gcc-switches vs. -frecord-gcc-switches - they should
produce the same content and thus -frecord-gcc-switches-format
should apply to -grecord-gcc-switches as well.
They do. Both respect the newly added -frecord-gcc-switches-format argument.
Now - I think what we output into the assembly file with -fverbose-asm
should _always_ be the processed arguments since the assembly
is produced by cc1, not gcc.
All right, changed that.
+/* Return value of env variable GCC_DRIVER_COMMAND_LINE if exists.
+ Otherwise return empty string. */
+
+const char *
+get_driver_command_line ()
+{
+ const char *cmdline = getenv ("GCC_DRIVER_COMMAND_LINE");
+ return cmdline != NULL ? cmdline : "";
+}
I think silently emitting nothing is not a good idea. In particular using
the environment to carry the driver command-line makes it difficult
to reproduce output with pasting commands as dumped by -v [-save-temps].
Likewise the driver seems to always populate GCC_DRIVER_COMMAND_LINE
even if not needed - why not look for -frecord-gcc-switches-format before
doing so? I'd make -frecord-gcc-switches-format a driver only option
(only the driver can do sth about it) and amend -frecord-gcc-switches
with a -frecord-gcc-switches=FILE variant specifying the content. The
driver would then substitute -frecord-gcc-switches-format=driver
with -frecord-gcc-switches=tempfile and dump the command line into
tempfile. cc1 can then pick contents from tempfile or use the processed
variant if no contents are specified.
I've just rewritten that to -frecord-gcc-switches-file option. Note that
we can't transform that to -frecord-gcc-switches=FILE as one can use:
-g frecord-gcc-switches-format=driver and so -frecord-gcc-switches is off.
Thoughts on the new version of the patch?
Thanks,
Martin
Richard.
Regards
Egeyar
Martin
Thanks
Egeyar
On 3/17/20 2:53 PM, Martin Liška wrote:
Hi.
I'm sending enhanced patch that makes the following changes:
- a new option -frecord-gcc-switches-format is added; the option
selects format (processed, driver) for all options that record
GCC command line
- Dwarf gen_produce_string is now used in -fverbose-asm
- The .s file is affected in the following way:
BEFORE:
# GNU C17 (SUSE Linux) version 9.2.1 20200128 [revision
83f65674e78d97d27537361de1a9d74067ff228d] (x86_64-suse-linux)
# compiled by GNU C version 9.2.1 20200128 [revision
83f65674e78d97d27537361de1a9d74067ff228d], GMP version 6.2.0, MPFR
version 4.0.2, MPC version 1.1.0, isl version isl-0.22.1-GMP
# GGC heuristics: --param ggc-min-expand=100 --param
ggc-min-heapsize=131072
# options passed: -fpreprocessed test.i -march=znver1 -mmmx -mno-3dnow
# -msse -msse2 -msse3 -mssse3 -msse4a -mcx16 -msahf -mmovbe -maes -msha
# -mpclmul -mpopcnt -mabm -mno-lwp -mfma -mno-fma4 -mno-xop -mbmi
-mno-sgx
# -mbmi2 -mno-pconfig -mno-wbnoinvd -mno-tbm -mavx -mavx2 -msse4.2
-msse4.1
# -mlzcnt -mno-rtm -mno-hle -mrdrnd -mf16c -mfsgsbase -mrdseed -mprfchw
# -madx -mfxsr -mxsave -mxsaveopt -mno-avx512f -mno-avx512er
-mno-avx512cd
# -mno-avx512pf -mno-prefetchwt1 -mclflushopt -mxsavec -mxsaves
# -mno-avx512dq -mno-avx512bw -mno-avx512vl -mno-avx512ifma
-mno-avx512vbmi
# -mno-avx5124fmaps -mno-avx5124vnniw -mno-clwb -mmwaitx -mclzero
-mno-pku
# -mno-rdpid -mno-gfni -mno-shstk -mno-avx512vbmi2 -mno-avx512vnni
# -mno-vaes -mno-vpclmulqdq -mno-avx512bitalg -mno-movdiri
-mno-movdir64b
# -mno-waitpkg -mno-cldemote -mno-ptwrite --param l1-cache-size=32
# --param l1-cache-line-size=64 --param l2-cache-size=512 -mtune=znver1
# -grecord-gcc-switches -g -fverbose-asm -frecord-gcc-switches
# options enabled: -faggressive-loop-optimizations -fassume-phsa
# -fasynchronous-unwind-tables -fauto-inc-dec -fcommon
# -fdelete-null-pointer-checks -fdwarf2-cfi-asm -fearly-inlining
# -feliminate-unused-debug-types -ffp-int-builtin-inexact
-ffunction-cse
# -fgcse-lm -fgnu-runtime -fgnu-unique -fident -finline-atomics
# -fipa-stack-alignment -fira-hoist-pressure -fira-share-save-slots
# -fira-share-spill-slots -fivopts -fkeep-static-consts
# -fleading-underscore -flifetime-dse -flto-odr-type-merging
-fmath-errno
# -fmerge-debug-strings -fpeephole -fplt -fprefetch-loop-arrays
# -frecord-gcc-switches -freg-struct-return
-fsched-critical-path-heuristic
# -fsched-dep-count-heuristic -fsched-group-heuristic
-fsched-interblock
# -fsched-last-insn-heuristic -fsched-rank-heuristic -fsched-spec
# -fsched-spec-insn-heuristic -fsched-stalled-insns-dep
-fschedule-fusion
# -fsemantic-interposition -fshow-column -fshrink-wrap-separate
# -fsigned-zeros -fsplit-ivs-in-unroller -fssa-backprop -fstdarg-opt
# -fstrict-volatile-bitfields -fsync-libcalls -ftrapping-math
-ftree-cselim
# -ftree-forwprop -ftree-loop-if-convert -ftree-loop-im
-ftree-loop-ivcanon
# -ftree-loop-optimize -ftree-parallelize-loops= -ftree-phiprop
# -ftree-reassoc -ftree-scev-cprop -funit-at-a-time -funwind-tables
# -fverbose-asm -fzero-initialized-in-bss -m128bit-long-double -m64
-m80387
# -mabm -madx -maes -malign-stringops -mavx -mavx2
# -mavx256-split-unaligned-store -mbmi -mbmi2 -mclflushopt -mclzero
-mcx16
# -mf16c -mfancy-math-387 -mfma -mfp-ret-in-387 -mfsgsbase -mfxsr
-mglibc
# -mieee-fp -mlong-double-80 -mlzcnt -mmmx -mmovbe -mmwaitx -mpclmul
# -mpopcnt -mprfchw -mpush-args -mrdrnd -mrdseed -mred-zone -msahf
-msha
# -msse -msse2 -msse3 -msse4 -msse4.1 -msse4.2 -msse4a -mssse3 -mstv
# -mtls-direct-seg-refs -mvzeroupper -mxsave -mxsavec -mxsaveopt
-mxsaves
AFTER:
# GGC heuristics: --param ggc-min-expand=30 --param
ggc-min-heapsize=4096
# GNU C17 10.0.1 20200317 (experimental) -march=znver1 -mmmx
-mno-3dnow -msse -msse2 -msse3 -mssse3 -msse4a -mcx16 -msahf -mmovbe
-maes -msha -mpclmul -mpopcnt -mabm -mno-lwp -mfma -mno-fma4
-mno-xop -mbmi -mno-sgx -mbmi2 -mno-pconfig -mno-wbnoinvd -mno-tbm
-mavx -mavx2 -msse4.2 -msse4.1 -mlzcnt -mno-rtm -mno-hle -mrdrnd
-mf16c -mfsgsbase -mrdseed -mprfchw -madx -mfxsr -mxsave -mxsaveopt
-mno-avx512f -mno-avx512er -mno-avx512cd -mno-avx512pf
-mno-prefetchwt1 -mclflushopt -mxsavec -mxsaves -mno-avx512dq
-mno-avx512bw -mno-avx512vl -mno-avx512ifma -mno-avx512vbmi
-mno-avx5124fmaps -mno-avx5124vnniw -mno-clwb -mmwaitx -mclzero
-mno-pku -mno-rdpid -mno-gfni -mno-shstk -mno-avx512vbmi2
-mno-avx512vnni -mno-vaes -mno-vpclmulqdq -mno-avx512bitalg
-mno-movdiri -mno-movdir64b -mno-waitpkg -mno-cldemote -mno-ptwrite
-mno-avx512bf16 -mno-enqcmd -mno-avx512vp2intersect
--param=l1-cache-size=32 --param=l1-cache-line-size=64
--param=l2-cache-size=512 -mtune=znver1 -g
That's the biggest change I made, but I hope it's acceptable.
Apart from that the patch simplifies and unifies places where
save_decoded_options
options are transformed back to string representation.
Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
Ready to be installed in next stage1?
Thanks,
Martin
>From b0e9bd2a625d06417fb2b52d04a824f33aba633c Mon Sep 17 00:00:00 2001
From: Martin Liska <mli...@suse.cz>
Date: Thu, 5 Mar 2020 09:39:17 +0100
Subject: [PATCH] Change semantics of -frecord-gcc-switches and add
-frecord-gcc-switches-format.
gcc/ChangeLog:
2020-03-17 Martin Liska <mli...@suse.cz>
Egeyar Bagcioglu <egeyar.bagcio...@oracle.com>
* common.opt: Document new options -frecord-gcc-switches-format
and -frecord-gcc-switches-file.
* doc/invoke.texi: Document the new options.
* doc/tm.texi: Remove documentation of the print_switch_type
enum value.
* dwarf2out.c (dwarf2out_early_finish): Respect
flag_record_gcc_switches_format.
* flag-types.h (enum record_gcc_switches_format): New.
* gcc.c (save_driver_cmdline): Save command line to a temporary
file.
(driver::main): Call set_commandline.
(driver::set_commandline): New.
* gcc.h (set_commandline): New.
* opts.c (get_producer_string): New function.
(get_driver_command_line): Likewise.
* opts.h (get_producer_string): New.
(get_driver_command_line): New.
* target.def: Change argument of record_gcc_switches to a string
that is printed to a file.
* target.h (enum print_switch_type): Remove.
(elf_record_gcc_switches): Change argument of the function
* toplev.c (MAX_LINE): Remove.
(print_to_asm_out_file): Remove.
(print_to_stderr): Likewise.
(print_single_switch): Likewise.
(print_switch_values): Likewise.
(init_asm_output): Use new function get_producer_string.
(process_options): Respect flag_record_gcc_switches_format
option.
* varasm.c (elf_record_gcc_switches): Simplify hook by just
printing the argument passed.
---
gcc/common.opt | 19 ++++-
gcc/doc/invoke.texi | 23 +++++-
gcc/doc/tm.texi | 38 +--------
gcc/dwarf2out.c | 15 +++-
gcc/flag-types.h | 7 ++
gcc/gcc.c | 37 ++++++++-
gcc/gcc.h | 1 +
gcc/opts.c | 139 ++++++++++++++++++++++++++++++++
gcc/opts.h | 6 ++
gcc/target.def | 38 +--------
gcc/target.h | 14 +---
gcc/toplev.c | 187 +++++++-------------------------------------
gcc/varasm.c | 48 +++---------
13 files changed, 287 insertions(+), 285 deletions(-)
diff --git a/gcc/common.opt b/gcc/common.opt
index ca8a2690799..a29735db669 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -2322,9 +2322,26 @@ Common Joined RejectNegative Var(common_deferred_options) Defer
; records information in the assembler output file as comments, so
; they never reach the object file.
frecord-gcc-switches
-Common Report Var(flag_record_gcc_switches)
+Common Driver Report Var(flag_record_gcc_switches)
Record gcc command line switches in the object file.
+Enum
+Name(record_gcc_switches_format) Type(enum record_gcc_switches_format)
+
+EnumValue
+Enum(record_gcc_switches_format) String(processed) Value(RECORD_GCC_SWITCHES_PROCESSED)
+
+EnumValue
+Enum(record_gcc_switches_format) String(driver) Value(RECORD_GCC_SWITCHES_DRIVER)
+
+frecord-gcc-switches-format=
+Common Report Joined RejectNegative Var(flag_record_gcc_switches_format) Enum(record_gcc_switches_format) Init(RECORD_GCC_SWITCHES_PROCESSED)
+-frecord-gcc-switches-format=[processed|driver] Format of recorded gcc command line switches.
+
+frecord-gcc-switches-file=
+Common Report Joined RejectNegative Var(flag_record_gcc_switches_file) Undocumented
+Path to file test.
+
freg-struct-return
Common Report Var(flag_pcc_struct_return,0) Optimization
Return small aggregates in registers.
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 26372a2435a..d7e43c84ffc 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -642,7 +642,7 @@ Objective-C and Objective-C++ Dialects}.
-finhibit-size-directive -fcommon -fno-ident @gol
-fpcc-struct-return -fpic -fPIC -fpie -fPIE -fno-plt @gol
-fno-jump-tables -fno-bit-tests @gol
--frecord-gcc-switches @gol
+-frecord-gcc-switches -frecord-gcc-switches-format @gol
-freg-struct-return -fshort-enums -fshort-wchar @gol
-fverbose-asm -fpack-struct[=@var{n}] @gol
-fleading-underscore -ftls-model=@var{model} @gol
@@ -16022,6 +16022,27 @@ 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.
+@item -frecord-gcc-switches-format=@var{format}
+@opindex frecord-gcc-switches-format
+This switch controls the output format of options that record
+the command line. The affected options are @option{-frecord-gcc-switches},
+@option{-grecord-gcc-switches} and @option{-fverbose-asm}.
+
+The @var{format} argument should be one of the following:
+
+@table @samp
+
+@item processed
+
+Options are printed after processing by the compiler driver.
+It is the default option value.
+
+@item driver
+
+Options are printed as provided to the compiler driver.
+
+@end table
+
@item -fpic
@opindex fpic
@cindex global offset table
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 2b88f78944f..baee63a3700 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -8077,43 +8077,9 @@ need to override this if your target has special flags that might be
set via @code{__attribute__}.
@end deftypefn
-@deftypefn {Target Hook} int TARGET_ASM_RECORD_GCC_SWITCHES (print_switch_type @var{type}, const char *@var{text})
+@deftypefn {Target Hook} void TARGET_ASM_RECORD_GCC_SWITCHES (const char *@var{})
Provides the target with the ability to record the gcc command line
-switches that have been passed to the compiler, and options that are
-enabled. The @var{type} argument specifies what is being recorded.
-It can take the following values:
-
-@table @gcctabopt
-@item SWITCH_TYPE_PASSED
-@var{text} is a command line switch that has been set by the user.
-
-@item SWITCH_TYPE_ENABLED
-@var{text} is an option which has been enabled. This might be as a
-direct result of a command line switch, or because it is enabled by
-default or because it has been enabled as a side effect of a different
-command line switch. For example, the @option{-O2} switch enables
-various different individual optimization passes.
-
-@item SWITCH_TYPE_DESCRIPTIVE
-@var{text} is either NULL or some descriptive text which should be
-ignored. If @var{text} is NULL then it is being used to warn the
-target hook that either recording is starting or ending. The first
-time @var{type} is SWITCH_TYPE_DESCRIPTIVE and @var{text} is NULL, the
-warning is for start up and the second time the warning is for
-wind down. This feature is to allow the target hook to make any
-necessary preparations before it starts to record switches and to
-perform any necessary tidying up after it has finished recording
-switches.
-
-@item SWITCH_TYPE_LINE_START
-This option can be ignored by this target hook.
-
-@item SWITCH_TYPE_LINE_END
-This option can be ignored by this target hook.
-@end table
-
-The hook's return value must be zero. Other return values may be
-supported in the future.
+switches provided as argument.
By default this hook is set to NULL, but an example implementation is
provided for ELF based targets. Called @var{elf_record_gcc_switches},
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 01e7ae183d5..8e13ef00083 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -32145,7 +32145,20 @@ dwarf2out_early_finish (const char *filename)
header compilation, so always fill it with empty string initially
and overwrite only here. */
dw_attr_node *producer = get_AT (comp_unit_die (), DW_AT_producer);
- producer_string = gen_producer_string ();
+ producer_string = concat (lang_hooks.name, " ", version_string, NULL);
+
+ if (dwarf_record_gcc_switches)
+ {
+ char *producer_string_old = producer_string;
+ if (flag_record_gcc_switches_format == RECORD_GCC_SWITCHES_DRIVER)
+ producer_string = concat (producer_string, " ",
+ get_driver_command_line (), NULL);
+ else
+ producer_string = get_producer_string (lang_hooks.name,
+ save_decoded_options,
+ save_decoded_options_count);
+ free (producer_string_old);
+ }
producer->dw_attr_val.v.val_str->refcount--;
producer->dw_attr_val.v.val_str = find_AT_string (producer_string);
diff --git a/gcc/flag-types.h b/gcc/flag-types.h
index 0dbab19943c..fa46de9e9bf 100644
--- a/gcc/flag-types.h
+++ b/gcc/flag-types.h
@@ -424,6 +424,13 @@ enum openacc_kernels
OPENACC_KERNELS_PARLOOPS
};
+/* Record GCC options type. */
+enum record_gcc_switches_format
+{
+ RECORD_GCC_SWITCHES_PROCESSED = 0,
+ RECORD_GCC_SWITCHES_DRIVER
+};
+
#endif
#endif /* ! GCC_FLAG_TYPES_H */
diff --git a/gcc/gcc.c b/gcc/gcc.c
index d78b5f582b5..a13e26c0c9f 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -235,6 +235,12 @@ static int verbose_only_flag;
static int print_subprocess_help;
+/* argc and argv provided to the driver. Necessary to keep for when
+ -frecord-gcc-switches-format=driver is given. */
+
+static unsigned int driver_gcc_argc;
+static const char **driver_gcc_argv;
+
/* Linker suffix passed to -fuse-ld=... */
static const char *use_ld;
@@ -433,6 +439,7 @@ static const char *greater_than_spec_func (int, const char **);
static const char *debug_level_greater_than_spec_func (int, const char **);
static const char *dwarf_version_greater_than_spec_func (int, const char **);
static const char *find_fortran_preinclude_file (int, const char **);
+static const char *save_driver_cmdline (int, const char **);
static char *convert_white_space (char *);
static char *quote_spec (char *);
static char *quote_spec_arg (char *);
@@ -1255,7 +1262,9 @@ static const char *cc1_options =
%{coverage:-fprofile-arcs -ftest-coverage}\
%{fprofile-arcs|fprofile-generate*|coverage:\
%{!fprofile-update=single:\
- %{pthread:-fprofile-update=prefer-atomic}}}";
+ %{pthread:-fprofile-update=prefer-atomic}}}\
+ %{frecord-gcc-switches-format=driver:-frecord-gcc-switches-file=%:save-driver-cmdline(%g.cmdline)\
+ %<-frecord-gcc-switches-format=driver}";
static const char *asm_options =
"%{-target-help:%:print-asm-header()} "
@@ -1747,6 +1756,7 @@ static const struct spec_function static_spec_functions[] =
{ "debug-level-gt", debug_level_greater_than_spec_func },
{ "dwarf-version-gt", dwarf_version_greater_than_spec_func },
{ "fortran-preinclude-file", find_fortran_preinclude_file},
+ { "save-driver-cmdline", save_driver_cmdline},
#ifdef EXTRA_SPEC_FUNCTIONS
EXTRA_SPEC_FUNCTIONS
#endif
@@ -7991,6 +8001,7 @@ driver::main (int argc, char **argv)
set_progname (argv[0]);
expand_at_files (&argc, &argv);
+ set_commandline (argc, const_cast <const char **> (argv));
decode_argv (argc, const_cast <const char **> (argv));
global_initializations ();
build_multilib_strings ();
@@ -8034,6 +8045,15 @@ driver::set_progname (const char *argv0) const
xmalloc_set_program_name (progname);
}
+/* Keep the command line for -frecord-gcc-switches-format=driver. */
+
+void
+driver::set_commandline (int argc, const char **argv) const
+{
+ driver_gcc_argc = argc;
+ driver_gcc_argv = argv;
+}
+
/* Expand any @ files within the command-line args,
setting at_file_supplied if any were expanded. */
@@ -10771,6 +10791,21 @@ find_fortran_preinclude_file (int argc, const char **argv)
return result;
}
+/* Save driver options to a temporary file. */
+
+static const char *
+save_driver_cmdline (int argc ATTRIBUTE_UNUSED,
+ const char **argv)
+{
+ FILE *f = fopen (argv[0], "w");
+ for (unsigned int i = 0; i < driver_gcc_argc; i++)
+ fprintf (f, i == 0 ? "%s" : " %s", driver_gcc_argv[i]);
+ fclose (f);
+
+ return argv[0];
+}
+
+
/* If any character in ORIG fits QUOTE_P (_, P), reallocate the string
so as to precede every one of them with a backslash. Return the
original string or the reallocated one. */
diff --git a/gcc/gcc.h b/gcc/gcc.h
index 70d8f08f059..cde77fbaad7 100644
--- a/gcc/gcc.h
+++ b/gcc/gcc.h
@@ -37,6 +37,7 @@ class driver
private:
void set_progname (const char *argv0) const;
+ void set_commandline (int argc, const char **argv) const;
void expand_at_files (int *argc, char ***argv) const;
void decode_argv (int argc, const char **argv);
void global_initializations ();
diff --git a/gcc/opts.c b/gcc/opts.c
index 57774916a09..5cb5aaac8f7 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see
#include "spellcheck.h"
#include "opt-suggestions.h"
#include "diagnostic-color.h"
+#include "version.h"
#include "selftest.h"
static void set_Wstrict_aliasing (struct gcc_options *opts, int onoff);
@@ -3200,6 +3201,144 @@ get_option_url (diagnostic_context *, int option_index)
return NULL;
}
+/* Return a heap allocated producer string including command line options. */
+
+char *
+get_producer_string (const char *language_string, cl_decoded_option *options,
+ unsigned int options_count)
+{
+ size_t j;
+ auto_vec<const char *> switches;
+ char *producer, *tail;
+ const char *p;
+ size_t len = 0;
+ size_t plen = strlen (language_string) + 1 + strlen (version_string);
+
+ for (j = 0; j < options_count; j++)
+ switch (options[j].opt_index)
+ {
+ case OPT_o:
+ case OPT_d:
+ case OPT_dumpbase:
+ case OPT_dumpdir:
+ case OPT_quiet:
+ case OPT_version:
+ case OPT_v:
+ case OPT_w:
+ case OPT_L:
+ case OPT_D:
+ case OPT_I:
+ case OPT_U:
+ case OPT_SPECIAL_unknown:
+ case OPT_SPECIAL_ignore:
+ case OPT_SPECIAL_warn_removed:
+ case OPT_SPECIAL_program_name:
+ case OPT_SPECIAL_input_file:
+ case OPT_grecord_gcc_switches:
+ case OPT_frecord_gcc_switches:
+ case OPT_frecord_gcc_switches_format_:
+ case OPT__output_pch_:
+ case OPT_fdiagnostics_show_location_:
+ case OPT_fdiagnostics_show_option:
+ case OPT_fdiagnostics_show_caret:
+ case OPT_fdiagnostics_show_labels:
+ case OPT_fdiagnostics_show_line_numbers:
+ case OPT_fdiagnostics_color_:
+ case OPT_fdiagnostics_format_:
+ case OPT_fverbose_asm:
+ case OPT____:
+ case OPT__sysroot_:
+ case OPT_nostdinc:
+ case OPT_nostdinc__:
+ case OPT_fpreprocessed:
+ case OPT_fltrans_output_list_:
+ case OPT_fresolution_:
+ case OPT_fdebug_prefix_map_:
+ case OPT_fmacro_prefix_map_:
+ case OPT_ffile_prefix_map_:
+ case OPT_fcompare_debug:
+ case OPT_fchecking:
+ case OPT_fchecking_:
+ /* Ignore these. */
+ continue;
+ case OPT_flto_:
+ {
+ const char *lto_canonical = "-flto";
+ switches.safe_push (lto_canonical);
+ len += strlen (lto_canonical) + 1;
+ break;
+ }
+ default:
+ if (cl_options[options[j].opt_index].flags
+ & CL_NO_DWARF_RECORD)
+ continue;
+ gcc_checking_assert (options[j].canonical_option[0][0] == '-');
+ switch (options[j].canonical_option[0][1])
+ {
+ case 'M':
+ case 'i':
+ case 'W':
+ continue;
+ case 'f':
+ if (strncmp (options[j].canonical_option[0] + 2,
+ "dump", 4) == 0)
+ continue;
+ break;
+ default:
+ break;
+ }
+ switches.safe_push (options[j].orig_option_with_args_text);
+ len += strlen (options[j].orig_option_with_args_text) + 1;
+ break;
+ }
+
+ producer = XNEWVEC (char, plen + 1 + len + 1);
+ tail = producer;
+ sprintf (tail, "%s %s", language_string, version_string);
+ tail += plen;
+
+ FOR_EACH_VEC_ELT (switches, j, p)
+ {
+ len = strlen (p);
+ *tail = ' ';
+ memcpy (tail + 1, p, len);
+ tail += len + 1;
+ }
+
+ *tail = '\0';
+ return producer;
+}
+
+/* Return value of env variable GCC_DRIVER_COMMAND_LINE if exists.
+ Otherwise return empty string. */
+
+const char *
+get_driver_command_line ()
+{
+ static char *cmdline = NULL;
+
+ if (cmdline != NULL)
+ return cmdline;
+
+ FILE *f = fopen (flag_record_gcc_switches_file, "r");
+ if (f == NULL)
+ fatal_error (UNKNOWN_LOCATION, "cannot open %s: %m", flag_record_gcc_switches_file);
+
+ fseek(f, 0, SEEK_END);
+ unsigned int size = ftell (f);
+ fseek(f, 0, SEEK_SET);
+
+ cmdline = XNEWVEC (char, size + 1);
+
+ unsigned int read;
+ char *ptr = cmdline;
+ while ((read = fread (ptr, 4096, 1, f)))
+ ptr += read;
+
+ cmdline[size] = '\0';
+ return cmdline;
+}
+
#if CHECKING_P
namespace selftest {
diff --git a/gcc/opts.h b/gcc/opts.h
index d62bfcfdf6a..4f4684ed8c2 100644
--- a/gcc/opts.h
+++ b/gcc/opts.h
@@ -482,6 +482,12 @@ extern void parse_options_from_collect_gcc_options (const char *, obstack *,
extern void prepend_xassembler_to_collect_as_options (const char *, obstack *);
+extern char *get_producer_string (const char *language_string,
+ cl_decoded_option *options,
+ unsigned int options_count);
+
+extern const char *get_driver_command_line ();
+
/* Set OPTION in OPTS to VALUE if the option is not set in OPTS_SET. */
#define SET_OPTION_IF_UNSET(OPTS, OPTS_SET, OPTION, VALUE) \
diff --git a/gcc/target.def b/gcc/target.def
index 810d5542c28..62b409507c9 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -757,41 +757,7 @@ directive to annotate @var{symbol} as used. The Darwin target uses the\n\
DEFHOOK
(record_gcc_switches,
"Provides the target with the ability to record the gcc command line\n\
-switches that have been passed to the compiler, and options that are\n\
-enabled. The @var{type} argument specifies what is being recorded.\n\
-It can take the following values:\n\
-\n\
-@table @gcctabopt\n\
-@item SWITCH_TYPE_PASSED\n\
-@var{text} is a command line switch that has been set by the user.\n\
-\n\
-@item SWITCH_TYPE_ENABLED\n\
-@var{text} is an option which has been enabled. This might be as a\n\
-direct result of a command line switch, or because it is enabled by\n\
-default or because it has been enabled as a side effect of a different\n\
-command line switch. For example, the @option{-O2} switch enables\n\
-various different individual optimization passes.\n\
-\n\
-@item SWITCH_TYPE_DESCRIPTIVE\n\
-@var{text} is either NULL or some descriptive text which should be\n\
-ignored. If @var{text} is NULL then it is being used to warn the\n\
-target hook that either recording is starting or ending. The first\n\
-time @var{type} is SWITCH_TYPE_DESCRIPTIVE and @var{text} is NULL, the\n\
-warning is for start up and the second time the warning is for\n\
-wind down. This feature is to allow the target hook to make any\n\
-necessary preparations before it starts to record switches and to\n\
-perform any necessary tidying up after it has finished recording\n\
-switches.\n\
-\n\
-@item SWITCH_TYPE_LINE_START\n\
-This option can be ignored by this target hook.\n\
-\n\
-@item SWITCH_TYPE_LINE_END\n\
-This option can be ignored by this target hook.\n\
-@end table\n\
-\n\
-The hook's return value must be zero. Other return values may be\n\
-supported in the future.\n\
+switches provided as argument.\n\
\n\
By default this hook is set to NULL, but an example implementation is\n\
provided for ELF based targets. Called @var{elf_record_gcc_switches},\n\
@@ -799,7 +765,7 @@ it records the switches as ASCII text inside a new, string mergeable\n\
section in the assembler output file. The name of the new section is\n\
provided by the @code{TARGET_ASM_RECORD_GCC_SWITCHES_SECTION} target\n\
hook.",
- int, (print_switch_type type, const char *text),
+ void, (const char *),
NULL)
/* The name of the section that the example ELF implementation of
diff --git a/gcc/target.h b/gcc/target.h
index 440cd25f297..960188023f1 100644
--- a/gcc/target.h
+++ b/gcc/target.h
@@ -68,16 +68,6 @@ union cumulative_args_t { void *p; };
#endif /* !CHECKING_P */
-/* Types used by the record_gcc_switches() target function. */
-enum print_switch_type
-{
- SWITCH_TYPE_PASSED, /* A switch passed on the command line. */
- SWITCH_TYPE_ENABLED, /* An option that is currently enabled. */
- SWITCH_TYPE_DESCRIPTIVE, /* Descriptive text, not a switch or option. */
- SWITCH_TYPE_LINE_START, /* Please emit any necessary text at the start of a line. */
- SWITCH_TYPE_LINE_END /* Please emit a line terminator. */
-};
-
/* Types of memory operation understood by the "by_pieces" infrastructure.
Used by the TARGET_USE_BY_PIECES_INFRASTRUCTURE_P target hook and
internally by the functions in expr.c. */
@@ -96,10 +86,8 @@ extern unsigned HOST_WIDE_INT by_pieces_ninsns (unsigned HOST_WIDE_INT,
unsigned int,
by_pieces_operation);
-typedef int (* print_switch_fn_type) (print_switch_type, const char *);
-
/* An example implementation for ELF targets. Defined in varasm.c */
-extern int elf_record_gcc_switches (print_switch_type type, const char *);
+extern void elf_record_gcc_switches (const char *);
/* Some places still assume that all pointer or address modes are the
standard Pmode and ptr_mode. These optimizations become invalid if
diff --git a/gcc/toplev.c b/gcc/toplev.c
index e0e0e04e95f..14e3169d0d0 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -116,9 +116,6 @@ static void compile_file (void);
/* True if we don't need a backend (e.g. preprocessing only). */
static bool no_backend;
-/* Length of line when printing switch values. */
-#define MAX_LINE 75
-
/* Decoded options, and number of such options. */
struct cl_decoded_option *save_decoded_options;
unsigned int save_decoded_options_count;
@@ -684,148 +681,7 @@ print_version (FILE *file, const char *indent, bool show_global_state)
}
}
-static int
-print_to_asm_out_file (print_switch_type type, const char * text)
-{
- bool prepend_sep = true;
-
- switch (type)
- {
- case SWITCH_TYPE_LINE_END:
- putc ('\n', asm_out_file);
- return 1;
-
- case SWITCH_TYPE_LINE_START:
- fputs (ASM_COMMENT_START, asm_out_file);
- return strlen (ASM_COMMENT_START);
-
- case SWITCH_TYPE_DESCRIPTIVE:
- if (ASM_COMMENT_START[0] == 0)
- prepend_sep = false;
- /* FALLTHRU */
- case SWITCH_TYPE_PASSED:
- case SWITCH_TYPE_ENABLED:
- if (prepend_sep)
- fputc (' ', asm_out_file);
- fputs (text, asm_out_file);
- /* No need to return the length here as
- print_single_switch has already done it. */
- return 0;
-
- default:
- return -1;
- }
-}
-
-static int
-print_to_stderr (print_switch_type type, const char * text)
-{
- switch (type)
- {
- case SWITCH_TYPE_LINE_END:
- putc ('\n', stderr);
- return 1;
-
- case SWITCH_TYPE_LINE_START:
- return 0;
-
- case SWITCH_TYPE_PASSED:
- case SWITCH_TYPE_ENABLED:
- fputc (' ', stderr);
- /* FALLTHRU */
-
- case SWITCH_TYPE_DESCRIPTIVE:
- fputs (text, stderr);
- /* No need to return the length here as
- print_single_switch has already done it. */
- return 0;
-
- default:
- return -1;
- }
-}
-
-/* Print an option value and return the adjusted position in the line.
- ??? print_fn doesn't handle errors, eg disk full; presumably other
- code will catch a disk full though. */
-
-static int
-print_single_switch (print_switch_fn_type print_fn,
- int pos,
- print_switch_type type,
- const char * text)
-{
- /* The ultrix fprintf returns 0 on success, so compute the result
- we want here since we need it for the following test. The +1
- is for the separator character that will probably be emitted. */
- int len = strlen (text) + 1;
-
- if (pos != 0
- && pos + len > MAX_LINE)
- {
- print_fn (SWITCH_TYPE_LINE_END, NULL);
- pos = 0;
- }
-
- if (pos == 0)
- pos += print_fn (SWITCH_TYPE_LINE_START, NULL);
- print_fn (type, text);
- return pos + len;
-}
-
-/* Print active target switches using PRINT_FN.
- POS is the current cursor position and MAX is the size of a "line".
- Each line begins with INDENT and ends with TERM.
- Each switch is separated from the next by SEP. */
-
-static void
-print_switch_values (print_switch_fn_type print_fn)
-{
- int pos = 0;
- size_t j;
-
- /* Print the options as passed. */
- pos = print_single_switch (print_fn, pos,
- SWITCH_TYPE_DESCRIPTIVE, _("options passed: "));
-
- for (j = 1; j < save_decoded_options_count; j++)
- {
- switch (save_decoded_options[j].opt_index)
- {
- case OPT_o:
- case OPT_d:
- case OPT_dumpbase:
- case OPT_dumpbase_ext:
- case OPT_dumpdir:
- case OPT_quiet:
- case OPT_version:
- /* Ignore these. */
- continue;
- }
-
- pos = print_single_switch (print_fn, pos, SWITCH_TYPE_PASSED,
- save_decoded_options[j].orig_option_with_args_text);
- }
-
- if (pos > 0)
- print_fn (SWITCH_TYPE_LINE_END, NULL);
-
- /* Print the -f and -m options that have been enabled.
- We don't handle language specific options but printing argv
- should suffice. */
- pos = print_single_switch (print_fn, 0,
- SWITCH_TYPE_DESCRIPTIVE, _("options enabled: "));
-
- unsigned lang_mask = lang_hooks.option_lang_mask ();
- for (j = 0; j < cl_options_count; j++)
- if (cl_options[j].cl_report
- && option_enabled (j, lang_mask, &global_options) > 0)
- pos = print_single_switch (print_fn, pos,
- SWITCH_TYPE_ENABLED, cl_options[j].opt_text);
-
- print_fn (SWITCH_TYPE_LINE_END, NULL);
-}
/* Open assembly code output file. Do this even if -fsyntax-only is
on, because then the driver will have provided the name of a
@@ -872,14 +728,21 @@ init_asm_output (const char *name)
{
if (targetm.asm_out.record_gcc_switches)
{
- /* Let the target know that we are about to start recording. */
- targetm.asm_out.record_gcc_switches (SWITCH_TYPE_DESCRIPTIVE,
- NULL);
- /* Now record the switches. */
- print_switch_values (targetm.asm_out.record_gcc_switches);
- /* Let the target know that the recording is over. */
- targetm.asm_out.record_gcc_switches (SWITCH_TYPE_DESCRIPTIVE,
- NULL);
+ if (flag_record_gcc_switches_format == RECORD_GCC_SWITCHES_DRIVER)
+ {
+ const char *str = concat (version_string, " ",
+ get_driver_command_line (), NULL);
+ targetm.asm_out.record_gcc_switches (str);
+ free (CONST_CAST (char *, str));
+ }
+ else
+ {
+ const char *str
+ = get_producer_string (lang_hooks.name,
+ save_decoded_options,
+ save_decoded_options_count);
+ targetm.asm_out.record_gcc_switches (str);
+ }
}
else
inform (UNKNOWN_LOCATION,
@@ -889,11 +752,13 @@ init_asm_output (const char *name)
if (flag_verbose_asm)
{
- /* Print the list of switches in effect
- into the assembler file as comments. */
print_version (asm_out_file, ASM_COMMENT_START, true);
- print_switch_values (print_to_asm_out_file);
- putc ('\n', asm_out_file);
+ fputs (ASM_COMMENT_START, asm_out_file);
+ fputc (' ', asm_out_file);
+ fputs (get_producer_string (lang_hooks.name, save_decoded_options,
+ save_decoded_options_count),
+ asm_out_file);
+ fputc ('\n', asm_out_file);
}
}
}
@@ -1523,8 +1388,14 @@ process_options (void)
if (version_flag)
{
print_version (stderr, "", true);
- if (! quiet_flag)
- print_switch_values (print_to_stderr);
+ if (!quiet_flag)
+ {
+ if (flag_record_gcc_switches_format == RECORD_GCC_SWITCHES_DRIVER)
+ fputs (get_driver_command_line (), stderr);
+ else
+ fputs (get_producer_string (lang_hooks.name, save_decoded_options,
+ save_decoded_options_count), stderr);
+ }
}
if (flag_syntax_only)
diff --git a/gcc/varasm.c b/gcc/varasm.c
index ada99940f65..f599d79bdb3 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -43,6 +43,7 @@ along with GCC; see the file COPYING3. If not see
#include "fold-const.h"
#include "stor-layout.h"
#include "varasm.h"
+#include "version.h"
#include "flags.h"
#include "stmt.h"
#include "expr.h"
@@ -58,6 +59,8 @@ along with GCC; see the file COPYING3. If not see
#include "rtl-iter.h"
#include "file-prefix-map.h" /* remap_debug_filename() */
#include "alloc-pool.h"
+#include "toplev.h"
+#include "opts.h"
#ifdef XCOFF_DEBUGGING_INFO
#include "xcoffout.h" /* Needed for external data declarations. */
@@ -8013,45 +8016,14 @@ output_object_blocks (void)
we want to emit NUL strings terminators into the object file we have to use
ASM_OUTPUT_SKIP. */
-int
-elf_record_gcc_switches (print_switch_type type, const char * name)
+void
+elf_record_gcc_switches (const char *options)
{
- switch (type)
- {
- case SWITCH_TYPE_PASSED:
- ASM_OUTPUT_ASCII (asm_out_file, name, strlen (name));
- ASM_OUTPUT_SKIP (asm_out_file, HOST_WIDE_INT_1U);
- break;
-
- case SWITCH_TYPE_DESCRIPTIVE:
- if (name == NULL)
- {
- /* Distinguish between invocations where name is NULL. */
- static bool started = false;
-
- if (!started)
- {
- section * sec;
-
- sec = get_section (targetm.asm_out.record_gcc_switches_section,
- SECTION_DEBUG
- | SECTION_MERGE
- | SECTION_STRINGS
- | (SECTION_ENTSIZE & 1),
- NULL);
- switch_to_section (sec);
- started = true;
- }
- }
-
- default:
- break;
- }
-
- /* The return value is currently ignored by the caller, but must be 0.
- For -fverbose-asm the return value would be the number of characters
- emitted into the assembler file. */
- return 0;
+ section *sec = get_section (targetm.asm_out.record_gcc_switches_section,
+ SECTION_DEBUG | SECTION_MERGE
+ | SECTION_STRINGS | (SECTION_ENTSIZE & 1), NULL);
+ switch_to_section (sec);
+ ASM_OUTPUT_ASCII (asm_out_file, options, strlen (options) + 1);
}
/* Emit text to declare externally defined symbols. It is needed to
--
2.29.2