This is a nasty hack, but I noticed a lot of time spent executing the linker within jit.dg/test-benchmark, with link lines like:
run_embedded_ld: 24 args argv[0]: ld argv[1]: --eh-frame-hdr argv[2]: -m argv[3]: elf_x86_64 argv[4]: -shared argv[5]: -o argv[6]: /tmp/libgccjit-mxDkPa/fake.so argv[7]: /lib/../lib64/crti.o argv[8]: /home/david/coding-3/gcc-git-jit-benchmarks/build-jit/gcc/crtbeginS.o argv[9]: -L/lib/../lib64 argv[10]: -L/usr/lib/../lib64 argv[11]: -L/home/david/coding-3/gcc-git-jit-benchmarks/build-jit/gcc argv[12]: /tmp/ccSlluGf.o argv[13]: -lgcc argv[14]: --as-needed argv[15]: -lgcc_s argv[16]: --no-as-needed argv[17]: -lc argv[18]: -lgcc argv[19]: --as-needed argv[20]: -lgcc_s argv[21]: --no-as-needed argv[22]: /home/david/coding-3/gcc-git-jit-benchmarks/build-jit/gcc/crtendS.o argv[23]: /lib/../lib64/crtn.o Much of this appears to be unnecessary; if I purge the link line to just: argv[0]: ld argv[1]: --eh-frame-hdr argv[2]: -m argv[3]: elf_x86_64 argv[4]: -shared argv[5]: -o argv[6]: /tmp/libgccjit-mxDkPa/fake.so argv[7]: /tmp/ccSlluGf.o the benchmark gets a 2x speedup. Clearly this patch isn't appropriate as-is; when are the various objects/libraries above that I hacked out actually needed? Is there a way programmatically determine what's needed? gcc/ChangeLog: * gcc.c (purge_ld_arg): HACK! Purge the arguments to the linker. (run_embedded_ld): Likewise. --- gcc/gcc.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/gcc/gcc.c b/gcc/gcc.c index ed92c7d..dc036e8 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -2887,6 +2887,25 @@ static int run_embedded_as (int argc, const char **argv) #ifdef HAVE_LIBLD +/* HACK! */ +static bool +purge_ld_arg (const char *arg) +{ + /* Hack away "-l", e.g. -lgcc, -lgcc_s, -lc. */ + if (0 == strncmp (arg, "-l", 2)) + return true; + + /* If we can survive without -l, we don't need -L. */ + if (0 == strncmp (arg, "-L", 2)) + return true; + + /* Hack away crti.o, crtbeginS.o, crtendS.o, crtn.o. */ + if (strstr (arg, "/crt")) + return true; + + return false; +} + /* Invoke ld_main, passing in the driver's timer so that the linker code can record timing information into it. */ @@ -2902,6 +2921,29 @@ static int run_embedded_ld (int argc, const char **argv) fprintf (stderr, " argv[%i]: %s\n", i, argv[i]); } + /* FIXME: Hack. Purge the linker line, to see if we can speed things + up. */ + int idx = 0; + while (idx < argc) + { + if (purge_ld_arg (argv[idx])) + { + memmove (&argv[idx], &argv[idx + 1], + sizeof (char *) * (argc - (idx + 1))); + argc--; + } + else + idx++; + } + + if (0) + { + fprintf (stderr, "run_embedded_ld: %i args\n", argc); + for (int i = 0; i < argc; i++) + fprintf (stderr, " argv[%i]: %s\n", i, argv[i]); + } + + ctimershim ct (driver_timer, timer::ITEM_DICT_EMBEDDED_LD); return ld_main (argc, argv, -- 1.8.5.3