On Mon, 20 Jan 2020 at 15:44, Richard Biener <richard.guent...@gmail.com> wrote: > > On Wed, Jan 8, 2020 at 11:20 AM Prathamesh Kulkarni > <prathamesh.kulka...@linaro.org> wrote: > > > > On Tue, 5 Nov 2019 at 17:38, Richard Biener <richard.guent...@gmail.com> > > wrote: > > > > > > On Tue, Nov 5, 2019 at 12:17 AM Kugan Vivekanandarajah > > > <kugan.vivekanandara...@linaro.org> wrote: > > > > > > > > Hi, > > > > Thanks for the review. > > > > > > > > On Tue, 5 Nov 2019 at 03:57, H.J. Lu <hjl.to...@gmail.com> wrote: > > > > > > > > > > On Sun, Nov 3, 2019 at 6:45 PM Kugan Vivekanandarajah > > > > > <kugan.vivekanandara...@linaro.org> wrote: > > > > > > > > > > > > Thanks for the reviews. > > > > > > > > > > > > > > > > > > On Sat, 2 Nov 2019 at 02:49, H.J. Lu <hjl.to...@gmail.com> wrote: > > > > > > > > > > > > > > On Thu, Oct 31, 2019 at 6:33 PM Kugan Vivekanandarajah > > > > > > > <kugan.vivekanandara...@linaro.org> wrote: > > > > > > > > > > > > > > > > On Wed, 30 Oct 2019 at 03:11, H.J. Lu <hjl.to...@gmail.com> > > > > > > > > wrote: > > > > > > > > > > > > > > > > > > On Sun, Oct 27, 2019 at 6:33 PM Kugan Vivekanandarajah > > > > > > > > > <kugan.vivekanandara...@linaro.org> wrote: > > > > > > > > > > > > > > > > > > > > Hi Richard, > > > > > > > > > > > > > > > > > > > > Thanks for the review. > > > > > > > > > > > > > > > > > > > > On Wed, 23 Oct 2019 at 23:07, Richard Biener > > > > > > > > > > <richard.guent...@gmail.com> wrote: > > > > > > > > > > > > > > > > > > > > > > On Mon, Oct 21, 2019 at 10:04 AM Kugan Vivekanandarajah > > > > > > > > > > > <kugan.vivekanandara...@linaro.org> wrote: > > > > > > > > > > > > > > > > > > > > > > > > Hi Richard, > > > > > > > > > > > > > > > > > > > > > > > > Thanks for the pointers. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > On Fri, 11 Oct 2019 at 22:33, Richard Biener > > > > > > > > > > > > <richard.guent...@gmail.com> wrote: > > > > > > > > > > > > > > > > > > > > > > > > > > On Fri, Oct 11, 2019 at 6:15 AM Kugan Vivekanandarajah > > > > > > > > > > > > > <kugan.vivekanandara...@linaro.org> wrote: > > > > > > > > > > > > > > > > > > > > > > > > > > > > Hi Richard, > > > > > > > > > > > > > > Thanks for the review. > > > > > > > > > > > > > > > > > > > > > > > > > > > > On Wed, 2 Oct 2019 at 20:41, Richard Biener > > > > > > > > > > > > > > <richard.guent...@gmail.com> wrote: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > On Wed, Oct 2, 2019 at 10:39 AM Kugan > > > > > > > > > > > > > > > Vivekanandarajah > > > > > > > > > > > > > > > <kugan.vivekanandara...@linaro.org> wrote: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Hi, > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > As mentioned in the PR, attached patch adds > > > > > > > > > > > > > > > > COLLECT_AS_OPTIONS for > > > > > > > > > > > > > > > > passing assembler options specified with -Wa, > > > > > > > > > > > > > > > > to the link-time driver. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > The proposed solution only works for uniform > > > > > > > > > > > > > > > > -Wa options across all > > > > > > > > > > > > > > > > TUs. As mentioned by Richard Biener, supporting > > > > > > > > > > > > > > > > non-uniform -Wa flags > > > > > > > > > > > > > > > > would require either adjusting partitioning > > > > > > > > > > > > > > > > according to flags or > > > > > > > > > > > > > > > > emitting multiple object files from a single > > > > > > > > > > > > > > > > LTRANS CU. We could > > > > > > > > > > > > > > > > consider this as a follow up. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Bootstrapped and regression tests on > > > > > > > > > > > > > > > > arm-linux-gcc. Is this OK for trunk? > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > While it works for your simple cases it is > > > > > > > > > > > > > > > unlikely to work in practice since > > > > > > > > > > > > > > > your implementation needs the assembler options > > > > > > > > > > > > > > > be present at the link > > > > > > > > > > > > > > > command line. I agree that this might be the way > > > > > > > > > > > > > > > for people to go when > > > > > > > > > > > > > > > they face the issue but then it needs to be > > > > > > > > > > > > > > > documented somewhere > > > > > > > > > > > > > > > in the manual. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > That is, with COLLECT_AS_OPTION (why singular? > > > > > > > > > > > > > > > I'd expected > > > > > > > > > > > > > > > COLLECT_AS_OPTIONS) available to cc1 we could > > > > > > > > > > > > > > > stream this string > > > > > > > > > > > > > > > to lto_options and re-materialize it at link time > > > > > > > > > > > > > > > (and diagnose mismatches > > > > > > > > > > > > > > > even if we like). > > > > > > > > > > > > > > OK. I will try to implement this. So the idea is if > > > > > > > > > > > > > > we provide > > > > > > > > > > > > > > -Wa,options as part of the lto compile, this should > > > > > > > > > > > > > > be available > > > > > > > > > > > > > > during link time. Like in: > > > > > > > > > > > > > > > > > > > > > > > > > > > > arm-linux-gnueabihf-gcc -march=armv7-a -mthumb -O2 > > > > > > > > > > > > > > -flto > > > > > > > > > > > > > > -Wa,-mimplicit-it=always,-mthumb -c test.c > > > > > > > > > > > > > > arm-linux-gnueabihf-gcc -flto test.o > > > > > > > > > > > > > > > > > > > > > > > > > > > > I am not sure where should we stream this. > > > > > > > > > > > > > > Currently, cl_optimization > > > > > > > > > > > > > > has all the optimization flag provided for compiler > > > > > > > > > > > > > > and it is > > > > > > > > > > > > > > autogenerated and all the flags are integer values. > > > > > > > > > > > > > > Do you have any > > > > > > > > > > > > > > preference or example where this should be done. > > > > > > > > > > > > > > > > > > > > > > > > > > In lto_write_options, I'd simply append the contents > > > > > > > > > > > > > of COLLECT_AS_OPTIONS > > > > > > > > > > > > > (with -Wa, prepended to each of them), then recover > > > > > > > > > > > > > them in lto-wrapper > > > > > > > > > > > > > for each TU and pass them down to the LTRANS compiles > > > > > > > > > > > > > (if they agree > > > > > > > > > > > > > for all TUs, otherwise I'd warn and drop them). > > > > > > > > > > > > > > > > > > > > > > > > Attached patch streams it and also make sure that the > > > > > > > > > > > > options are the > > > > > > > > > > > > same for all the TUs. Maybe it is a bit restrictive. > > > > > > > > > > > > > > > > > > > > > > > > What is the best place to document COLLECT_AS_OPTIONS. > > > > > > > > > > > > We don't seem > > > > > > > > > > > > to document COLLECT_GCC_OPTIONS anywhere ? > > > > > > > > > > > > > > > > > > > > > > Nowhere, it's an implementation detail then. > > > > > > > > > > > > > > > > > > > > > > > Attached patch passes regression and also fixes the > > > > > > > > > > > > original ARM > > > > > > > > > > > > kernel build issue with tumb2. > > > > > > > > > > > > > > > > > > > > > > Did you try this with multiple assembler options? I see > > > > > > > > > > > you stream > > > > > > > > > > > them as -Wa,-mfpu=xyz,-mthumb but then compare the whole > > > > > > > > > > > option strings so a mismatch with -Wa,-mthumb,-mfpu=xyz > > > > > > > > > > > would be > > > > > > > > > > > diagnosed. If there's a spec induced -Wa option do we > > > > > > > > > > > get to see > > > > > > > > > > > that as well? I can imagine -march=xyz enabling a -Wa > > > > > > > > > > > option > > > > > > > > > > > for example. > > > > > > > > > > > > > > > > > > > > > > + *collect_as = XNEWVEC (char, strlen > > > > > > > > > > > (args_text) + 1); > > > > > > > > > > > + strcpy (*collect_as, args_text); > > > > > > > > > > > > > > > > > > > > > > there's strdup. Btw, I'm not sure why you don't simply > > > > > > > > > > > leave > > > > > > > > > > > the -Wa option in the merged options [individually] and > > > > > > > > > > > match > > > > > > > > > > > them up but go the route of comparing strings and > > > > > > > > > > > carrying that > > > > > > > > > > > along separately. I think that would be much better. > > > > > > > > > > > > > > > > > > > > Is attached patch which does this is OK? > > > > > > > > > > > > > > > > > > > > > > > > > > > > Don't you need to also handle -Xassembler? Since -Wa, doesn't > > > > > > > > > work with comma in > > > > > > > > > assembler options, like -mfoo=foo1,foo2, one needs to use > > > > > > > > > > > > > > > > > > -Xassembler -mfoo=foo1,foo2 > > > > > > > > > > > > > > > > > > to pass -mfoo=foo1,foo2 to assembler. > > > > > > > > > > > > > > > > > > > > > > > > gcc -flto -O2 -Wa,-mcpu=zzz1 -mcpu=xxx1 -c foo.c > > > > > > > > gcc -flto -O2 -Wa,-mcpu=zzz2 -mcpu=xxx2 -c bar.c > > > > > > > > > > > > > > > > What should be the option we should provide for the final > > > > > > > > gcc -flto foo.o bar.o -o out > > > > > > > > > > > > > > > > I think our ultimate aim is to handle this in LTO partitioning. > > > > > > > > That > > > > > > > > is, we should create partitioning such that each partition has > > > > > > > > the > > > > > > > > same -Wa options. This could also handle -Xassembler > > > > > > > > -mfoo=foo1,foo2 > > > > > > > > which H.J. Lu wanted. We need to modify the heuristics and do > > > > > > > > some > > > > > > > > performance testing. > > > > > > > > > > > > > > > > In the meantime we could push a simpler solution which is to > > > > > > > > accept > > > > > > > > -Wa option if they are identical. This would fix at least some > > > > > > > > of the > > > > > > > > reported cases. Trying to work out what is compatible options, > > > > > > > > even if > > > > > > > > we ask the back-end to do this, is not a straightforward > > > > > > > > strategy and > > > > > > > > can be a maintenance nightmare. Unless we can query GNU AS > > > > > > > > somehow. If > > > > > > > > I am missing something please let me know. > > > > > > > > > > > > > > +/* Store switches specified for as with -Wa in COLLECT_AS_OPTIONS > > > > > > > + and place that in the environment. */ > > > > > > > +static void > > > > > > > +putenv_COLLECT_AS_OPTIONS (vec<char_p> vec) > > > > > > > +{ > > > > > > > + unsigned ix; > > > > > > > + char *opt; > > > > > > > + int len = vec.length (); > > > > > > > + > > > > > > > + if (!len) > > > > > > > + return; > > > > > > > + > > > > > > > + obstack_init (&collect_obstack); > > > > > > > + obstack_grow (&collect_obstack, "COLLECT_AS_OPTIONS=", > > > > > > > + sizeof ("COLLECT_AS_OPTIONS=") - 1); > > > > > > > + obstack_grow (&collect_obstack, "-Wa,", strlen ("-Wa,")); > > > > > > > + > > > > > > > + FOR_EACH_VEC_ELT (vec, ix, opt) > > > > > > > + { > > > > > > > + obstack_grow (&collect_obstack, opt, strlen (opt)); > > > > > > > + --len; > > > > > > > + if (len) > > > > > > > + obstack_grow (&collect_obstack, ",", strlen (",")); > > > > > > > + } > > > > > > > + > > > > > > > + xputenv (XOBFINISH (&collect_obstack, char *)); > > > > > > > > > > > > > > This missed the null terminator. > > > > > > > > > > > > Attached patch addresses the review comments I got so far. > > > > > > > > > > > > > > > > + if (len) > > > > > + obstack_grow (&collect_obstack, ",", strlen (",")); > > > > > > > > > > Why not sizeof (",") - 1? > > > > I guess I copied and pasted it from elsewhere else. We seem to use > > > > both. I have changed it now. > > > > > > > > > > > > > > diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c > > > > > index 9a7bbd0c022..148c52906d1 100644 > > > > > --- a/gcc/lto-wrapper.c > > > > > +++ b/gcc/lto-wrapper.c > > > > > @@ -253,6 +253,11 @@ merge_and_complain (struct cl_decoded_option > > > > > **decoded_options, > > > > > break; > > > > > > > > > > default: > > > > > + if (foption->opt_index == OPT_Wa_) > > > > > + { > > > > > + append_option (decoded_options, decoded_options_count, > > > > > foption); > > > > > + break; > > > > > + } > > > > > if (!(cl_options[foption->opt_index].flags & CL_TARGET)) > > > > > break; > > > > > > > > > > Why not use "case OPT_Wa_:" here? > > > > Done. > > > > > > > > > > For > > > > > > > > > > + static const char *collect_as; > > > > > + for (unsigned int j = 1; j < count; ++j) > > > > > + { > > > > > + struct cl_decoded_option *option = &opts[j]; > > > > > + if (j == 1) > > > > > + collect_as = NULL; > > > > > > > > > > why not simply > > > > > > > > > > const char *collect_as = NULL? > > > > > > > > I wanted to make sure that if we call this from multiple places, it > > > > still works. I guess it is still going to be the same. I have changed > > > > it now as you have suggested. > > > > > > > > Is this revised patch OK? I will do a fresh bootstrap and regression > > > > testing before committing. > > > > > > In putenv_COLLECT_AS_OPTIONS you'll happily make > > > -Wa,-march=foo,bar out of -Xassembler -march=foo,bar which > > > will later cause us to fail to assemble with unknown assembler options. > > > May I suggest to instead always use -Xassembler syntax in > > > COLLECT_AS_OPTIONS? Please also make sure to quote > > > options the same way set_collect_gcc_options does > > > (with '', separated by spaces). Then the lto-opts.c part > > > becomes "easier" as you can simply copy the string to the > > > obstack without wrapping it again with append_to_collect_gcc_options. > > > > > > In lto-wrapper you then only have to handle OPT_Xassembler. > > > > > > You simply end up appending _all_ assembler options in order > > > of TUs processed by lto-wrapper to the final command (N times > > > even if exactly the same). I'm also not sure how you can check > > > for positional equivalence (or if we even should). With -Wa > > > we could compare the full option string but with separate -Xassembler > > > we're having a more difficult task here. OTOH your patch doesn't > > > do any comparing here. > > > > > > Your append_compiler_wa_options should be merged into > > > append_compiler_options, passing -Xassembler through. > > Hi Richard, > > Since Kugan has left Linaro (and GCC), I'd like to take up this task. > > I have modified his patch to always pass assembler options via -Xassembler. > > Does it look OK ? > > > > I am not sure how we should proceed with error-checking for Xassembler ? > > In lto-wrapper, I suppose, we can append all Xassembler options for a > > TU into a single string, and then > > do strcmp similar to previous patch(es) doing strcmp for -Wa options > > string, although not sure if that's a good idea. > > I think there are multiple issues with the main one being how to > actually interpret -Xassembler in the LTO context. > > First let me point out some bits in the COLLECT_AS_OPTIONS parts. > > + FOR_EACH_VEC_ELT (vec, ix, opt) > + { > + obstack_grow (&collect_obstack, "\'-Xassembler\' ", > + strlen ("\'-Xassembler\' ")); > > quoting of -Xassembler is not necessary. > > + obstack_1grow (&collect_obstack, '\''); > + obstack_grow (&collect_obstack, opt, strlen (opt)); > + obstack_grow (&collect_obstack, "\' ", 2); > > This adds a stray space after the last option. > > Note that COLLECT_AS_OPTIONS gives the impression of listing > assembler options but the above adds GCC driver options - assembler > options prepended by -Xassembler. IMHO we should drop the > -Xassembler emission from the above loop and simply emit the plain > assembler options. That requires adjustments to lto_write_options, > adding those -Xassembler options. > > + char *asm_opts = XOBFINISH (&collect_obstack, char *); > + xputenv (XOBFINISH (&collect_obstack, char *)); > + xputenv (asm_opts); > > That outputs the ENV twice. > > Note that we record things like --version or --help into > assembler_options but I'm not sure the merging of assembler > options should be affected on whether one TU was compiled with -v > or not. This might mean simply pruning those in lto-options.c > (not listing them in COLLECT_AS_OPTIONS wouldn't tell the truth). > > @@ -252,6 +252,10 @@ merge_and_complain (struct cl_decoded_option > **decoded_options, > case OPT_SPECIAL_input_file: > break; > > + case OPT_Xassembler: > + append_option (decoded_options, decoded_options_count, foption); > + break; > + > > this adds the same option over-and-over again, possibly becoming unwieldly. > Most of the function also assumes that option position isn't important > which might or might not be true. So I think a better course of action > would be to not handle Xassembler in the above loop but do a separate > one checking 1:1 equality of passed assembler options like > > /* Verify -Xassembler options are the same on all TUs. */ > j = 0; > i = 0; > unsigned Xascount = 0; > while (j < *decoded_options_count && i < fdeconded_options_count) > { > while (fdecoded_options[i].opt_index != OPT_Xassembler) ++i; > same for *decoded_options > if (stray Xassembler on one side) > fatal_error (...); > if (strcmp (...) != 0) > fatal_error (...); > } > > which means we use the -Xassembler options from the first TU and > above only verify those match those from all other TUs. Hi Richard, Thanks for the suggestions, I tried to address them in the attached patch. It now gives errors on following cases during link command:
1] gcc -O -flto -c -Xassembler -mfoo f1.c gcc -O -flto -c f2.c gcc -O -flto f1.o f2.o 2] gcc -O -flto -c -Xassembler -mfoo f1.c gcc -O -flto -c -Xassembler -mbar f2.c gcc -O -flto f1.o f2.o 3] gcc -O -flto -c -Xassembler -mfoo -Xassembler -mbar f1.c gcc -O -flto -c -Xassembler -mbar -Xassembler -mfoo f2.c gcc -O -flto f1.o f2.o 4] gcc -O -flto -c f1.c gcc -O -flto -Xassembler -mfoo f1.c gcc -O -flto f1.o f2.o 5] gcc -O -flto -Xassembler -mfoo f1.c gcc -O -flto -Xassembler -mfoo f2.c gcc -O -flto -Xassembler -mbar f1.o f2.o The following correct case works: gcc -O -flto -Xassembler -mfoo f1.c gcc -O -flto -Xassembler -mfoo f2.c gcc -O -flto f1.o f2.o Could you please suggest how to add the above cases in dejaGNU format ? I am not sure how to write multiple files test with dejaGNU. Also, do you think it's better if we append xassembler options to COLLECT_GCC itself rather than maintaining COLLECT_AS_OPTIONS with "Xassembler" prepended ? Because in both lto_write_options, and run_gcc, I am reconstructing "-Xassembler" <opt> for each opt in COLLECT_AS_OPTIONS. I am not quite sure how Xassembler options were added to fdecoded_options because I am not appending them explicitly. IIUC, find_and_merge_options will add -Xassembler to fdecoded_options when it's NULL ? if (!fdecoded_options) { fdecoded_options = f2decoded_options; fdecoded_options_count = f2decoded_options_count; } since merge_and_complain does not handle OPT_Xassembler. Thanks, Prathamesh > > Richard. > > > Thanks, > > Prathamesh > > > > > > Thanks, > > > Richard. > > > > > > > Thanks, > > > > Kugan > > > > > > > > > > > > > > > > > > > H.J.
diff --git a/gcc/gcc.c b/gcc/gcc.c index effc384f3ef..9f790db0daf 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -5242,6 +5242,34 @@ do_specs_vec (vec<char_p> vec) } } +/* Add options passed via -Xassembler or -Wa to COLLECT_AS_OPTIONS. */ + +static void +putenv_COLLECT_AS_OPTIONS (vec<char_p> vec) +{ + if (vec.is_empty ()) + return; + + obstack_init (&collect_obstack); + obstack_grow (&collect_obstack, "COLLECT_AS_OPTIONS=", + strlen ("COLLECT_AS_OPTIONS=")); + + char *opt; + unsigned ix; + + FOR_EACH_VEC_ELT (vec, ix, opt) + { + obstack_1grow (&collect_obstack, '\''); + obstack_grow (&collect_obstack, opt, strlen (opt)); + obstack_1grow (&collect_obstack, '\''); + if (ix < vec.length () - 1) + obstack_1grow(&collect_obstack, ' '); + } + + obstack_1grow (&collect_obstack, '\0'); + xputenv (XOBFINISH (&collect_obstack, char *)); +} + /* Process the sub-spec SPEC as a portion of a larger spec. This is like processing a whole spec except that we do not initialize at the beginning and we do not supply a @@ -7363,6 +7391,7 @@ driver::main (int argc, char **argv) global_initializations (); build_multilib_strings (); set_up_specs (); + putenv_COLLECT_AS_OPTIONS (assembler_options); putenv_COLLECT_GCC (argv[0]); maybe_putenv_COLLECT_LTO_WRAPPER (); maybe_putenv_OFFLOAD_TARGETS (); diff --git a/gcc/lto-opts.c b/gcc/lto-opts.c index 90bfde5a8fd..595be137ba9 100644 --- a/gcc/lto-opts.c +++ b/gcc/lto-opts.c @@ -163,6 +163,22 @@ lto_write_options (void) append_to_collect_gcc_options (&temporary_obstack, &first_p, option->canonical_option[j]); } + + char *collect_as_options = getenv ("COLLECT_AS_OPTIONS"); + if (collect_as_options) + { + char *saveptr; + char *tok = strtok_r (collect_as_options, " ", &saveptr); + + while (tok) + { + obstack_grow (&temporary_obstack, " '-Xassembler' ", + strlen (" '-Xassembler' ")); + obstack_grow (&temporary_obstack, tok, strlen (tok)); + tok = strtok_r (NULL, " ", &saveptr); + } + } + obstack_grow (&temporary_obstack, "\0", 1); args = XOBFINISH (&temporary_obstack, char *); lto_write_data (args, strlen (args) + 1); diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c index fe8f292f877..624ad096441 100644 --- a/gcc/lto-wrapper.c +++ b/gcc/lto-wrapper.c @@ -48,6 +48,7 @@ along with GCC; see the file COPYING3. If not see #include "simple-object.h" #include "lto-section-names.h" #include "collect-utils.h" +#include <algorithm> /* Environment variable, used for passing the names of offload targets from GCC driver to lto-wrapper. */ @@ -624,6 +625,7 @@ append_compiler_options (obstack *argv_obstack, struct cl_decoded_option *opts, case OPT_Ofast: case OPT_Og: case OPT_Os: + case OPT_Xassembler: break; default: @@ -967,6 +969,10 @@ find_crtoffloadtable (void) free_array_of_ptrs ((void **) paths, n_paths); } +/* Used for storing Xassembler opts passed to first TU. */ +static struct cl_decoded_option *xassembler_opts = NULL; +static unsigned xassembler_opts_count = 0; + /* A subroutine of run_gcc. Examine the open file FD for lto sections with name prefix PREFIX, at FILE_OFFSET, and store any options we find in OPTS and OPT_COUNT. Return true if we found a matchingn section, false @@ -976,7 +982,8 @@ find_crtoffloadtable (void) static bool find_and_merge_options (int fd, off_t file_offset, const char *prefix, struct cl_decoded_option **opts, - unsigned int *opt_count, const char *collect_gcc) + unsigned int *opt_count, const char *collect_gcc, + bool first_tu = false) { off_t offset, length; char *data; @@ -986,6 +993,10 @@ find_and_merge_options (int fd, off_t file_offset, const char *prefix, struct cl_decoded_option *fdecoded_options = *opts; unsigned int fdecoded_options_count = *opt_count; + /* Store Xassembler opts passed to current TU. */ + struct cl_decoded_option *curr_xopts; + unsigned curr_xopts_count = 0; + simple_object_read *sobj; sobj = simple_object_start_read (fd, file_offset, "__GNU_LTO", &errmsg, &err); @@ -1023,10 +1034,42 @@ find_and_merge_options (int fd, off_t file_offset, const char *prefix, &fdecoded_options_count, f2decoded_options, f2decoded_options_count); + /* Collect -Xassembler options of current TU in curr_xopts. */ + for (unsigned i = 0; i < f2decoded_options_count; i++) + if (f2decoded_options[i].opt_index == OPT_Xassembler) + append_option (&curr_xopts, &curr_xopts_count, &f2decoded_options[i]); + fopts += strlen (fopts) + 1; } while (fopts - data < length); + /* xassembler_opts might be non-null for first TU + if -Xassembler is passed as cmdline option during link time. */ + if (first_tu && !xassembler_opts) + { + xassembler_opts = curr_xopts; + xassembler_opts_count = curr_xopts_count; + } + else + { + unsigned min_opts_count + = std::min (xassembler_opts_count, curr_xopts_count); + for (unsigned i = 0; i < min_opts_count; i++) + if (strcmp (xassembler_opts[i].arg, curr_xopts[i].arg)) + fatal_error (input_location, + "Options to Xassembler do not match: %s, %s.", + xassembler_opts[i].arg, curr_xopts[i].arg); + + for (unsigned i = min_opts_count; i < xassembler_opts_count; i++) + fatal_error (input_location, + "Extra option to Xassembler: %s.", + xassembler_opts[i].arg); + + for (unsigned i = min_opts_count; i < curr_xopts_count; i++) + fatal_error (input_location, + "Extra option %s to Xassembler.", curr_xopts[i].arg); + } + free (data); simple_object_release_read (sobj); *opts = fdecoded_options; @@ -1251,7 +1294,8 @@ run_gcc (unsigned argc, char *argv[]) const char **argv_ptr; char *list_option_full = NULL; const char *linker_output = NULL; - const char *collect_gcc, *collect_gcc_options; + const char *collect_gcc; + char *collect_gcc_options; int parallel = 0; int jobserver = 0; int auto_parallel = 0; @@ -1281,15 +1325,48 @@ run_gcc (unsigned argc, char *argv[]) if (!collect_gcc_options) fatal_error (input_location, "environment variable %<COLLECT_GCC_OPTIONS%> must be set"); + + char *collect_as_options = getenv ("COLLECT_AS_OPTIONS"); + + /* Prepend -Xassembler to each option, and append the string + to collect_gcc_options. */ + if (collect_as_options) + { + obstack temporary_obstack; + obstack_init (&temporary_obstack); + + char *saveptr; + char *tok = strtok_r (collect_as_options, " ", &saveptr); + + while (tok) + { + obstack_grow (&temporary_obstack, " '-Xassembler' ", + strlen (" '-Xassembler' ")); + obstack_grow (&temporary_obstack, tok, strlen (tok)); + tok = strtok_r (NULL, " ", &saveptr); + } + + obstack_1grow (&temporary_obstack, '\0'); + + char *xassembler_opts_string + = XOBFINISH (&temporary_obstack, char *); + strcat (collect_gcc_options, xassembler_opts_string); + } + get_options_from_collect_gcc_options (collect_gcc, collect_gcc_options, &decoded_options, &decoded_options_count); + for (unsigned i = 0; i < decoded_options_count; i++) + if (decoded_options[i].opt_index == OPT_Xassembler) + append_option (&xassembler_opts, &xassembler_opts_count, + &decoded_options[i]); + /* Allocate array for input object files with LTO IL, and for possible preceding arguments. */ lto_argv = XNEWVEC (char *, argc); ltoobj_argv = XNEWVEC (char *, argc); - + bool first_tu = true; /* Look at saved options in the IL files. */ for (i = 1; i < argc; ++i) { @@ -1334,11 +1411,12 @@ run_gcc (unsigned argc, char *argv[]) if (find_and_merge_options (fd, file_offset, LTO_SECTION_NAME_PREFIX, &fdecoded_options, &fdecoded_options_count, - collect_gcc)) + collect_gcc, first_tu)) { have_lto = true; ltoobj_argv[ltoobj_argc++] = argv[i]; } + first_tu = false; close (fd); } diff --git a/gcc/testsuite/gcc.target/arm/pr78353-1.c b/gcc/testsuite/gcc.target/arm/pr78353-1.c new file mode 100644 index 00000000000..aec0fb0cbfd --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/pr78353-1.c @@ -0,0 +1,8 @@ +/* { dg-do link } */ +/* { dg-options "-march=armv7-a -mthumb -O2 -flto -Wa,-mimplicit-it=always" } */ + +int main(int x) +{ + asm("teq %0, #0; addne %0, %0, #1" : "=r" (x)); + return x; +} diff --git a/gcc/testsuite/gcc.target/arm/pr78353-2.c b/gcc/testsuite/gcc.target/arm/pr78353-2.c new file mode 100644 index 00000000000..18a90e8834e --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/pr78353-2.c @@ -0,0 +1,9 @@ +/* { dg-do link } */ +/* { dg-options "-march=armv7-a -mthumb -O2 -flto -Wa,-mimplicit-it=always,-mthumb" } */ + +int main(int x) +{ + asm("teq %0, #0; addne %0, %0, #1" : "=r" (x)); + return x; +} +