Message ID | 20110712234608.GR2687@tyan-ft48-01.lab.bos.redhat.com |
---|---|
State | New |
Headers | show |
On 07/12/2011 07:46 PM, Jakub Jelinek wrote: > The aim is to include just (or primarily) code generation affecting options > explicitly passed on the command line. So that the merging actually works, > options or arguments which include filenames or paths shouldn't be added, > on Roland's request -D*/-U* options aren't added either (that should be > covered by .debug_macinfo) ...but only with -g3. > Ideally we'd just include explicitly passed options from command line that > haven't been overridden by other command line options, and would sort them, > so that there are higher chances of DW_AT_producer strings being merged > (e.g. -O2 -ffast-math vs. -ffast-math -O2 are now different strings, and > similarly -O2 vs. -O3 -O2 vs. -O0 -O1 -Ofast -O2), but I'm not sure if it is > easily possible using current option handling framework. Why not? Sorting sounds pretty straightforward to me, though you might want to copy the array first. On the other hand, it probably isn't worthwhile; presumably most relocatables being linked together will share the same CFLAGS, so you'll get a high degree of merging without any sorting. > --- gcc/testsuite/lib/dg-pch.exp.jj 2011-01-03 18:58:03.000000000 +0100 > +++ gcc/testsuite/lib/dg-pch.exp 2011-07-12 23:13:50.943670171 +0200 > - dg-test -keep-output "./$bname$suffix" "$otherflags $flags" "" > + dg-test -keep-output "./$bname$suffix" "-gno-record-gcc-switches $otherflags $flags" "" Why is this necessary? Jason
On Wed, Jul 13, 2011 at 09:56:58AM -0400, Jason Merrill wrote: > On 07/12/2011 07:46 PM, Jakub Jelinek wrote: > >The aim is to include just (or primarily) code generation affecting options > >explicitly passed on the command line. So that the merging actually works, > >options or arguments which include filenames or paths shouldn't be added, > >on Roland's request -D*/-U* options aren't added either (that should be > >covered by .debug_macinfo) > > ...but only with -g3. Sure. But if we put -D*/-U* into DW_AT_producer, -D_FORTIFY_SOURCE=2 on the command line acts the same as #define _FORTIFY_SOURCE 2 before including the first header and the latter wouldn't be recorded. I'm working on smaller .debug_macinfo right now. > >Ideally we'd just include explicitly passed options from command line that > >haven't been overridden by other command line options, and would sort them, > >so that there are higher chances of DW_AT_producer strings being merged > >(e.g. -O2 -ffast-math vs. -ffast-math -O2 are now different strings, and > >similarly -O2 vs. -O3 -O2 vs. -O0 -O1 -Ofast -O2), but I'm not sure if it is > >easily possible using current option handling framework. > > Why not? Sorting sounds pretty straightforward to me, though you > might want to copy the array first. If the command line options contain options that override each other, then sorting would drop important information what comes last and thus overrides other options. If we would have only options which weren't overridden, we could sort. Otherwise -O2 -O0 would be sorted as -O0 -O2 and we'd think the code was optimized when it wasn't. > On the other hand, it probably isn't worthwhile; presumably most > relocatables being linked together will share the same CFLAGS, so > you'll get a high degree of merging without any sorting. > > >--- gcc/testsuite/lib/dg-pch.exp.jj 2011-01-03 18:58:03.000000000 +0100 > >+++ gcc/testsuite/lib/dg-pch.exp 2011-07-12 23:13:50.943670171 +0200 > >- dg-test -keep-output "./$bname$suffix" "$otherflags $flags" "" > >+ dg-test -keep-output "./$bname$suffix" "-gno-record-gcc-switches $otherflags $flags" "" > > Why is this necessary? It is only necessary if somebody wants to make -grecord-gcc-switches the default (for bootstrap/regtest I've tweaked common.opt to do that to test it better). PCH is a big mess and screws debuginfo in many ways, in this case it was just small differences in DW_AT_producer, but we have e.g. ICEs with PCH and -feliminate-dwarf-dups etc. Jakub
On 07/13/2011 10:06 AM, Jakub Jelinek wrote: >>> --- gcc/testsuite/lib/dg-pch.exp.jj 2011-01-03 18:58:03.000000000 +0100 >>> +++ gcc/testsuite/lib/dg-pch.exp 2011-07-12 23:13:50.943670171 +0200 >>> - dg-test -keep-output "./$bname$suffix" "$otherflags $flags" "" >>> + dg-test -keep-output "./$bname$suffix" "-gno-record-gcc-switches $otherflags $flags" "" >> > It is only necessary if somebody wants to make -grecord-gcc-switches > the default (for bootstrap/regtest I've tweaked common.opt to do that > to test it better). PCH is a big mess and screws debuginfo in many ways, > in this case it was just small differences in DW_AT_producer, but > we have e.g. ICEs with PCH and -feliminate-dwarf-dups etc. Why would PCH change DW_AT_producer? Because we're restoring single_comp_unit_die from the PCH? Then perhaps we should set DW_AT_producer in output_comp_unit rather than gen_compile_unit_die. Jason
On Wed, 13 Jul 2011, Jakub Jelinek wrote: > Ideally we'd just include explicitly passed options from command line that > haven't been overridden by other command line options, and would sort them, > so that there are higher chances of DW_AT_producer strings being merged > (e.g. -O2 -ffast-math vs. -ffast-math -O2 are now different strings, and > similarly -O2 vs. -O3 -O2 vs. -O0 -O1 -Ofast -O2), but I'm not sure if it is > easily possible using current option handling framework. I don't think there's enough structure for that, although prune_options could always be enhanced to cover more cases of overridden options. > + default: > + if (save_decoded_options[j].orig_option_with_args_text[0] != '-') > + continue; Should instead be ignoring OPT_SPECIAL_*. > + switch (save_decoded_options[j].orig_option_with_args_text[1]) > + { > + case 'M': > + case 'i': > + case 'W': It would be better to check the canonical option text rather than the original text. Normally this wouldn't make any difference because the driver will have passed canonical options to cc1, but if someone calls cc1 directly then I think aliases should still act the same as the options they are aliases for in this regard. > + continue; > + case 'n': > + if (save_decoded_options[j].orig_option_with_args_text[2] > + == 'o') > + continue; When would a "-no" option ever get passed to cc1?
On Thu, Jul 21, 2011 at 08:06:49PM +0000, Joseph S. Myers wrote: > On Wed, 13 Jul 2011, Jakub Jelinek wrote: > > > Ideally we'd just include explicitly passed options from command line that > > haven't been overridden by other command line options, and would sort them, > > so that there are higher chances of DW_AT_producer strings being merged > > (e.g. -O2 -ffast-math vs. -ffast-math -O2 are now different strings, and > > similarly -O2 vs. -O3 -O2 vs. -O0 -O1 -Ofast -O2), but I'm not sure if it is > > easily possible using current option handling framework. > > I don't think there's enough structure for that, although prune_options > could always be enhanced to cover more cases of overridden options. Perhaps we can emit it in the original order even with duplicates for now and if we get better infrastructure later, reduce its size. > > + default: > > + if (save_decoded_options[j].orig_option_with_args_text[0] != '-') > > + continue; > > Should instead be ignoring OPT_SPECIAL_*. It already ignores them above: + case OPT_SPECIAL_unknown: + case OPT_SPECIAL_ignore: + case OPT_SPECIAL_program_name: + case OPT_SPECIAL_input_file: I just didn't want to crash if it wouldn't start with -. I can make it a gcc_checking_assert instead. > > > + switch (save_decoded_options[j].orig_option_with_args_text[1]) > > + { > > + case 'M': > > + case 'i': > > + case 'W': > > It would be better to check the canonical option text rather than the > original text. Normally this wouldn't make any difference because the > driver will have passed canonical options to cc1, but if someone calls cc1 > directly then I think aliases should still act the same as the options > they are aliases for in this regard. So gcc_checking_assert (save_decoded_options[j].canonical_option[0][0] == '-'); switch (save_decoded_options[j].canonical_option[0][1]) instead? The reason for checking the option text instead of code was just because there are hundreds of -W options etc. and I didn't want to list them all and create a maintanance nightmare. > > > + continue; > > + case 'n': > > + if (save_decoded_options[j].orig_option_with_args_text[2] > > + == 'o') > > + continue; > > When would a "-no" option ever get passed to cc1? If -no can't make it to cc1, I'll drop it. Is -fdump* checking that way ok (with the orig_option_with_args_text -> canonical_option[0] change)? Jakub
On Thu, 21 Jul 2011, Jakub Jelinek wrote: > So > > gcc_checking_assert (save_decoded_options[j].canonical_option[0][0] == '-'); > switch (save_decoded_options[j].canonical_option[0][1]) > > instead? The reason for checking the option text instead of code Yes. > was just because there are hundreds of -W options etc. and I didn't want to > list them all and create a maintanance nightmare. Flags such as CL_WARNING and the various bit-fields in struct cl_option (bit-fields are preferred if --help doesn't need to care about a property of an option) could be used, but I don't think it would really be an improvement in this case. > If -no can't make it to cc1, I'll drop it. Is -fdump* checking that way > ok (with the orig_option_with_args_text -> canonical_option[0] change)? Yes, that seems reasonable.
different DW_AT_producer strings, but it is still possible to find out what has been compiled with what options. The aim is to include just (or primarily) code generation affecting options explicitly passed on the command line. So that the merging actually works, options or arguments which include filenames or paths shouldn't be added, on Roland's request -D*/-U* options aren't added either (that should be covered by .debug_macinfo), similarly -I/-i* options (the interesting stuff what headers have been actually used is recorded in .debug_line) and warning options shouldn't affect code generation either. Ideally we'd just include explicitly passed options from command line that haven't been overridden by other command line options, and would sort them, so that there are higher chances of DW_AT_producer strings being merged (e.g. -O2 -ffast-math vs. -ffast-math -O2 are now different strings, and similarly -O2 vs. -O3 -O2 vs. -O0 -O1 -Ofast -O2), but I'm not sure if it is easily possible using current option handling framework. Bootstrapped/regtested on x86_64-linux, e.g. cc1plus has just a few different DW_AT_producers (sort|uniq -c|sort -n -r output): 322 (indirect string, offset: 0x4fb3): GNU C 4.7.0 20110712 (experimental) -mtune=generic -march=x86-64 -g -O2 -pedantic -fno-common 48 (indirect string, offset: 0xf41f1): GNU C 4.7.0 20110712 (experimental) -mtune=generic -march=x86-64 -g -O2 -pedantic 16 (indirect string, offset: 0xebf8): GNU C 4.7.0 20110712 (experimental) -mtune=generic -march=x86-64 -g -O2 -fno-common 9 (indirect string, offset: 0xfa115): GNU C 4.7.0 20110712 (experimental) -mtune=generic -march=x86-64 -g -O2 2 (indirect string, offset: 0xfa974): GNU C 4.7.0 20110712 (experimental) -mtune=generic -march=x86-64 -g -g -g -O2 -O2 -O2 -fPIC -fbuilding-libgcc -fno-stack-protector -fvisibility=hidden 2011-07-13 Jakub Jelinek <jakub@redhat.com> PR other/32998 * common.opt (grecord-gcc-switches, gno-record-gcc-switches): New options. * dwarf2out.c: Include opts.h. (dchar_p): New typedef. Define heap VEC for it. (gen_compile_unit_die): Handle dwarf_record_gcc_switches. * Makefile.in (dwarf2out.o): Depend on $(OPTS_H). * lib/dg-pch.exp (dg-flags-pch): Compile tests for assembly comparison with -gno-record-gcc-switches. --- gcc/common.opt.jj 2011-06-28 19:09:09.936421970 +0200 +++ gcc/common.opt 2011-07-12 21:17:13.809402161 +0200 @@ -2184,6 +2184,14 @@ ggdb Common JoinedOrMissing Generate debug information in default extended format +gno-record-gcc-switches +Common RejectNegative Var(dwarf_record_gcc_switches,0) Init(0) +Don't record gcc command line switches in DWARF DW_AT_producer. + +grecord-gcc-switches +Common RejectNegative Var(dwarf_record_gcc_switches,1) +Record gcc command line switches in DWARF DW_AT_producer. + gstabs Common JoinedOrMissing Negative(gstabs+) Generate debug information in STABS format --- gcc/dwarf2out.c.jj 2011-07-12 21:15:46.987389471 +0200 +++ gcc/dwarf2out.c 2011-07-13 01:18:21.864451800 +0200 @@ -94,6 +94,7 @@ along with GCC; see the file COPYING3. #include "tree-pass.h" #include "tree-flow.h" #include "cfglayout.h" +#include "opts.h" static void dwarf2out_source_line (unsigned int, const char *, int, bool); static rtx last_var_location_insn; @@ -18110,6 +18111,10 @@ gen_ptr_to_mbr_type_die (tree type, dw_d /* Generate the DIE for the compilation unit. */ +typedef const char *dchar_p; /* For DEF_VEC_P. */ +DEF_VEC_P(dchar_p); +DEF_VEC_ALLOC_P(dchar_p,heap); + static dw_die_ref gen_compile_unit_die (const char *filename) { @@ -18130,18 +18135,104 @@ gen_compile_unit_die (const char *filena sprintf (producer, "%s %s", language_string, version_string); + if (dwarf_record_gcc_switches) + { + size_t j; + VEC(dchar_p, heap) *switches = NULL; + char *producer_and_switches, *tail; + const char *p; + size_t len = 0, plen = strlen (producer); + 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_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_program_name: + case OPT_SPECIAL_input_file: + case OPT_grecord_gcc_switches: + case OPT_gno_record_gcc_switches: + case OPT__output_pch_: + case OPT_fdiagnostics_show_location_: + case OPT_fdiagnostics_show_option: + case OPT____: + case OPT__sysroot_: + /* Ignore these. */ + continue; + default: + if (save_decoded_options[j].orig_option_with_args_text[0] != '-') + continue; + switch (save_decoded_options[j].orig_option_with_args_text[1]) + { + case 'M': + case 'i': + case 'W': + continue; + case 'n': + if (save_decoded_options[j].orig_option_with_args_text[2] + == 'o') + continue; + break; + case 'f': + if (strncmp (save_decoded_options[j].orig_option_with_args_text + + 2, "dump", 4) == 0) + continue; + break; + default: + break; + } + VEC_safe_push (dchar_p, heap, switches, + save_decoded_options[j].orig_option_with_args_text); + len += strlen (save_decoded_options[j].orig_option_with_args_text) + + 1; + break; + } + + len += plen + 1; + producer_and_switches = XALLOCAVEC (char, len + 1); + tail = producer_and_switches; + memcpy (tail, producer, plen); + tail += plen; + FOR_EACH_VEC_ELT (dchar_p, switches, j, p) + { + len = strlen (p); + *tail = ' '; + memcpy (tail + 1, p, len); + tail += len + 1; + } + *tail = '\0'; + add_AT_string (die, DW_AT_producer, producer_and_switches); + VEC_free (dchar_p, heap, switches); + } + else + { #ifdef MIPS_DEBUGGING_INFO - /* The MIPS/SGI compilers place the 'cc' command line options in the producer - string. The SGI debugger looks for -g, -g1, -g2, or -g3; if they do - not appear in the producer string, the debugger reaches the conclusion - that the object file is stripped and has no debugging information. - To get the MIPS/SGI debugger to believe that there is debugging - information in the object file, we add a -g to the producer string. */ - if (debug_info_level > DINFO_LEVEL_TERSE) - strcat (producer, " -g"); + /* The MIPS/SGI compilers place the 'cc' command line options in the + producer string. The SGI debugger looks for -g, -g1, -g2, or -g3; + if they do not appear in the producer string, the debugger reaches + the conclusion that the object file is stripped and has no debugging + information. To get the MIPS/SGI debugger to believe that there is + debugging information in the object file, we add a -g to the producer + string. */ + if (debug_info_level > DINFO_LEVEL_TERSE) + strcat (producer, " -g"); #endif - add_AT_string (die, DW_AT_producer, producer); + add_AT_string (die, DW_AT_producer, producer); + } /* If our producer is LTO try to figure out a common language to use from the global list of translation units. */ --- gcc/Makefile.in.jj 2011-07-11 18:34:37.297452455 +0200 +++ gcc/Makefile.in 2011-07-12 21:16:34.594796181 +0200 @@ -2968,7 +2968,7 @@ dwarf2out.o : dwarf2out.c $(CONFIG_H) $( $(GGC_H) $(EXCEPT_H) dwarf2asm.h $(TM_P_H) langhooks.h $(HASHTAB_H) \ gt-dwarf2out.h $(TARGET_H) $(CGRAPH_H) $(MD5_H) $(INPUT_H) $(FUNCTION_H) \ $(GIMPLE_H) $(TREE_PASS_H) $(TREE_FLOW_H) $(CFGLAYOUT_H) \ - tree-pretty-print.h $(COMMON_TARGET_H) + tree-pretty-print.h $(COMMON_TARGET_H) $(OPTS_H) dwarf2cfi.o : dwarf2cfi.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ version.h $(RTL_H) $(FUNCTION_H) $(DWARF2_H) dwarf2asm.h dwarf2out.h \ $(GGC_H) $(TM_P_H) $(TARGET_H) $(TREE_PASS_H) --- gcc/testsuite/lib/dg-pch.exp.jj 2011-01-03 18:58:03.000000000 +0100 +++ gcc/testsuite/lib/dg-pch.exp 2011-07-12 23:13:50.943670171 +0200 @@ -39,7 +39,7 @@ proc dg-flags-pch { subdir test otherfla set dg-do-what-default precompile catch { file_on_host delete "$bname$suffix" } gcc_copy_files "[file rootname $test]${suffix}s" "$bname$suffix" - dg-test -keep-output "./$bname$suffix" "$otherflags $flags" "" + dg-test -keep-output "./$bname$suffix" "-gno-record-gcc-switches $otherflags $flags" "" # For the rest, the default is to compile to .s. set dg-do-what-default compile @@ -50,14 +50,14 @@ proc dg-flags-pch { subdir test otherfla # Ensure that the PCH file is used, not the original header. file_on_host delete "$bname$suffix" - dg-test -keep-output $test "$otherflags $flags -I." "" + dg-test -keep-output $test "-gno-record-gcc-switches $otherflags $flags -I." "" file_on_host delete "$bname$suffix.gch" if { !$have_errs } { if { [ file_on_host exists "$bname.s" ] } { remote_upload host "$bname.s" "$bname.s-gch" remote_download host "$bname.s-gch" gcc_copy_files "[file rootname $test]${suffix}s" "$bname$suffix" - dg-test -keep-output $test "$otherflags $flags -I." "" + dg-test -keep-output $test "-gno-record-gcc-switches $otherflags $flags -I." "" remote_upload host "$bname.s" set tmp [ diff "$bname.s" "$bname.s-gch" ] if { $tmp == 0 } {