[lld] e20a215 - [ELF] Add convenience TableGen classes to enforce two dashes for options not supported by GNU ld

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Fri May 8 07:37:37 PDT 2020


Author: Fangrui Song
Date: 2020-05-08T07:37:06-07:00
New Revision: e20a215992dc685ed843b1023143f914edbb1211

URL: https://github.com/llvm/llvm-project/commit/e20a215992dc685ed843b1023143f914edbb1211
DIFF: https://github.com/llvm/llvm-project/commit/e20a215992dc685ed843b1023143f914edbb1211.diff

LOG: [ELF] Add convenience TableGen classes to enforce two dashes for options not supported by GNU ld

Announced on https://lists.llvm.org/pipermail/llvm-dev/2020-May/141416.html

For many options, we have to support either one or two dash to be
compatible with GNU ld. For newer and lld specific options, we can enforce strict double dashes.

Affected options:

* --thinlto-*
* --lto-*
* --shuffle-sections=

This patch does not change `-plugin-opt=*` because clang driver passes
`-plugin-opt=*` and I don't intend to cause churn.

In 2000, GNU ld tried something similar with --omagic
https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=e4897a3288f37d5f69e8acd256a6e83e607fe8d8

Reviewed By: tejohnson, psmith

Differential Revision: https://reviews.llvm.org/D79371

Added: 
    

Modified: 
    lld/ELF/Options.td
    lld/docs/ReleaseNotes.rst
    lld/test/ELF/lto/devirt_vcall_vis_public.ll
    lld/test/ELF/lto/thinlto-emit-imports.ll
    lld/test/ELF/lto/thinlto-index-file.ll
    lld/test/ELF/lto/thinlto-obj-path.ll
    lld/test/ELF/lto/thinlto-object-suffix-replace.ll
    lld/test/ELF/lto/thinlto-prefix-replace.ll

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Options.td b/lld/ELF/Options.td
index ae32cab5c33b..ecef2289b9cd 100644
--- 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<string name> : Flag<["--"], name>;
+class JJ<string name>: Joined<["--"], name>;
+
+multiclass EEq<string name, string help> {
+  def NAME: Separate<["--"], name>;
+  def NAME # _eq: Joined<["--"], name # "=">, Alias<!cast<Separate>(NAME)>,
+    HelpText<help>;
+}
+
 // 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<string name>: Flag<["--", "-"], name>;
@@ -265,7 +278,7 @@ def o: JoinedOrSeparate<["-"], "o">, MetaVarName<"<path>">,
 def oformat: Separate<["--"], "oformat">, MetaVarName<"<format>">,
   HelpText<"Specify the binary format for the output object file">;
 
-def omagic: Flag<["--"], "omagic">, MetaVarName<"<magic>">,
+def omagic: FF<"omagic">, MetaVarName<"<magic>">,
   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: JoinedOrSeparate<["-"], "u">, Alias<undefined>, HelpText<"Alias for --undef
 def: Flag<["-"], "V">, Alias<version>, 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<"<opt-level>">,
+def lto_O: JJ<"lto-O">, MetaVarName<"<opt-level>">,
   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 @@ def opt_remarks_filename: Separate<["--"], "opt-remarks-filename">,
   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<"<seed>">,
+def shuffle_sections: JJ<"shuffle-sections=">, MetaVarName<"<seed>">,
   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<lto_O>, HelpText<"Alias for --lto-O">;
 def: F<"plugin-opt=debug-pass-manager">,

diff  --git a/lld/docs/ReleaseNotes.rst b/lld/docs/ReleaseNotes.rst
index 12b74c87f737..8ec3ff9348f5 100644
--- a/lld/docs/ReleaseNotes.rst
+++ b/lld/docs/ReleaseNotes.rst
@@ -26,6 +26,12 @@ ELF Improvements
 
 * ...
 
+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
index f07297d5863c..0d344ec9483d 100644
--- 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
index 3e6cfc318a34..25466a1663c1 100644
--- 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
index 5792f7b6a9bf..4135c1ad4bf3 100644
--- 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
index 5d22360fc282..7311774416d2 100644
--- 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
index 0593e574b724..d22d79d34d58 100644
--- 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
index 3afbdb0f895b..dcdf93be24be 100644
--- 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


        


More information about the llvm-commits mailing list