From cb38bf526bf55e3a9fbedd6a24fec6c508461ae4 Mon Sep 17 00:00:00 2001 From: George Rimar Date: Mon, 14 Aug 2017 10:17:30 +0000 Subject: [PATCH] [ELF] - LTO: Try to be option compatible with the gold plugin. This is relative to PR30720. Previously we ignored all --plugin-opt arguments. Patch adds support for them. Patch does not add any new LTO options, and just implements mapping from --plugin-opt to existent ones. Differential revision: https://reviews.llvm.org/D36227 llvm-svn: 310826 --- lld/ELF/Driver.cpp | 27 +++++++++++++++++++++++++-- lld/ELF/Options.td | 4 ++-- lld/test/ELF/basic.s | 2 ++ lld/test/ELF/lto-plugin-ignore.s | 5 +++++ lld/test/ELF/lto/opt-level.ll | 21 +++++++++++++++++---- lld/test/ELF/lto/save-temps.ll | 7 +++++++ lld/test/ELF/lto/verify-invalid.ll | 2 ++ 7 files changed, 60 insertions(+), 8 deletions(-) create mode 100644 lld/test/ELF/lto-plugin-ignore.s diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index cc30780ce3d0..15d4ba139dd9 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -611,6 +611,13 @@ static bool getCompressDebugSections(opt::InputArgList &Args) { return true; } +static int parseInt(StringRef S, opt::Arg *Arg) { + int V = 0; + if (!to_integer(S, V, 10)) + error(Arg->getSpelling() + ": number expected, but got '" + S + "'"); + return V; +} + // Initializes Config members by the command line options. void LinkerDriver::readConfigs(opt::InputArgList &Args) { Config->AllowMultipleDefinition = @@ -694,9 +701,25 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) { Config->ZText = !hasZOption(Args, "notext"); Config->ZWxneeded = hasZOption(Args, "wxneeded"); + for (auto *Arg : Args.filtered(OPT_plugin_opt, OPT_plugin_opt_eq)) { + StringRef S = Arg->getValue(); + if (S == "disable-verify") + Config->DisableVerify = true; + else if (S == "save-temps") + Config->SaveTemps = true; + else if (S.startswith("O")) + Config->LTOO = parseInt(S.substr(1), Arg); + else if (S.startswith("lto-partitions=")) + Config->LTOPartitions = parseInt(S.substr(15), Arg); + else if (S.startswith("jobs=")) + Config->ThinLTOJobs = parseInt(S.substr(5), Arg); + // Ignore some options always passed by gcc. + else if (!S.startswith("/") && !S.startswith("-fresolution=") && + !S.startswith("-pass-through=")) + error(Arg->getSpelling() + ": unknown option: " + S); + } if (Config->LTOO > 3) - error("invalid optimization level for LTO: " + - Args.getLastArgValue(OPT_lto_O)); + error("invalid optimization level for LTO: " + Twine(Config->LTOO)); if (Config->LTOPartitions == 0) error("--lto-partitions: number of threads must be > 0"); if (Config->ThinLTOJobs == 0) diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td index c047b75d11ab..5e77e2bd765f 100644 --- a/lld/ELF/Options.td +++ b/lld/ELF/Options.td @@ -362,6 +362,8 @@ def opt_remarks_filename: Separate<["--"], "opt-remarks-filename">, HelpText<"YAML output file for optimization remarks">; def opt_remarks_with_hotness: Flag<["--"], "opt-remarks-with-hotness">, HelpText<"Include hotness informations in the optimization remarks file">; +defm plugin_opt: Eq<"plugin-opt">, + HelpText<"specifies LTO options for compatibility with GNU linkers">; def save_temps: F<"save-temps">; def thinlto_cache_dir: J<"thinlto-cache-dir=">, HelpText<"Path to ThinLTO cached object file directory">; @@ -378,8 +380,6 @@ def thinlto_jobs: J<"thinlto-jobs=">, HelpText<"Number of ThinLTO jobs">; // --version output. def plugin: S<"plugin">; def plugin_eq: J<"plugin=">; -def plugin_opt: S<"plugin-opt">; -def plugin_opt_eq: J<"plugin-opt=">; // Options listed below are silently ignored for now for compatibility. def allow_shlib_undefined: F<"allow-shlib-undefined">; diff --git a/lld/test/ELF/basic.s b/lld/test/ELF/basic.s index 164e17c805e0..166c3b2f14fa 100644 --- a/lld/test/ELF/basic.s +++ b/lld/test/ELF/basic.s @@ -246,7 +246,9 @@ _start: # UNKNOWN_EMUL: unknown emulation: wrong_emul_fbsd # RUN: not ld.lld %t --lto-partitions=0 2>&1 | FileCheck --check-prefix=NOTHREADS %s +# RUN: not ld.lld %t --plugin-opt=lto-partitions=0 2>&1 | FileCheck --check-prefix=NOTHREADS %s # NOTHREADS: --lto-partitions: number of threads must be > 0 # RUN: not ld.lld %t --thinlto-jobs=0 2>&1 | FileCheck --check-prefix=NOTHREADSTHIN %s +# RUN: not ld.lld %t --plugin-opt=jobs=0 2>&1 | FileCheck --check-prefix=NOTHREADSTHIN %s # NOTHREADSTHIN: --thinlto-jobs: number of threads must be > 0 diff --git a/lld/test/ELF/lto-plugin-ignore.s b/lld/test/ELF/lto-plugin-ignore.s new file mode 100644 index 000000000000..7014a928b1fa --- /dev/null +++ b/lld/test/ELF/lto-plugin-ignore.s @@ -0,0 +1,5 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: ld.lld %t -plugin-opt=/foo/bar -plugin-opt=-fresolution=zed \ +# RUN: -plugin-opt=-pass-through=-lgcc -o /dev/null diff --git a/lld/test/ELF/lto/opt-level.ll b/lld/test/ELF/lto/opt-level.ll index 1065ca775751..57fa3041ac65 100644 --- a/lld/test/ELF/lto/opt-level.ll +++ b/lld/test/ELF/lto/opt-level.ll @@ -2,18 +2,31 @@ ; RUN: llvm-as -o %t.o %s ; RUN: ld.lld -o %t0 -m elf_x86_64 -e main --lto-O0 %t.o ; RUN: llvm-nm %t0 | FileCheck --check-prefix=CHECK-O0 %s +; RUN: ld.lld -o %t0 -m elf_x86_64 -e main --plugin-opt=O0 %t.o +; RUN: llvm-nm %t0 | FileCheck --check-prefix=CHECK-O0 %s ; RUN: ld.lld -o %t2 -m elf_x86_64 -e main --lto-O2 %t.o ; RUN: llvm-nm %t2 | FileCheck --check-prefix=CHECK-O2 %s ; RUN: ld.lld -o %t2a -m elf_x86_64 -e main %t.o ; RUN: llvm-nm %t2a | FileCheck --check-prefix=CHECK-O2 %s +; RUN: ld.lld -o %t2 -m elf_x86_64 -e main --plugin-opt=O2 %t.o +; RUN: llvm-nm %t2 | FileCheck --check-prefix=CHECK-O2 %s ; Reject invalid optimization levels. ; RUN: not ld.lld -o %t3 -m elf_x86_64 -e main --lto-O6 %t.o 2>&1 | \ -; RUN: FileCheck --check-prefix=INVALID %s -; INVALID: invalid optimization level for LTO: 6 +; RUN: FileCheck --check-prefix=INVALID1 %s +; INVALID1: invalid optimization level for LTO: 6 +; RUN: not ld.lld -o %t3 -m elf_x86_64 -e main --plugin-opt=O6 %t.o 2>&1 | \ +; RUN: FileCheck --check-prefix=INVALID1 %s +; RUN: not ld.lld -o %t3 -m elf_x86_64 -e main --plugin-opt=Ofoo %t.o 2>&1 | \ +; RUN: FileCheck --check-prefix=INVALID2 %s +; INVALID2: --plugin-opt: number expected, but got 'foo' + ; RUN: not ld.lld -o %t3 -m elf_x86_64 -e main --lto-O-1 %t.o 2>&1 | \ -; RUN: FileCheck --check-prefix=INVALIDNEGATIVE %s -; INVALIDNEGATIVE: invalid optimization level for LTO: -1 +; RUN: FileCheck --check-prefix=INVALIDNEGATIVE1 %s +; INVALIDNEGATIVE1: invalid optimization level for LTO: 4294967295 +; RUN: not ld.lld -o %t3 -m elf_x86_64 -e main --plugin-opt=O-1 %t.o 2>&1 | \ +; RUN: FileCheck --check-prefix=INVALIDNEGATIVE2 %s +; INVALIDNEGATIVE2: invalid optimization level for LTO: 4294967295 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/lld/test/ELF/lto/save-temps.ll b/lld/test/ELF/lto/save-temps.ll index f7af99ed40af..c8e52ff4b4ec 100644 --- a/lld/test/ELF/lto/save-temps.ll +++ b/lld/test/ELF/lto/save-temps.ll @@ -9,6 +9,13 @@ ; RUN: llvm-nm a.out.lto.o | FileCheck %s ; RUN: llvm-dis a.out.0.0.preopt.bc +; RUN: rm -f a.out a.out.lto.bc a.out.lto.o +; RUN: ld.lld -shared -m elf_x86_64 %t.o %t2.o --plugin-opt=save-temps +; RUN: llvm-nm a.out | FileCheck %s +; RUN: llvm-nm a.out.0.0.preopt.bc | FileCheck %s +; RUN: llvm-nm a.out.lto.o | FileCheck %s +; RUN: llvm-dis a.out.0.0.preopt.bc + target triple = "x86_64-unknown-linux-gnu" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" diff --git a/lld/test/ELF/lto/verify-invalid.ll b/lld/test/ELF/lto/verify-invalid.ll index 16d6a3e54f12..e6138a3cca62 100644 --- a/lld/test/ELF/lto/verify-invalid.ll +++ b/lld/test/ELF/lto/verify-invalid.ll @@ -4,6 +4,8 @@ ; RUN: 2>&1 | FileCheck -check-prefix=DEFAULT %s ; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -mllvm -debug-pass=Arguments \ ; RUN: -disable-verify 2>&1 | FileCheck -check-prefix=DISABLE %s +; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -mllvm -debug-pass=Arguments \ +; RUN: --plugin-opt=disable-verify 2>&1 | FileCheck -check-prefix=DISABLE %s target triple = "x86_64-unknown-linux-gnu" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" -- GitLab