-
Notifications
You must be signed in to change notification settings - Fork 798
[NewOffloadModel] Remove compiler backend option and linker option to be passed as argument for ClangLinkerWrapper #20691
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
base: sycl
Are you sure you want to change the base?
Conversation
43ec9a6 to
2c3b7bc
Compare
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.
Pull request overview
This PR removes the passing of backend compiler and linker options via --gpu-tool-arg and --cpu-tool-arg arguments to ClangLinkerWrapper. Instead, these options are now consumed directly from SYCLImage metadata using the --device-compiler argument format. The change simplifies the option passing mechanism by consolidating all backend compile options through a single path.
- Remove obsolete
gpu_tool_arg_EQandcpu_tool_arg_EQoption definitions - Refactor option handling in ClangLinkerWrapper to use
--device-compilerformat instead - Update
runSYCLPostLinkToolto acceptHasGPUToolboolean parameter instead of checking removed option
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td | Removes gpu_tool_arg_EQ and cpu_tool_arg_EQ option definitions |
| clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp | Updates option processing to use HasGPUTool parameter and adds handling for OPT_device_compiler_args_EQ |
| clang/lib/Driver/ToolChains/Clang.cpp | Refactors argument construction to pass backend options via --device-compiler instead of removed wrapper options |
| clang/lib/Driver/Driver.cpp | Adds GetUseNewOffloadDriverForSYCLOffload utility function to determine when to use new offload driver |
| clang/include/clang/Driver/Driver.h | Declares GetUseNewOffloadDriverForSYCLOffload function |
| clang/test/Driver/*.cpp | Updates test expectations to check for new --device-compiler argument format |
|
5 SYCL E2E tests passed (test names are listed in the PR description, and 3 pm_access_n test were only failing in Self Build CI before), and no SYCL E2E test or driver test regression occurred when the new offloading model was enabled as default together with my changes (the CI before removing new offloading changes from this PR can be found at https://github.com/intel/llvm/actions/runs/19864471834/job/56923211306?pr=20691) |
| "--device-linker=" + TC->getTripleString() + "=" + Arg)); | ||
| // SYCL offload toolchains handle device compiler and linker argument forwarding using SYCLImage. | ||
| // Therefore, we skip forwarding these arguments here when a SYCL offload toolchain is present. | ||
| if (!C.hasOffloadToolChain<Action::OFK_SYCL>()) { |
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 it possible to avoid this SYCL-specific customization? What happens if we keep this for SYCL as well?
If I understand correctly @mdtoguchi : "The expected behavior is for any device options to be handled at both compile and link time. ", we need to keep this code and pass user-specified options to clang-linker-wrapper same as for any other programming model.
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.
Where does CompilerArgs and LinkerArgs come from? I mean, is it from some clang++ arguments?
|
|
||
| /// Test option passing behavior for clang-offload-wrapper options. | ||
| // RUN: %clangxx --target=x86_64-unknown-linux-gnu -fsycl --offload-new-driver \ | ||
| // RUN: -Xsycl-target-backend -backend-opt -### %s 2>&1 \ |
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.
Per my understanding, we still need to pass -backend-opt to clang-linker-wrapper through device-compiler option.
so this test should be just updated to use proper clang-linker-wrapper option.
Similar for linker options.
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.
Thanks for pointing this out!
I think for backend option and linker option that are passed at compile time, they are stored in the SYCLImage like --image=file=... compile-opts=... -backend-opt. The option that are stored in the SYCLImage got directly extracted in clang-linker-wrapper (this is done is another PR #19579 and extractSYCLCompileLinkOptions function found at https://github.com/YixingZhang007/llvm/blob/fe390ac353c65ec85ccd2b3bf7883a1efca55a5e/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp#L2218).
Only the -backend-opt that are passed at link time for AOT, which should be through format clang++ ... -fsycl-targets=spir64_gen -Xsycl-target-backend=spir64_gen -backend-gen-opt will added to device-compiler and passed to the clang-linker-wrapper.
Therefore, for this test and the one got deleted below, -backend-opt and -link-opt are passed through the SYCLImage but not directly added as argument for clang-linker-wrapper :)
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.
Yes, I understand how it works with your implementation. And I challenge that. Despite we extracted and put options to SYCLImage on compile stage, we still want to pass these options to link stage as well.
Example of when this is needed is if we provide both source and object files as an input to clang++.
|
|
||
| // RUN: %clang -### -target x86_64-unknown-linux-gnu -fsycl --offload-new-driver -fsycl-targets=spir64-unknown-unknown -Xsycl-target-backend "-DFOO1 -DFOO2" %s 2>&1 \ | ||
| // RUN: | FileCheck -check-prefix=CHK-TOOLS-OPTS %s | ||
| // CHK-TOOLS-OPTS: clang-linker-wrapper{{.*}} "--sycl-backend-compile-options=-DFOO1 -DFOO2" |
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.
similar here, per my understanding, need to pass options using device-compiler
|
|
||
| // RUN: %clang -### -target x86_64-unknown-linux-gnu -fsycl --offload-new-driver -fsycl-targets=spir64-unknown-unknown -Xsycl-target-linker "-DFOO1 -DFOO2" %s 2>&1 \ | ||
| // RUN: | FileCheck -check-prefix=CHK-TOOLS-OPTS2 %s | ||
| // CHK-TOOLS-OPTS2: clang-linker-wrapper{{.*}} "--sycl-target-link-options=-DFOO1 -DFOO2" |
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.
same here, but for device-linker
| // RUN: | FileCheck -check-prefixes=SYCL_TARGET_OPT %s | ||
| // RUN: %clangxx -### -target x86_64-unknown-linux-gnu -fsycl --offload-new-driver -Xsycl-target-backend=spir64 -DFOO -Xsycl-target-linker=spir64 -DFOO2 %S/Inputs/SYCL/objlin64.o 2>&1 \ | ||
| // RUN: | FileCheck -check-prefixes=SYCL_TARGET_OPT %s | ||
| // SYCL_TARGET_OPT: clang-linker-wrapper{{.*}} "--sycl-backend-compile-options=-DFOO" "--sycl-target-link-options=-DFOO2" |
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.
same here...
|
|
||
| SmallVector<StringRef, 16> Args; | ||
| StringRef(CompileLinkOptionsOrErr->first).split(Args, ' '); | ||
| bool HasGPUTool = |
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.
The name of the variable is a bit confusing to me. Would something like this be better?
IsDevicePassedWithSyclTargetBackend. Maybe a little bit verbose, but maybe it is OK.
| static Expected<std::vector<module_split::SplitModule>> | ||
| runSYCLPostLinkTool(ArrayRef<StringRef> InputFiles, const ArgList &Args) { | ||
| runSYCLPostLinkTool(ArrayRef<StringRef> InputFiles, const ArgList &Args, | ||
| bool HasGPUTool) { |
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.
new parameter needs to be documented in comments above
| StringRef OptTool = (IsCPU) ? Args.getLastArgValue(OPT_cpu_tool_arg_EQ) | ||
| : Args.getLastArgValue(OPT_gpu_tool_arg_EQ); | ||
| OptTool.split(CmdArgs, " ", /*MaxSplit=*/-1, /*KeepEmpty=*/false); | ||
| return; |
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.
this return is also unnecessary, right?
| } | ||
| } | ||
|
|
||
| StringRef OptTool = (IsCPU) ? Args.getLastArgValue(OPT_cpu_tool_arg_EQ) |
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.
Args parameter is not used anymore in this function and can be removed.
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.
Or maybe we need to handle OPT_device_compiler_args_EQ here.
I think it depends on how such options are handled for other programming models. We need to try to be as close as possible to upstream...
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.
Thanks for the suggestion!
The reason I didn't move the handling of OPT_device_compiler_args_EQ to here is that -device xxx may be passed as a link-time backend argument, and we need to check for that in linkAndWrapDeviceFiles (found at https://github.com/YixingZhang007/llvm/blob/fe390ac353c65ec85ccd2b3bf7883a1efca55a5e/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp#L2250) so that we can determine whether we need to add the device name in front of the output table.
Therefore, to avoid processing OPT_device_compiler_args_EQ twice, I add OPT_device_compiler_args_EQ to CompileLinkOptionsOrErr in linkAndWrapDeviceFiles, and CompileLinkOptionsOrErr is later passed as BackendOptions to this function.
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, now I see that order of options did not change. So, I guess, just remove the Args param as not used.
In another patch #19579, compilation and linking options used in ClangLinkerWrapper are changed to be consumed from the
SYCLImage, instead ofsycl_backend_compile_options_EQandsycl_target_link_options_EQthat are passed as argument to the ClangLinkerWrapper. Since the compiler option and linker option passed into ClangLinkerWrapper are no longer useful, this PR remove them to be passed into ClangLinkerWrapper. The specific changes are listed below.BackendOptStringandLinkOptStringand append to the argument for calling ClangLinkerWrapper are removed inClang.cpp.gpu_tool_arg_EQandcpu_tool_arg_EQoptions specification inLinkerWrapperOpts.td. We are now passing the link time backend compile option for GPU and CPU throughOPT_device_compiler_args_EQto ClangLinkerWrapper, as coded inClang.cpp.ClangLinkerWrapper.cpp, the option inOPT_device_compiler_args_EQare added toSYCLBackendOptionsand handled together with other compiler option passed throughSYCLImage.With this patch, the following SYCL E2E tests pass with the new offloading model: