From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) by sourceware.org (Postfix) with ESMTPS id 0A083387102B for ; Wed, 18 Mar 2020 09:05:45 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 0A083387102B Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=suse.cz Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=mliska@suse.cz X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id C8963AD83; Wed, 18 Mar 2020 09:05:43 +0000 (UTC) Subject: Re: [stage1][PATCH] Change semantics of -frecord-gcc-switches and add -frecord-gcc-switches-format. To: Egeyar Bagcioglu , Jakub Jelinek Cc: Richard Biener , GCC Patches , nickc@redhat.com References: <1583246660-6390-1-git-send-email-egeyar.bagcioglu@oracle.com> <1583246660-6390-4-git-send-email-egeyar.bagcioglu@oracle.com> <20200304173322.GR2156@tucnak> <648767d6-68ff-cb3c-811b-c20ee2202b41@oracle.com> <63cd2ac4-bd04-929d-98c3-2762da882e9c@suse.cz> <92bec310-4955-6fe0-df51-ed39f82f5c3b@suse.cz> <290802a0-d979-c46a-8042-6a9ff7be8f5b@oracle.com> From: =?UTF-8?Q?Martin_Li=c5=a1ka?= Message-ID: Date: Wed, 18 Mar 2020 10:05:42 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.5.0 MIME-Version: 1.0 In-Reply-To: <290802a0-d979-c46a-8042-6a9ff7be8f5b@oracle.com> Content-Type: multipart/mixed; boundary="------------0326D2C72BED63DBFB2BBD28" Content-Language: en-US X-Spam-Status: No, score=-25.0 required=5.0 tests=GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_DMARC_STATUS, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 18 Mar 2020 09:05:48 -0000 This is a multi-part message in MIME format. --------------0326D2C72BED63DBFB2BBD28 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit 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. 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 > --------------0326D2C72BED63DBFB2BBD28 Content-Type: text/x-patch; charset=UTF-8; name="0001-Change-semantics-of-frecord-gcc-switches-and-add-fre.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename*0="0001-Change-semantics-of-frecord-gcc-switches-and-add-fre.pa"; filename*1="tch" >From 60653c2c37d8c2f0eec171c3ab9a1b7487b82e0f Mon Sep 17 00:00:00 2001 From: Martin Liska 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 Egeyar Bagcioglu * common.opt: Add new option -frecord-gcc-switches-format. * doc/invoke.texi: Document the new option. * doc/tm.texi: Remove print_switch_type documentation entry. * dwarf2out.c (gen_producer_string): Move to varasm.c and ignore also OPT_frecord_gcc_switches and OPT_frecord_gcc_switches_format_. (dwarf2out_early_finish): Print corresponding producer format string. * flag-types.h (enum record_gcc_switches_format): * gcc.c (set_driver_command_line_envvar): New function. (driver_handle_option): Always save command line options. (driver::main): Save command line. (driver::set_commandline): New. * gcc.h (driver::set_commandline): New. * opts.c (get_producer_string): Moved from dwarf2out.c. (get_driver_command_line): New function. * opts.h (get_producer_string): New. (get_driver_command_line): Likewise. * target.def: Remove documentation foor print_switch_type. * target.h (enum print_switch_type): Remove. (elf_record_gcc_switches): Change to void type. * toplev.c (MAX_LINE): Remove. (print_to_asm_out_file): Remove. (print_to_stderr): Remove. (print_single_switch): Likewise. (print_switch_values): Likewise. (init_asm_output): Call directly record_gcc_switches. (process_options): Print options to stderr. * varasm.c (elf_record_gcc_switches): Support new flag_record_gcc_switches_format option. --- gcc/common.opt | 15 +++- gcc/doc/invoke.texi | 23 +++++- gcc/doc/tm.texi | 37 +-------- gcc/dwarf2out.c | 125 ++++-------------------------- gcc/flag-types.h | 7 ++ gcc/gcc.c | 39 ++++++++++ gcc/gcc.h | 1 + gcc/opts.c | 121 +++++++++++++++++++++++++++++ gcc/opts.h | 6 ++ gcc/target.def | 37 +-------- gcc/target.h | 14 +--- gcc/toplev.c | 180 +++++--------------------------------------- gcc/varasm.c | 59 ++++++--------- 13 files changed, 270 insertions(+), 394 deletions(-) diff --git a/gcc/common.opt b/gcc/common.opt index 4368910cb54..7809c734ee1 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -2246,9 +2246,22 @@ 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. + 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 96a95162696..7925990e320 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -622,7 +622,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 @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 @@ -15070,6 +15070,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 3560cfae74f..56d493eed21 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -8061,43 +8061,10 @@ 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 (void) 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. +enabled. 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 bb45279ea56..2e8ed4e946d 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -24314,116 +24314,6 @@ gen_ptr_to_mbr_type_die (tree type, dw_die_ref context_die) static char *producer_string; -/* Return a heap allocated producer string including command line options - if -grecord-gcc-switches. */ - -static char * -gen_producer_string (void) -{ - size_t j; - auto_vec switches; - const char *language_string = lang_hooks.name; - char *producer, *tail; - const char *p; - size_t len = dwarf_record_gcc_switches ? 0 : 3; - size_t plen = strlen (language_string) + 1 + strlen (version_string); - - for (j = 1; dwarf_record_gcc_switches && j < save_decoded_options_count; j++) - switch (save_decoded_options[j].opt_index) - { - case OPT_o: - case OPT_d: - case OPT_dumpbase: - case OPT_dumpdir: - case OPT_auxbase: - case OPT_auxbase_strip: - 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__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[save_decoded_options[j].opt_index].flags - & CL_NO_DWARF_RECORD) - continue; - gcc_checking_assert (save_decoded_options[j].canonical_option[0][0] - == '-'); - switch (save_decoded_options[j].canonical_option[0][1]) - { - case 'M': - case 'i': - case 'W': - continue; - case 'f': - if (strncmp (save_decoded_options[j].canonical_option[0] + 2, - "dump", 4) == 0) - continue; - break; - default: - break; - } - switches.safe_push (save_decoded_options[j].orig_option_with_args_text); - len += strlen (save_decoded_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; -} - /* Given a C and/or C++ language/version string return the "highest". C++ is assumed to be "higher" than C in this case. Used for merging LTO translation unit languages. */ @@ -31986,7 +31876,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 b092c563f3d..20ff86e2af5 100644 --- a/gcc/flag-types.h +++ b/gcc/flag-types.h @@ -381,4 +381,11 @@ enum parloops_schedule_type PARLOOPS_SCHEDULE_RUNTIME }; +/* Record GCC options type. */ +enum record_gcc_switches_format +{ + RECORD_GCC_SWITCHES_PROCESSED = 0, + RECORD_GCC_SWITCHES_DRIVER +}; + #endif /* ! GCC_FLAG_TYPES_H */ diff --git a/gcc/gcc.c b/gcc/gcc.c index 9f790db0daf..b4315750079 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -235,6 +235,11 @@ static int verbose_only_flag; static int print_subprocess_help; +/* argc and argv used to call gcc. Necessary for + --record-gcc-command-line option. */ +static unsigned int driver_gcc_argc; +static const char **driver_gcc_argv; + /* Linker suffix passed to -fuse-ld=... */ static const char *use_ld; @@ -3724,6 +3729,28 @@ set_source_date_epoch_envvar () setenv ("SOURCE_DATE_EPOCH", source_date_epoch, 0); } +/* Set GCC_DRIVER_COMMAND_LINE enviromental variable that is later + used by -frecord-gcc-switches option. */ + +static void +set_driver_command_line_envvar () +{ + unsigned int length = 0; + for (unsigned int i = 0; i < driver_gcc_argc; i++) + length += strlen (driver_gcc_argv[i]) + 1; + + char *buffer = (char *)xmalloc (length); + char *ptr = buffer; + for (unsigned int i = 0; i < driver_gcc_argc; i++) + { + unsigned l = sprintf (ptr, i == 0 ? "%s" : " %s", driver_gcc_argv[i]); + ptr += l; + } + + setenv ("GCC_DRIVER_COMMAND_LINE", buffer, 0); + free (buffer); +} + /* Handle an option DECODED that is unknown to the option-processing machinery. */ @@ -4296,6 +4323,8 @@ driver_handle_option (struct gcc_options *opts, break; } + set_driver_command_line_envvar (); + if (do_save) save_switch (decoded->canonical_option[0], decoded->canonical_option_num_elements - 1, @@ -7387,6 +7416,7 @@ driver::main (int argc, char **argv) set_progname (argv[0]); expand_at_files (&argc, &argv); + set_commandline (argc, const_cast (argv)); decode_argv (argc, const_cast (argv)); global_initializations (); build_multilib_strings (); @@ -7430,6 +7460,15 @@ driver::set_progname (const char *argv0) const xmalloc_set_program_name (progname); } +/* Keep command line for --record-gcc-command-line. */ + +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. */ 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 ac160ed8404..e5ec6bef62a 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" static void set_Wstrict_aliasing (struct gcc_options *opts, int onoff); @@ -3132,3 +3133,123 @@ get_option_url (diagnostic_context *, int option_index) else 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 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_auxbase: + case OPT_auxbase_strip: + 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 () +{ + const char *cmdline = getenv ("GCC_DRIVER_COMMAND_LINE"); + return cmdline != NULL ? cmdline : ""; +} diff --git a/gcc/opts.h b/gcc/opts.h index 8f594b46e33..fc3cd4b4596 100644 --- a/gcc/opts.h +++ b/gcc/opts.h @@ -465,6 +465,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 b5e82ff826e..9cb9dab60ab 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -746,40 +746,7 @@ 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\ +enabled.\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\ @@ -787,7 +754,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, (void), NULL) /* The name of the section that the example ELF implementation of diff --git a/gcc/target.h b/gcc/target.h index 2f47c577d00..8421f78915f 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 (void); /* 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 4c8be502c71..4128a547ea4 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -114,9 +114,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,149 +681,6 @@ 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_dumpdir: - case OPT_auxbase: - 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 temporary file or bit bucket for us. NAME is the file specified on @@ -871,16 +725,7 @@ init_asm_output (const char *name) if (flag_record_gcc_switches) { 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); - } + targetm.asm_out.record_gcc_switches (); else inform (UNKNOWN_LOCATION, "%<-frecord-gcc-switches%> is not supported by " @@ -889,11 +734,16 @@ 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); + if (flag_record_gcc_switches_format == RECORD_GCC_SWITCHES_DRIVER) + fputs (get_driver_command_line (), asm_out_file); + else + fputs (get_producer_string (lang_hooks.name, save_decoded_options, + save_decoded_options_count), + asm_out_file); + fputc ('\n', asm_out_file); } } } @@ -1520,8 +1370,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 dc6da6c0b5b..1b23b5f4cc4 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" @@ -57,6 +58,8 @@ along with GCC; see the file COPYING3. If not see #include "asan.h" #include "rtl-iter.h" #include "file-prefix-map.h" /* remap_debug_filename() */ +#include "toplev.h" +#include "opts.h" #ifdef XCOFF_DEBUGGING_INFO #include "xcoffout.h" /* Needed for external data declarations. */ @@ -7803,45 +7806,29 @@ 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 () { - 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; - } - } + 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); - default: - break; + if (flag_record_gcc_switches_format == RECORD_GCC_SWITCHES_DRIVER) + { + ASM_OUTPUT_ASCII (asm_out_file, version_string, strlen (version_string)); + ASM_OUTPUT_ASCII (asm_out_file, " ", 1); + const char *cmdline = get_driver_command_line (); + ASM_OUTPUT_ASCII (asm_out_file, cmdline, strlen (cmdline) + 1); + } + else + { + const char *producer_string + = get_producer_string (lang_hooks.name, save_decoded_options, + save_decoded_options_count); + ASM_OUTPUT_ASCII (asm_out_file, producer_string, + strlen (producer_string) + 1); } - - /* 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; } /* Emit text to declare externally defined symbols. It is needed to -- 2.25.1 --------------0326D2C72BED63DBFB2BBD28--