diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td --- a/lld/ELF/Options.td +++ b/lld/ELF/Options.td @@ -1,5 +1,18 @@ include "llvm/Option/OptParser.td" +// 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 EEq { + def NAME: Separate<["--"], name>; + def NAME # _eq: Joined<["--"], name # "=">, Alias(NAME)>, + HelpText; +} + // For options whose names are multiple letters, either one dash or // two can precede the option name except those that start with 'o'. class F: Flag<["--", "-"], name>; @@ -265,7 +278,7 @@ def oformat: Separate<["--"], "oformat">, MetaVarName<"">, HelpText<"Specify the binary format for the output object file">; -def omagic: Flag<["--"], "omagic">, MetaVarName<"">, +def omagic: FF<"omagic">, MetaVarName<"">, HelpText<"Set the text and data sections to be readable and writable, do not page align sections, link against static libraries">; defm orphan_handling: @@ -484,28 +497,28 @@ def: Flag<["-"], "V">, Alias, HelpText<"Alias for --version">; // LTO-related options. -def lto_aa_pipeline: J<"lto-aa-pipeline=">, +def lto_aa_pipeline: JJ<"lto-aa-pipeline=">, HelpText<"AA pipeline to run during LTO. Used in conjunction with -lto-newpm-passes">; -def lto_debug_pass_manager: F<"lto-debug-pass-manager">, +def lto_debug_pass_manager: FF<"lto-debug-pass-manager">, HelpText<"Debug new pass manager">; -def lto_emit_asm: F<"lto-emit-asm">, +def lto_emit_asm: FF<"lto-emit-asm">, HelpText<"Emit assembly code">; -def lto_new_pass_manager: F<"lto-new-pass-manager">, +def lto_new_pass_manager: FF<"lto-new-pass-manager">, HelpText<"Use new pass manager">; -def lto_newpm_passes: J<"lto-newpm-passes=">, +def lto_newpm_passes: JJ<"lto-newpm-passes=">, HelpText<"Passes to run during LTO">; -def lto_O: J<"lto-O">, MetaVarName<"">, +def lto_O: JJ<"lto-O">, MetaVarName<"">, HelpText<"Optimization level for LTO">; -def lto_partitions: J<"lto-partitions=">, +def lto_partitions: JJ<"lto-partitions=">, HelpText<"Number of LTO codegen partitions">; -def lto_cs_profile_generate: F<"lto-cs-profile-generate">, +def lto_cs_profile_generate: FF<"lto-cs-profile-generate">, HelpText<"Perform context sensitive PGO instrumentation">; -def lto_cs_profile_file: J<"lto-cs-profile-file=">, +def lto_cs_profile_file: JJ<"lto-cs-profile-file=">, HelpText<"Context sensitive profile file path">; -def lto_obj_path_eq: J<"lto-obj-path=">; -def lto_sample_profile: J<"lto-sample-profile=">, +def lto_obj_path_eq: JJ<"lto-obj-path=">; +def lto_sample_profile: JJ<"lto-sample-profile=">, HelpText<"Sample profile file path">; -def lto_whole_program_visibility: F<"lto-whole-program-visibility">, +def lto_whole_program_visibility: FF<"lto-whole-program-visibility">, HelpText<"Asserts that the LTO link has whole program visibility">; def disable_verify: F<"disable-verify">; defm mllvm: Eq<"mllvm", "Additional arguments to forward to LLVM's option processing">; @@ -513,28 +526,28 @@ HelpText<"YAML output file for optimization remarks">; def opt_remarks_passes: Separate<["--"], "opt-remarks-passes">, HelpText<"Regex for the passes that need to be serialized to the output file">; -def opt_remarks_with_hotness: Flag<["--"], "opt-remarks-with-hotness">, +def opt_remarks_with_hotness: FF<"opt-remarks-with-hotness">, HelpText<"Include hotness information in the optimization remarks file">; def opt_remarks_format: Separate<["--"], "opt-remarks-format">, HelpText<"The format used for serializing remarks (default: YAML)">; def save_temps: F<"save-temps">; -def lto_basicblock_sections: J<"lto-basicblock-sections=">, +def lto_basicblock_sections: JJ<"lto-basicblock-sections=">, HelpText<"Enable basic block sections for LTO">; defm lto_unique_bb_section_names: B<"lto-unique-bb-section-names", "Give unique names to every basic block section for LTO", "Do not give unique names to every basic block section for LTO (default)">; -def shuffle_sections: J<"shuffle-sections=">, MetaVarName<"">, +def shuffle_sections: JJ<"shuffle-sections=">, MetaVarName<"">, HelpText<"Shuffle input sections using the given seed. If 0, use a random seed">; -def thinlto_cache_dir: J<"thinlto-cache-dir=">, +def thinlto_cache_dir: JJ<"thinlto-cache-dir=">, HelpText<"Path to ThinLTO cached object file directory">; -defm thinlto_cache_policy: Eq<"thinlto-cache-policy", "Pruning policy for the ThinLTO cache">; -def thinlto_emit_imports_files: F<"thinlto-emit-imports-files">; -def thinlto_index_only: F<"thinlto-index-only">; -def thinlto_index_only_eq: J<"thinlto-index-only=">; -def thinlto_jobs: J<"thinlto-jobs=">, +defm thinlto_cache_policy: EEq<"thinlto-cache-policy", "Pruning policy for the ThinLTO cache">; +def thinlto_emit_imports_files: FF<"thinlto-emit-imports-files">; +def thinlto_index_only: FF<"thinlto-index-only">; +def thinlto_index_only_eq: JJ<"thinlto-index-only=">; +def thinlto_jobs: JJ<"thinlto-jobs=">, HelpText<"Number of ThinLTO jobs. Default to --threads=">; -def thinlto_object_suffix_replace_eq: J<"thinlto-object-suffix-replace=">; -def thinlto_prefix_replace_eq: J<"thinlto-prefix-replace=">; +def thinlto_object_suffix_replace_eq: JJ<"thinlto-object-suffix-replace=">; +def thinlto_prefix_replace_eq: JJ<"thinlto-prefix-replace=">; def: J<"plugin-opt=O">, Alias, HelpText<"Alias for --lto-O">; def: F<"plugin-opt=debug-pass-manager">, diff --git a/lld/docs/ReleaseNotes.rst b/lld/docs/ReleaseNotes.rst --- a/lld/docs/ReleaseNotes.rst +++ b/lld/docs/ReleaseNotes.rst @@ -26,6 +26,12 @@ * ... +Breaking changes +---------------- + +* One-dash form of some long option (``--thinlto-*``, ``--lto-*``, ``--shuffle-sections=``) + are no longer supported. + COFF Improvements ----------------- diff --git a/lld/test/ELF/lto/devirt_vcall_vis_public.ll b/lld/test/ELF/lto/devirt_vcall_vis_public.ll --- a/lld/test/ELF/lto/devirt_vcall_vis_public.ll +++ b/lld/test/ELF/lto/devirt_vcall_vis_public.ll @@ -1,23 +1,23 @@ ; REQUIRES: x86 -; Test that -lto-whole-program-visibility enables devirtualization. +; Test that --lto-whole-program-visibility enables devirtualization. ; Index based WPD ; Generate unsplit module with summary for ThinLTO index-based WPD. -; RUN: opt -thinlto-bc -o %t2.o %s -; RUN: ld.lld %t2.o -o %t3 -save-temps -lto-whole-program-visibility \ +; RUN: opt --thinlto-bc -o %t2.o %s +; RUN: ld.lld %t2.o -o %t3 -save-temps --lto-whole-program-visibility \ ; RUN: -mllvm -pass-remarks=. --export-dynamic 2>&1 | FileCheck %s --check-prefix=REMARK ; RUN: llvm-dis %t2.o.4.opt.bc -o - | FileCheck %s --check-prefix=CHECK-IR ; Hybrid WPD ; Generate split module with summary for hybrid Thin/Regular LTO WPD. -; RUN: opt -thinlto-bc -thinlto-split-lto-unit -o %t.o %s -; RUN: ld.lld %t.o -o %t3 -save-temps -lto-whole-program-visibility \ +; RUN: opt --thinlto-bc --thinlto-split-lto-unit -o %t.o %s +; RUN: ld.lld %t.o -o %t3 -save-temps --lto-whole-program-visibility \ ; RUN: -mllvm -pass-remarks=. --export-dynamic 2>&1 | FileCheck %s --check-prefix=REMARK ; RUN: llvm-dis %t.o.4.opt.bc -o - | FileCheck %s --check-prefix=CHECK-IR ; Regular LTO WPD ; RUN: opt -o %t4.o %s -; RUN: ld.lld %t4.o -o %t3 -save-temps -lto-whole-program-visibility \ +; RUN: ld.lld %t4.o -o %t3 -save-temps --lto-whole-program-visibility \ ; RUN: -mllvm -pass-remarks=. --export-dynamic 2>&1 | FileCheck %s --check-prefix=REMARK ; RUN: llvm-dis %t3.0.4.opt.bc -o - | FileCheck %s --check-prefix=CHECK-IR diff --git a/lld/test/ELF/lto/thinlto-emit-imports.ll b/lld/test/ELF/lto/thinlto-emit-imports.ll --- a/lld/test/ELF/lto/thinlto-emit-imports.ll +++ b/lld/test/ELF/lto/thinlto-emit-imports.ll @@ -43,10 +43,10 @@ ; RUN: not ls %t2.o.imports ; RUN: not ls %t3.o.imports -; Check that imports files are generated also when -thinlto-index-only +; Check that imports files are generated also when --thinlto-index-only ; is specified without --plugin-opt=. ; RUN: rm -f %t1.o.imports -; RUN: ld.lld -thinlto-index-only -thinlto-emit-imports-files -shared %t1.o %t2.o %t3.o -o %t4 +; RUN: ld.lld --thinlto-index-only --thinlto-emit-imports-files -shared %t1.o %t2.o %t3.o -o %t4 ; RUN: count 1 < %t1.o.imports ; RUN: FileCheck %s --check-prefix=IMPORTS1 < %t1.o.imports diff --git a/lld/test/ELF/lto/thinlto-index-file.ll b/lld/test/ELF/lto/thinlto-index-file.ll --- a/lld/test/ELF/lto/thinlto-index-file.ll +++ b/lld/test/ELF/lto/thinlto-index-file.ll @@ -13,7 +13,7 @@ ; CHECK: {{.*}}thinlto-index-file.ll.tmp3.o ; Check that this also works without the --plugin-opt= prefix. -; RUN: ld.lld -thinlto-index-only=%t.idx -shared %t1.o %t2.o %t3.o -o /dev/null +; RUN: ld.lld --thinlto-index-only=%t.idx -shared %t1.o %t2.o %t3.o -o /dev/null ; RUN: FileCheck %s < %t.idx target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" diff --git a/lld/test/ELF/lto/thinlto-obj-path.ll b/lld/test/ELF/lto/thinlto-obj-path.ll --- a/lld/test/ELF/lto/thinlto-obj-path.ll +++ b/lld/test/ELF/lto/thinlto-obj-path.ll @@ -11,7 +11,7 @@ ; Check that this also works without the --plugin-opt= prefix. ; RUN: rm -f %t4.o -; RUN: ld.lld -thinlto-index-only -lto-obj-path=%t4.o -shared %t1.o %t2.o -o /dev/null +; RUN: ld.lld --thinlto-index-only --lto-obj-path=%t4.o -shared %t1.o %t2.o -o /dev/null ; RUN: llvm-readobj -h %t4.o | FileCheck %s ;; Ensure lld emits empty combined module if specific obj-path. diff --git a/lld/test/ELF/lto/thinlto-object-suffix-replace.ll b/lld/test/ELF/lto/thinlto-object-suffix-replace.ll --- a/lld/test/ELF/lto/thinlto-object-suffix-replace.ll +++ b/lld/test/ELF/lto/thinlto-object-suffix-replace.ll @@ -5,7 +5,7 @@ ; Generate bitcode file with summary, as well as a minimized bitcode without ; the debug metadata for the thin link. -; RUN: opt -thinlto-bc %s -thin-link-bitcode-file=%t1.thinlink.bc -o %t1.o +; RUN: opt --thinlto-bc %s -thin-link-bitcode-file=%t1.thinlink.bc -o %t1.o ; First perform the thin link on the normal bitcode file, and save the ; resulting index. @@ -22,8 +22,8 @@ ; RUN: -shared %t1.thinlink.bc -o %t3 ; RUN: diff %t1.o.thinlto.bc.orig %t1.o.thinlto.bc ; Also check that this works without the --plugin-opt= prefix. -; RUN: ld.lld -thinlto-index-only \ -; RUN: -thinlto-object-suffix-replace=".thinlink.bc;.o" \ +; RUN: ld.lld --thinlto-index-only \ +; RUN: --thinlto-object-suffix-replace=".thinlink.bc;.o" \ ; RUN: -shared %t1.thinlink.bc -o %t3 ; RUN: diff %t1.o.thinlto.bc.orig %t1.o.thinlto.bc diff --git a/lld/test/ELF/lto/thinlto-prefix-replace.ll b/lld/test/ELF/lto/thinlto-prefix-replace.ll --- a/lld/test/ELF/lto/thinlto-prefix-replace.ll +++ b/lld/test/ELF/lto/thinlto-prefix-replace.ll @@ -11,7 +11,7 @@ ; Check that this also works without the --plugin-opt= prefix. ; RUN: rm -f %t/newpath/thinlto_prefix_replace.o.thinlto.bc -; RUN: ld.lld -thinlto-index-only -thinlto-prefix-replace="%t/oldpath/;%t/newpath/" -shared %t/oldpath/thinlto_prefix_replace.o -o %t/thinlto_prefix_replace +; RUN: ld.lld --thinlto-index-only --thinlto-prefix-replace="%t/oldpath/;%t/newpath/" -shared %t/oldpath/thinlto_prefix_replace.o -o %t/thinlto_prefix_replace ; RUN: ls %t/newpath/thinlto_prefix_replace.o.thinlto.bc ; Ensure that lld generates error if prefix replace option does not have 'old;new' format