Hello. Based on discussion with Richi, I'm re-sending the patch. Note that the patch has been waiting for a review for almost one year and I would like to see it in GCC 11.1.
Thank you, Martin
>From 4cb8475a40464d5b7805ececb280bb2463d3caa4 Mon Sep 17 00:00:00 2001 From: Martin Liska <mli...@suse.cz> Date: Fri, 5 Feb 2021 10:28:57 +0100 Subject: [PATCH] Change semantics of -frecord-gcc-switches and add -frecord-gcc-switches-format. gcc/ChangeLog: * common.opt: Document new options -frecord-gcc-switches-format and -frecord-gcc-switches-file. * doc/invoke.texi: Document the new options. * 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_driver_command_line): New. * opts.h (get_driver_command_line): New. * toplev.c (init_asm_output): Use new function get_producer_string. (process_options): Respect flag_record_gcc_switches_format option. Co-Authored-By: Egeyar Bagcioglu <egeyar.bagcio...@oracle.com> --- gcc/common.opt | 19 ++++++++++++++++++- gcc/doc/invoke.texi | 23 ++++++++++++++++++++++- gcc/dwarf2out.c | 17 ++++++++++++----- gcc/flag-types.h | 7 +++++++ gcc/gcc.c | 37 ++++++++++++++++++++++++++++++++++++- gcc/gcc.h | 1 + gcc/opts.c | 31 +++++++++++++++++++++++++++++++ gcc/opts.h | 2 ++ gcc/toplev.c | 27 ++++++++++++++++++++------- 9 files changed, 149 insertions(+), 15 deletions(-) diff --git a/gcc/common.opt b/gcc/common.opt index a8a2b67a99d..088d552cf31 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -2326,9 +2326,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 Var(flag_record_gcc_switches) +Common Driver 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 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 Joined RejectNegative Var(flag_record_gcc_switches_file) Undocumented +Path to file that contains driver command line options. + freg-struct-return Common 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 3751bc3ac7c..acdf9ed2dba 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -654,7 +654,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 @@ -16359,6 +16359,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/dwarf2out.c b/gcc/dwarf2out.c index 0a61d148c8a..2de79446b5e 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -32149,13 +32149,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 = concat (lang_hooks.name, " ", version_string, NULL); if (dwarf_record_gcc_switches) - producer_string = gen_producer_string (lang_hooks.name, - save_decoded_options, - save_decoded_options_count); - else - producer_string = concat (lang_hooks.name, " ", version_string, NULL); + { + 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 = gen_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 a038c8fb738..8ab413f5e1d 100644 --- a/gcc/flag-types.h +++ b/gcc/flag-types.h @@ -427,6 +427,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 76f1d422f9a..7cac56416c8 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 *); @@ -1277,7 +1284,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()} " @@ -1769,6 +1778,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 @@ -8007,6 +8017,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 (); @@ -8050,6 +8061,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. */ @@ -10817,6 +10837,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 244edbc26c6..809fe14429c 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 1f1cf8388f7..eedd3928e16 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -3303,6 +3303,7 @@ gen_command_line_string (cl_decoded_option *options, 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: @@ -3388,6 +3389,36 @@ gen_producer_string (const char *language_string, cl_decoded_option *options, gen_command_line_string (options, options_count), NULL); } +/* 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 a6ed2e3953e..aadb35b4eef 100644 --- a/gcc/opts.h +++ b/gcc/opts.h @@ -486,6 +486,8 @@ extern char *gen_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/toplev.c b/gcc/toplev.c index a8947a735ff..c6d1355dc57 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -731,11 +731,21 @@ init_asm_output (const char *name) { if (targetm.asm_out.record_gcc_switches) { - const char *str - = gen_producer_string (lang_hooks.name, - save_decoded_options, - save_decoded_options_count); - targetm.asm_out.record_gcc_switches (str); + 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 + = gen_producer_string (lang_hooks.name, + save_decoded_options, + save_decoded_options_count); + targetm.asm_out.record_gcc_switches (str); + } } else inform (UNKNOWN_LOCATION, @@ -1384,8 +1394,11 @@ process_options (void) if (!quiet_flag) { fputs ("options passed: ", stderr); - fputs (gen_command_line_string (save_decoded_options, - save_decoded_options_count), stderr); + if (flag_record_gcc_switches_format == RECORD_GCC_SWITCHES_DRIVER) + fputs (get_driver_command_line (), stderr); + else + fputs (gen_command_line_string (save_decoded_options, + save_decoded_options_count), stderr); fputc ('\n', stderr); } } -- 2.30.0