diff --git a/lld/MinGW/Driver.cpp b/lld/MinGW/Driver.cpp --- a/lld/MinGW/Driver.cpp +++ b/lld/MinGW/Driver.cpp @@ -282,6 +282,8 @@ add("-align:" + StringRef(a->getValue())); if (auto *a = args.getLastArg(OPT_heap)) add("-heap:" + StringRef(a->getValue())); + if (auto *a = args.getLastArg(OPT_threads)) + add("-threads:" + StringRef(a->getValue())); if (auto *a = args.getLastArg(OPT_o)) add("-out:" + StringRef(a->getValue())); @@ -420,6 +422,18 @@ if (auto *arg = args.getLastArg(OPT_plugin_opt_mcpu_eq)) add("-mllvm:-mcpu=" + StringRef(arg->getValue())); + if (auto *arg = args.getLastArg(OPT_thinlto_jobs_eq)) + add("-opt:lldltojobs=" + StringRef(arg->getValue())); + if (auto *arg = args.getLastArg(OPT_lto_O)) + add("-opt:lldlto=" + StringRef(arg->getValue())); + if (auto *arg = args.getLastArg(OPT_lto_CGO)) + add("-opt:lldltocgo=" + StringRef(arg->getValue())); + if (auto *arg = args.getLastArg(OPT_plugin_opt_dwo_dir_eq)) + add("-dwodir:" + StringRef(arg->getValue())); + if (args.hasArg(OPT_lto_cs_profile_generate)) + add("-lto-cs-profile-generate"); + if (auto *arg = args.getLastArg(OPT_lto_cs_profile_file)) + add("-lto-cs-profile-file:" + StringRef(arg->getValue())); for (auto *a : args.filtered(OPT_plugin_opt_eq_minus)) add("-mllvm:-" + StringRef(a->getValue())); diff --git a/lld/MinGW/Options.td b/lld/MinGW/Options.td --- a/lld/MinGW/Options.td +++ b/lld/MinGW/Options.td @@ -4,12 +4,25 @@ class J: Joined<["--", "-"], name>; class S: Separate<["--", "-"], name>; +// Convenience classes for long options which only accept two dashes. For lld +// specific or newer long options, we prefer two dashes to avoid collision with +// short options. For many others, we have to accept both forms to be compatible +// with GNU ld. +class FF : Flag<["--"], name>; +class JJ: Joined<["--"], name>; + multiclass Eq { def NAME: Separate<["--", "-"], name>; def NAME # _eq: Joined<["--", "-"], name # "=">, Alias(NAME)>, HelpText; } +multiclass EEq { + def NAME: Separate<["--"], name>; + def NAME # _eq: Joined<["--"], name # "=">, Alias(NAME)>, + HelpText; +} + multiclass EqLong { def NAME: Separate<["--"], name>; def NAME # _eq: Joined<["--"], name # "=">, Alias(NAME)>, @@ -119,6 +132,10 @@ "Write a tar file containing input files and command line options to reproduce link">; defm require_defined: Eq<"require-defined", "Force symbol to be added to symbol table as an undefined one">; +defm threads + : EEq<"threads", + "Number of threads. '1' disables multi-threading. By default all " + "available hardware threads are used">; defm tsaware: B_disable<"tsaware", "Set the 'Terminal Server aware' flag", "Don't set the 'Terminal Server aware' flag">; defm undefined: Eq<"undefined", "Include symbol in the link, if available">; @@ -131,9 +148,33 @@ defm wrap: Eq<"wrap", "Use wrapper functions for symbol">, MetaVarName<"">; + +def lto_O: JJ<"lto-O">, MetaVarName<"">, + HelpText<"Optimization level for LTO">; +def lto_CGO: JJ<"lto-CGO">, MetaVarName<"">, + HelpText<"Codegen optimization level for LTO">; +def lto_cs_profile_generate: FF<"lto-cs-profile-generate">, + HelpText<"Perform context sensitive PGO instrumentation">; +def lto_cs_profile_file: JJ<"lto-cs-profile-file=">, + HelpText<"Context sensitive profile file path">; + +def thinlto_jobs_eq: JJ<"thinlto-jobs=">, + HelpText<"Number of ThinLTO jobs. Default to --threads=">; + def plugin_opt_eq_minus: J<"plugin-opt=-">, HelpText<"Specify an LLVM option for compatibility with LLVMgold.so">; +def: J<"plugin-opt=thinlto">; + +def: J<"plugin-opt=O">, Alias, HelpText<"Alias for --lto-O">; +def: F<"plugin-opt=cs-profile-generate">, + Alias, HelpText<"Alias for --lto-cs-profile-generate">; +def: J<"plugin-opt=cs-profile-path=">, + Alias, HelpText<"Alias for --lto-cs-profile-file">; +def plugin_opt_dwo_dir_eq: J<"plugin-opt=dwo_dir=">, + HelpText<"Directory to store .dwo files when LTO and debug fission are used">; +def: J<"plugin-opt=jobs=">, Alias, HelpText<"Alias for --thinlto-jobs=">; def plugin_opt_mcpu_eq: J<"plugin-opt=mcpu=">; + // This may be either an unhandled LLVMgold.so feature or GCC passed // -plugin-opt=path/to/{liblto_plugin.so,lto-wrapper} def plugin_opt_eq : J<"plugin-opt=">; diff --git a/lld/test/MinGW/driver.test b/lld/test/MinGW/driver.test --- a/lld/test/MinGW/driver.test +++ b/lld/test/MinGW/driver.test @@ -372,8 +372,15 @@ RUN: ld.lld -### foo.o -m i386pep --no-guard-cf --guard-longjmp 2>&1 | FileCheck -check-prefix=GUARD_LONGJMP_NO_CF %s GUARD_LONGJMP_NO_CF: warning: parameter --guard-longjmp only takes effect when used with --guard-cf -RUN: ld.lld -### foo.o -m i386pep -plugin-opt=mcpu=x86-64 -plugin-opt=-emulated-tls 2>&1 | FileCheck -check-prefix=LTO_OPTS %s -LTO_OPTS: -mllvm:-mcpu=x86-64 -mllvm:-emulated-tls +RUN: ld.lld -### foo.o -m i386pep --threads 3 --thinlto-jobs=4 2>&1 | FileCheck -check-prefix=THREADS %s +RUN: ld.lld -### foo.o -m i386pep --threads 3 -plugin-opt=jobs=4 2>&1 | FileCheck -check-prefix=THREADS %s +THREADS: -threads:3 {{.*}} -opt:lldltojobs=4 + +RUN: ld.lld -### foo.o -m i386pep -plugin-opt=mcpu=x86-64 -plugin-opt=-emulated-tls -plugin-opt=thinlto -plugin-opt=O2 -plugin-opt=dwo_dir=foo -plugin-opt=cs-profile-generate -plugin-opt=cs-profile-path=bar 2>&1 | FileCheck -check-prefix=LTO_OPTS %s +LTO_OPTS: -mllvm:-mcpu=x86-64 -opt:lldlto=2 -dwodir:foo -lto-cs-profile-generate -lto-cs-profile-file:bar -mllvm:-emulated-tls + +RUN: ld.lld -### foo.o -m i386pep --lto-O2 --lto-CGO1 --lto-cs-profile-generate --lto-cs-profile-file=foo 2>&1 | FileCheck -check-prefix=LTO_OPTS2 %s +LTO_OPTS2:-opt:lldlto=2 -opt:lldltocgo=1 -lto-cs-profile-generate -lto-cs-profile-file:foo Test GCC specific LTO options that GCC passes unconditionally, that we ignore.