[NewOffloadModel] Refactor device compiler and linker option parsing in ClangLinkerWrapper#21055
Conversation
|
I haven’t seen any issues with removing the |
I guess it is because our variant of new offloading model is not using them, but most likely community variant of the code (for other programming models at least) will likely fail, after this change. |
|
I don’t think the current CI failure is related to the change in this PR, as our change only affects tests with the new offloading model. |
| continue; | ||
| Arg = Arg.substr(ColonPos + 1); | ||
| } | ||
| size_t EqPos = Arg.find('='); |
There was a problem hiding this comment.
Can you add a comment giving an example value of Arg and then explain how we process it? It seems we are looking both for a : and for =. I want to understand the processing we are doing here a bit better
There was a problem hiding this comment.
For sure! I’ve added the following comment before the lambda function to explain the --device-compiler and --device-linker arguments passed to the clang-linker-wrapper.
// The device_linker_args and device_compiler_args options accept values
// in the form [<kind>:][<triple>=]<value>.
// An example of passing such an option to clang-linker-wrapper is:
// --device-compiler=spir64_gen-unknown-unknown=opt_val.
| // Filter the SYCL device compiler and linker options by target triple and | ||
| // offload kind. | ||
| const StringRef TripleStr = DAL.getLastArgValue(OPT_triple_EQ); | ||
| auto processDeviceArgs = [&](unsigned DeviceOptID, unsigned OptID) { |
There was a problem hiding this comment.
Can we give these arguments some more descriptive names?
There was a problem hiding this comment.
Thanks for the suggestion! I have changed it to be
auto ProcessDeviceArgs =
[&](unsigned DeviceArgsOptionID, unsigned ForwardedOptionID) {
| CompileLinkOptionsOrErr->first, | ||
| CompileLinkOptionsOrErr->second); | ||
| StringRef DeviceCompilerArgs = | ||
| LinkerArgs.getLastArgValue(OPT_compiler_arg_EQ); |
There was a problem hiding this comment.
Is this part combining the flags from the image with the command line flags from the tool? If so please add a comment
There was a problem hiding this comment.
Yes, this is the part for combing the flags from the image with argument passed via option -device-compiler= and -device-linker= to clang-linker-warpper? I have added a comment in the code. Thank you! ;)
| // Filter the SYCL device compiler and linker options by target triple and | ||
| // offload kind. | ||
| const StringRef TripleStr = DAL.getLastArgValue(OPT_triple_EQ); | ||
| auto processDeviceArgs = [&](unsigned DeviceOptID, unsigned OptID) { |
There was a problem hiding this comment.
nit: usually we start lambda names with a capital letter
There was a problem hiding this comment.
Thank you for pointing this out! I have made the change.
| // offload kind. | ||
| const StringRef TripleStr = DAL.getLastArgValue(OPT_triple_EQ); | ||
| auto processDeviceArgs = [&](unsigned DeviceOptID, unsigned OptID) { | ||
| for (StringRef Arg : Args.getAllArgValues(DeviceOptID)) { |
There was a problem hiding this comment.
nit: Rename variable Arg to DeviceArgValue or something similar as this is not an Arg*, but the values attached to the --device-compiler or --device-linker
There was a problem hiding this comment.
Thank you for the suggestion! I have rename the variable to DeviceArgValue.
| for (StringRef Arg : Args.getAllArgValues(DeviceOptID)) { | ||
| size_t ColonPos = Arg.find(':'); | ||
| if (ColonPos != StringRef::npos) { | ||
| StringRef Kind = Arg.substr(0, ColonPos); |
There was a problem hiding this comment.
nit: For better readability consider using drop_front and take_front functions instead of substr functions as appropriate.
There was a problem hiding this comment.
I also agree that using drop_front and take_front would be better. I have made the change.
|
I don’t think the current CI failure is related to the changes in this patch. The failures seems to be caused by the CI machine itself, and I am seeing similar issues with other PRs as well. Thank you! |
| auto ProcessDeviceArgs = [&](unsigned DeviceArgsOptionID, | ||
| unsigned ForwardedOptionID) { |
There was a problem hiding this comment.
| auto ProcessDeviceArgs = [&](unsigned DeviceArgsOptionID, | |
| unsigned ForwardedOptionID) { | |
| auto ProcessDeviceArgs = [&](llvm::opt::OptSpecifier DeviceArgsOptionID, | |
| llvm::opt::OptSpecifier ForwardedOptionID) { |
nit - while technically it is an unsigned, using OptSpecifier provides some clarity.
There was a problem hiding this comment.
Thank you for the suggestion! I have made the changes :)
sarnex
left a comment
There was a problem hiding this comment.
looks good just some minor questions
| llvm::opt::OptSpecifier ForwardedOptionID) { | ||
| for (StringRef DeviceArgValue : Args.getAllArgValues(DeviceArgsOptionID)) { | ||
| size_t ColonPos = DeviceArgValue.find(':'); | ||
| if (ColonPos != StringRef::npos) { |
There was a problem hiding this comment.
Should we instead change all the != npos checks to be if ( == npos) continue? Or are there valid cases where some of those might not be present?
There was a problem hiding this comment.
Thanks for the suggestion! Yes, there could be cases where the argument contains only <kind>:<value>, only <triple>=<value>, or even just <value> (both <kind> and <triple> are optional). If we use continue, it would skip cases where either <kind> or <triple> is not available.
There was a problem hiding this comment.
got it, thanks. my third question seems related to this so ill ask a follow-up there
| // If this isn't a recognized triple then it's an `arg=value` option. | ||
| if (TT.getArch() != Triple::ArchType::UnknownArch) { | ||
| if (TargetTriple != TripleStr) | ||
| continue; |
There was a problem hiding this comment.
In what cases will the driver generate arg=value instead of including the triple?
There was a problem hiding this comment.
There is an example found at
llvm/clang/test/Driver/linker-wrapper.c
Lines 145 to 148 in edd04ef
In this example,
foo=bar is passed as an argument to -device-linker, and foo is not an triple. I am not sure when this case would happen, and this is the only test found that tests this behavior. This line is added to allow this test case. Also, before this patch, we were also supporting the case of arg=value; removing it may make our code less aligned with the community code. Please feel free to let me know if there is any suggestion on this :) Thank you!
There was a problem hiding this comment.
@mdtoguchi Do you think we need to support the above argument style? Or should we just change the test
There was a problem hiding this comment.
The argument style can present itself externally - but albeit only with using the internal undocumented -Zlinker-input option. Weird case, but as community supports it we should as well.
|
@intel/llvm-gatekeepers I don't think the CI failure is related to the change in this patch. Could you please help merge the PR? Thank you! |
|
Still needs a review from @intel/dpcpp-clang-driver-reviewers |
|
@YuriPlyakhin I think you need to remove your 'Requested changes' before we can merge (unless I should force merge) |
@intel/llvm-gatekeepers I have removed the |
This patch refactors the parsing of device compiler and linker options in
clang-linker-wrapper.The specific changes are listed below:
appendSYCLDeviceOptionsAtLinkTime()directly intogetLinkerArgs()in ClangLinkerWrapper.cpp, so the ArgList returned bygetLinkerArgs()includes bothlinker_arg_EQandcompiler_arg_EQoptions, which are the filtered options ofOPT_device_linker_args_EQandOPT_device_compiler_args_EQ.OPT_compiler_arg_EQandOPT_linker_arg_EQare now storing both the options passed to the backend compiler and the options passed to the Clang command for linking.With this patch, the SYCL E2E test
KernelAndProgram/kernel-bundle-merge-options-env.cpppass with the new offloading mode.