-
Notifications
You must be signed in to change notification settings - Fork 11.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[LinkerWrapper] Extend with usual pass options #96704
[LinkerWrapper] Extend with usual pass options #96704
Conversation
The goal of this patch is to enable utilizing LLVM plugin passes and remarks for GPU offload code at link time. Specifically, this patch extends clang-linker-wrapper's `--offload-opt` (and consequently `-mllvm`) to accept the various LLVM pass options that tools like opt usually accept. Those options include `--passes`, `--load-pass-plugin`, and various remarks options. Unlike many other LLVM options that are inherited from linked code by clang-linker-wrapper (e.g., `-pass-remarks` is already implemented in `llvm/lib/IR/DiagnosticHandler.cpp`), these options are implemented separately as needed by each tool (e.g., opt, llc). Fortunately, this patch is able to handle most of the implementation by passing the option values to `lto::Config`. For testing plugin support, this patch uses the simple `Bye` plugin from LLVM core, but that requires several small Clang test suite config extensions.
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-driver Author: Joel E. Denny (jdenny-ornl) ChangesThe goal of this patch is to enable utilizing LLVM plugin passes and remarks for GPU offload code at link time. Specifically, this patch extends clang-linker-wrapper's Unlike many other LLVM options that are inherited from linked code by clang-linker-wrapper (e.g., For testing plugin support, this patch uses the simple Full diff: https://github.com/llvm/llvm-project/pull/96704.diff 9 Files Affected:
diff --git a/clang/test/CMakeLists.txt b/clang/test/CMakeLists.txt
index 5fceb1d710334..8303269a9ad07 100644
--- a/clang/test/CMakeLists.txt
+++ b/clang/test/CMakeLists.txt
@@ -11,6 +11,9 @@ llvm_canonicalize_cmake_booleans(
CLANG_SPAWN_CC1
CLANG_ENABLE_CIR
ENABLE_BACKTRACES
+ LLVM_BUILD_EXAMPLES
+ LLVM_BYE_LINK_INTO_TOOLS
+ LLVM_ENABLE_PLUGINS
LLVM_ENABLE_ZLIB
LLVM_ENABLE_ZSTD
LLVM_ENABLE_PER_TARGET_RUNTIME_DIR
diff --git a/clang/test/Driver/linker-wrapper-llvm-help.c b/clang/test/Driver/linker-wrapper-llvm-help.c
new file mode 100644
index 0000000000000..ffd1cf78bcd9a
--- /dev/null
+++ b/clang/test/Driver/linker-wrapper-llvm-help.c
@@ -0,0 +1,10 @@
+// Check that these simple command lines for listing LLVM options are supported,
+// as claimed by 'clang-linker-wrapper --help'.
+
+// RUN: clang-linker-wrapper -mllvm --help 2>&1 | FileCheck %s
+// RUN: clang-linker-wrapper --offload-opt=--help 2>&1 | FileCheck %s
+
+// Look for a few options supported only after -mllvm and --offload-opt.
+// CHECK: OPTIONS:
+// CHECK-DAG: --passes=<string>
+// CHECK-DAG: --load-pass-plugin=<string>
diff --git a/clang/test/Driver/linker-wrapper-passes.ll b/clang/test/Driver/linker-wrapper-passes.ll
new file mode 100644
index 0000000000000..28493b9a88eb1
--- /dev/null
+++ b/clang/test/Driver/linker-wrapper-passes.ll
@@ -0,0 +1,86 @@
+; Check various clang-linker-wrapper pass options after -offload-opt.
+
+; REQUIRES: llvm-plugins, llvm-examples
+; REQUIRES: x86-registered-target
+; REQUIRES: amdgpu-registered-target
+
+; Setup.
+; RUN: split-file %s %t
+; RUN: opt -o %t/host-x86_64-unknown-linux-gnu.bc \
+; RUN: %t/host-x86_64-unknown-linux-gnu.ll
+; RUN: opt -o %t/openmp-amdgcn-amd-amdhsa.bc \
+; RUN: %t/openmp-amdgcn-amd-amdhsa.ll
+; RUN: clang-offload-packager -o %t/openmp-x86_64-unknown-linux-gnu.out \
+; RUN: --image=file=%t/openmp-amdgcn-amd-amdhsa.bc,triple=amdgcn-amd-amdhsa
+; RUN: %clang -cc1 -S -o %t/host-x86_64-unknown-linux-gnu.s \
+; RUN: -fopenmp -fopenmp-targets=amdgcn-amd-amdhsa \
+; RUN: -fembed-offload-object=%t/openmp-x86_64-unknown-linux-gnu.out \
+; RUN: %t/host-x86_64-unknown-linux-gnu.bc
+; RUN: %clang -cc1as -o %t/host-x86_64-unknown-linux-gnu.o \
+; RUN: -triple x86_64-unknown-linux-gnu -filetype obj -target-cpu x86-64 \
+; RUN: %t/host-x86_64-unknown-linux-gnu.s
+
+; Check plugin, -passes, and no remarks.
+; RUN: clang-linker-wrapper -o a.out --embed-bitcode \
+; RUN: --linker-path=/usr/bin/true %t/host-x86_64-unknown-linux-gnu.o \
+; RUN: %offload-opt-loadbye --offload-opt=-wave-goodbye \
+; RUN: --offload-opt=-passes="function(goodbye),module(inline)" 2>&1 | \
+; RUN: FileCheck -match-full-lines -check-prefixes=OUT %s
+
+; Check plugin, -p, and remarks.
+; RUN: clang-linker-wrapper -o a.out --embed-bitcode \
+; RUN: --linker-path=/usr/bin/true %t/host-x86_64-unknown-linux-gnu.o \
+; RUN: %offload-opt-loadbye --offload-opt=-wave-goodbye \
+; RUN: --offload-opt=-p="function(goodbye),module(inline)" \
+; RUN: --offload-opt=-pass-remarks=inline \
+; RUN: --offload-opt=-pass-remarks-output=%t/remarks.yml \
+; RUN: --offload-opt=-pass-remarks-filter=inline \
+; RUN: --offload-opt=-pass-remarks-format=yaml 2>&1 | \
+; RUN: FileCheck -match-full-lines -check-prefixes=OUT,REM %s
+; RUN: FileCheck -input-file=%t/remarks.yml -match-full-lines \
+; RUN: -check-prefixes=YML %s
+
+; Check handling of bad plugin.
+; RUN: not clang-linker-wrapper \
+; RUN: --offload-opt=-load-pass-plugin=%t/nonexistent.so 2>&1 | \
+; RUN: FileCheck -match-full-lines -check-prefixes=BAD-PLUGIN %s
+
+; OUT-NOT: {{.}}
+; OUT: Bye: f
+; OUT-NEXT: Bye: test
+; REM-NEXT: remark: {{.*}} 'f' inlined into 'test' {{.*}}
+; OUT-NOT: {{.}}
+
+; YML-NOT: {{.}}
+; YML: --- !Passed
+; YML-NEXT: Pass: inline
+; YML-NEXT: Name: Inlined
+; YML-NEXT: Function: test
+; YML-NEXT: Args:
+; YML: - Callee: f
+; YML: - Caller: test
+; YML: ...
+; YML-NOT: {{.}}
+
+; BAD-PLUGIN-NOT: {{.}}
+; BAD-PLUGIN: {{.*}}Could not load library {{.*}}nonexistent.so{{.*}}
+; BAD-PLUGIN-NOT: {{.}}
+
+;--- host-x86_64-unknown-linux-gnu.ll
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+;--- openmp-amdgcn-amd-amdhsa.ll
+target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9"
+target triple = "amdgcn-amd-amdhsa"
+
+define void @f() {
+entry:
+ ret void
+}
+
+define amdgpu_kernel void @test() {
+entry:
+ call void @f()
+ ret void
+}
diff --git a/clang/test/Driver/lit.local.cfg b/clang/test/Driver/lit.local.cfg
index 6370e9f92d89b..9bde2333a2e0d 100644
--- a/clang/test/Driver/lit.local.cfg
+++ b/clang/test/Driver/lit.local.cfg
@@ -19,6 +19,7 @@ config.suffixes = [
".hip",
".hipi",
".hlsl",
+ ".ll",
".yaml",
".test",
]
diff --git a/clang/test/lit.cfg.py b/clang/test/lit.cfg.py
index e5630a07424c7..2e0fbc2c9e1dd 100644
--- a/clang/test/lit.cfg.py
+++ b/clang/test/lit.cfg.py
@@ -109,6 +109,15 @@
if config.clang_examples:
config.available_features.add("examples")
+if config.llvm_examples:
+ config.available_features.add("llvm-examples")
+
+if config.llvm_linked_bye_extension:
+ config.substitutions.append(("%offload-opt-loadbye", ""))
+else:
+ loadbye = f"-load-pass-plugin={config.llvm_shlib_dir}/Bye{config.llvm_shlib_ext}"
+ config.substitutions.append(("%offload-opt-loadbye", f"--offload-opt={loadbye}"))
+
def have_host_jit_feature_support(feature_name):
clang_repl_exe = lit.util.which("clang-repl", config.clang_tools_dir)
@@ -213,6 +222,9 @@ def have_host_clang_repl_cuda():
if config.has_plugins and config.llvm_plugin_ext:
config.available_features.add("plugins")
+if config.llvm_has_plugins and config.llvm_plugin_ext:
+ config.available_features.add("llvm-plugins")
+
if config.clang_default_pie_on_linux:
config.available_features.add("default-pie-on-linux")
diff --git a/clang/test/lit.site.cfg.py.in b/clang/test/lit.site.cfg.py.in
index 1cbd876ac5bb9..2cc70e52f1aa1 100644
--- a/clang/test/lit.site.cfg.py.in
+++ b/clang/test/lit.site.cfg.py.in
@@ -7,6 +7,7 @@ config.llvm_obj_root = path(r"@LLVM_BINARY_DIR@")
config.llvm_tools_dir = lit_config.substitute(path(r"@LLVM_TOOLS_DIR@"))
config.llvm_libs_dir = lit_config.substitute(path(r"@LLVM_LIBS_DIR@"))
config.llvm_shlib_dir = lit_config.substitute(path(r"@SHLIBDIR@"))
+config.llvm_shlib_ext = "@SHLIBEXT@"
config.llvm_plugin_ext = "@LLVM_PLUGIN_EXT@"
config.lit_tools_dir = path(r"@LLVM_LIT_TOOLS_DIR@")
config.errc_messages = "@LLVM_LIT_ERRC_MESSAGES@"
@@ -39,7 +40,10 @@ config.python_executable = "@Python3_EXECUTABLE@"
config.use_z3_solver = lit_config.params.get('USE_Z3_SOLVER', "@USE_Z3_SOLVER@")
config.has_plugins = @CLANG_PLUGIN_SUPPORT@
config.clang_vendor_uti = "@CLANG_VENDOR_UTI@"
+config.llvm_examples = @LLVM_BUILD_EXAMPLES@
+config.llvm_linked_bye_extension = @LLVM_BYE_LINK_INTO_TOOLS@
config.llvm_external_lit = path(r"@LLVM_EXTERNAL_LIT@")
+config.llvm_has_plugins = @LLVM_ENABLE_PLUGINS@
config.standalone_build = @CLANG_BUILT_STANDALONE@
config.ppc_linux_default_ieeelongdouble = @PPC_LINUX_DEFAULT_IEEELONGDOUBLE@
config.have_llvm_driver = @LLVM_TOOL_LLVM_DRIVER_BUILD@
diff --git a/clang/tools/clang-linker-wrapper/CMakeLists.txt b/clang/tools/clang-linker-wrapper/CMakeLists.txt
index 5556869affaa6..bf37d8031025e 100644
--- a/clang/tools/clang-linker-wrapper/CMakeLists.txt
+++ b/clang/tools/clang-linker-wrapper/CMakeLists.txt
@@ -41,3 +41,5 @@ target_link_libraries(clang-linker-wrapper
PRIVATE
${CLANG_LINKER_WRAPPER_LIB_DEPS}
)
+
+export_executable_symbols_for_plugins(clang-linker-wrapper)
diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
index 9027076119cf9..cb4cc5debae87 100644
--- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
+++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
@@ -37,6 +37,8 @@
#include "llvm/Option/ArgList.h"
#include "llvm/Option/OptTable.h"
#include "llvm/Option/Option.h"
+#include "llvm/Passes/PassPlugin.h"
+#include "llvm/Remarks/HotnessThresholdParser.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/FileOutputBuffer.h"
@@ -62,6 +64,54 @@ using namespace llvm;
using namespace llvm::opt;
using namespace llvm::object;
+// Various tools (e.g., llc and opt) duplicate this series of declarations for
+// options related to passes and remarks.
+
+static cl::opt<bool> RemarksWithHotness(
+ "pass-remarks-with-hotness",
+ cl::desc("With PGO, include profile count in optimization remarks"),
+ cl::Hidden);
+
+static cl::opt<std::optional<uint64_t>, false, remarks::HotnessThresholdParser>
+ RemarksHotnessThreshold(
+ "pass-remarks-hotness-threshold",
+ cl::desc("Minimum profile count required for "
+ "an optimization remark to be output. "
+ "Use 'auto' to apply the threshold from profile summary."),
+ cl::value_desc("N or 'auto'"), cl::init(0), cl::Hidden);
+
+static cl::opt<std::string>
+ RemarksFilename("pass-remarks-output",
+ cl::desc("Output filename for pass remarks"),
+ cl::value_desc("filename"));
+
+static cl::opt<std::string>
+ RemarksPasses("pass-remarks-filter",
+ cl::desc("Only record optimization remarks from passes whose "
+ "names match the given regular expression"),
+ cl::value_desc("regex"));
+
+static cl::opt<std::string> RemarksFormat(
+ "pass-remarks-format",
+ cl::desc("The format used for serializing remarks (default: YAML)"),
+ cl::value_desc("format"), cl::init("yaml"));
+
+static cl::list<std::string>
+ PassPlugins("load-pass-plugin",
+ cl::desc("Load passes from plugin library"));
+
+static cl::opt<std::string> PassPipeline(
+ "passes",
+ cl::desc(
+ "A textual description of the pass pipeline. To have analysis passes "
+ "available before a certain pass, add 'require<foo-analysis>'. "
+ "'-passes' overrides the pass pipeline (but not all effects) from "
+ "specifying '--opt-level=O?' (O2 is the default) to "
+ "clang-linker-wrapper. Be sure to include the corresponding "
+ "'default<O?>' in '-passes'."));
+static cl::alias PassPipeline2("p", cl::aliasopt(PassPipeline),
+ cl::desc("Alias for -passes"));
+
/// Path of the current binary.
static const char *LinkerExecutable;
@@ -628,6 +678,12 @@ std::unique_ptr<lto::LTO> createLTO(
Conf.CPU = Arch.str();
Conf.Options = codegen::InitTargetOptionsFromCodeGenFlags(Triple);
+ Conf.RemarksFilename = RemarksFilename;
+ Conf.RemarksPasses = RemarksPasses;
+ Conf.RemarksWithHotness = RemarksWithHotness;
+ Conf.RemarksHotnessThreshold = RemarksHotnessThreshold;
+ Conf.RemarksFormat = RemarksFormat;
+
StringRef OptLevel = Args.getLastArgValue(OPT_opt_level, "O2");
Conf.MAttrs = Features;
std::optional<CodeGenOptLevel> CGOptLevelOrNone =
@@ -637,6 +693,17 @@ std::unique_ptr<lto::LTO> createLTO(
Conf.OptLevel = OptLevel[1] - '0';
Conf.DefaultTriple = Triple.getTriple();
+ // TODO: Should we complain about combining --opt-level and -passes, as opt
+ // does? That might be too limiting in clang-linker-wrapper, so for now we
+ // just warn in the help entry for -passes that the default<O?> corresponding
+ // to --opt-level=O? should be included there. The problem is that
+ // --opt-level produces effects in clang-linker-wrapper beyond what -passes
+ // appears to be able to achieve, so rejecting the combination of --opt-level
+ // and -passes would apparently make it impossible to combine those effects
+ // with a custom pass pipeline.
+ Conf.OptPipeline = PassPipeline;
+ Conf.PassPlugins = PassPlugins;
+
LTOError = false;
Conf.DiagHandler = diagnosticHandler;
@@ -1660,6 +1727,13 @@ int main(int Argc, char **Argv) {
NewArgv.push_back(Arg->getValue());
for (const opt::Arg *Arg : Args.filtered(OPT_offload_opt_eq_minus))
NewArgv.push_back(Args.MakeArgString(StringRef("-") + Arg->getValue()));
+ SmallVector<PassPlugin, 1> PluginList;
+ PassPlugins.setCallback([&](const std::string &PluginPath) {
+ auto Plugin = PassPlugin::Load(PluginPath);
+ if (!Plugin)
+ report_fatal_error(Plugin.takeError(), /*gen_crash_diag=*/false);
+ PluginList.emplace_back(Plugin.get());
+ });
cl::ParseCommandLineOptions(NewArgv.size(), &NewArgv[0]);
Verbose = Args.hasArg(OPT_verbose);
diff --git a/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td b/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td
index eb31b98a3f545..9c27e588fc4f5 100644
--- a/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td
+++ b/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td
@@ -94,9 +94,13 @@ def linker_arg_EQ : Joined<["--"], "linker-arg=">,
// Arguments for the LLVM backend.
def mllvm : Separate<["-"], "mllvm">, Flags<[WrapperOnlyOption]>,
- MetaVarName<"<arg>">, HelpText<"Arguments passed to the LLVM invocation">;
+ MetaVarName<"<arg>">,
+ HelpText<"Arguments passed to LLVM, including Clang invocations, for which "
+ "the '-mllvm' prefix is preserved. Use '-mllvm --help' for a list "
+ "of options.">;
def offload_opt_eq_minus : Joined<["--", "-"], "offload-opt=-">, Flags<[HelpHidden, WrapperOnlyOption]>,
- HelpText<"Options passed to LLVM">;
+ HelpText<"Options passed to LLVM, not including the Clang invocation. Use "
+ "'--offload-opt=--help' for a list of options.">;
// Standard linker flags also used by the linker wrapper.
def sysroot_EQ : Joined<["--"], "sysroot=">, HelpText<"Set the system root">;
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense overall. However in the future I'm looking to move away from the home-baked LTO pipeline in favor of giving it to the linker. That allows me to set up libraries as a part of the target toolchain in the driver. I guess for that I'll just need to forward -mllvm
to the internal clang invocation.
ret void | ||
} | ||
|
||
define amdgpu_kernel void @test() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the kernel really necessary? Otherwise I'd just compile with -mtriple=amdgcn--
or something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That came from clang followed by llvm-reduce. I'll look into refactoring it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the kernel really necessary?
OK, I removed it and the test still passed.
Otherwise I'd just compile with
-mtriple=amdgcn--
or something.
Not sure what you're asking for here. Which command line do you want me to change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean, we have this kernel-split thing when we could just have some generic LLVM-IR and set -mtriple
in opt
to just get the triple and default data layout instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I pushed another commit. Let know if that's what you had in mind.
@@ -0,0 +1,10 @@ | |||
// Check that these simple command lines for listing LLVM options are supported, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have any other tests that just check the output for --help
? Might be a little excessive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Grepping for -help in llvm's test suite finds various such tests. The point here is to make sure `--offload-opt=--help can list these opt-like options as opposed to the normal clang-linker-wrapper options. Seems like an important feature.
As long as there's some way to inject an LLVM pass plugin at link time (even if it requires -flto or -foffload-lto), that's fine. I don't know that a stable command-line interface is critical at this point. Of course, please ping me if it changes. |
@@ -0,0 +1,77 @@ | |||
; Check various clang-linker-wrapper pass options after -offload-opt. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, is this really the only LLVM-IR file in the Driver directory? I guess it makes sense, though you could probably just do what the other linker wrapper tests do and use clang-cc1
to directly get some random IR to use.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I suppose that's just as good. I do wonder if this is really the right directory for these tests at all. Its lit.local.cfg has a %clang_cc1 substitution that expands to a complaint that it shouldn't be used in Driver tests, so existing tests just use %clang -cc1
instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I did that. I used opt to discard the noinline attribute that clang introduces. If you know of a better way that doesn't perform inlining before the clang-linker-wrapper call, let me know.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-disable-O0-optnone handles the optnone, don't think noinline
affects that much.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
noinline prevents the inline pass in the test from succeeding.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, probably fine then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this looks good overall, though I'd like to hear some other clang maintainers chime in on the LIT config changes.
Thanks for the fast reviews.
For reference, I mostly copied that from the llvm test suite config. |
The original version was introduced here in c4bfb84.
Is there anyone specific we should ping for additional review? |
If no one's said anything yet I'd just push it. |
The goal of this patch is to enable utilizing LLVM plugin passes and remarks for GPU offload code at link time. Specifically, this patch extends clang-linker-wrapper's `--offload-opt` (and consequently `-mllvm`) to accept the various LLVM pass options that tools like opt usually accept. Those options include `--passes`, `--load-pass-plugin`, and various remarks options. Unlike many other LLVM options that are inherited from linked code by clang-linker-wrapper (e.g., `-pass-remarks` is already implemented in `llvm/lib/IR/DiagnosticHandler.cpp`), these options are implemented separately as needed by each tool (e.g., opt, llc). Fortunately, this patch is able to handle most of the implementation by passing the option values to `lto::Config`. For testing plugin support, this patch uses the simple `Bye` plugin from LLVM core, but that requires several small Clang test suite config extensions.
This reverts commit 90ccf21. Fixes: llvm#100212
…lvm#102226) This reverts commit 90ccf21. Fixes: llvm#100212
…lvm#102226) This reverts commit 90ccf21. Fixes: llvm#100212
…lvm#102226) This reverts commit 90ccf21. Fixes: llvm#100212 (cherry picked from commit 030ee84) Conflicts: clang/test/Driver/linker-wrapper-passes.c
The goal of this patch is to enable utilizing LLVM plugin passes and remarks for GPU offload code at link time. Specifically, this patch extends clang-linker-wrapper's
--offload-opt
(and consequently-mllvm
) to accept the various LLVM pass options that tools like opt usually accept. Those options include--passes
,--load-pass-plugin
, and various remarks options.Unlike many other LLVM options that are inherited from linked code by clang-linker-wrapper (e.g.,
-pass-remarks
is already implemented inllvm/lib/IR/DiagnosticHandler.cpp
), these options are implemented separately as needed by each tool (e.g., opt, llc). Fortunately, this patch is able to handle most of the implementation by passing the option values tolto::Config
.For testing plugin support, this patch uses the simple
Bye
plugin from LLVM core, but that requires several small Clang test suite config extensions.