Skip to content

Commit 22fab5a

Browse files
authored
[Driver][SYCL] Improve support for -fsycl-link with AOT (#12828)
Support for -fsycl-link was restricted to only providing device linking and providing the final device binary for JIT. These changes expand on that functionality to pull in the ability to also perform offline compilation steps to support AOT targets. Example: clang++ -fsycl -fsycl-targets=spir64_gen -c file.cpp clang++ -fsycl -fsycl-link -fsycl-targets=spir64_gen -Xsycl-target-backend "-device skl" file.o -o newfile.o clang++ file.o newfile.o -o finalexe 'newfile.o' here is a final device binary for GPU that is wrapped and allowed to be linked in as a regular host object. The changes here are significant, performing adjustments on when the device linking occurs within the compilation toolchain within the driver. This improves the general dependency flow, allowing for the device linking to occur in a common location for -fsycl-link and normal link steps. Due to this, a number of tests relying on phase checking required to be tweaked.
1 parent ce70f0d commit 22fab5a

38 files changed

+1017
-1441
lines changed

clang/lib/Driver/Driver.cpp

Lines changed: 150 additions & 112 deletions
Large diffs are not rendered by default.

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 62 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -9747,6 +9747,53 @@ void OffloadBundler::ConstructJobMultipleOutputs(
97479747

97489748
// Begin OffloadWrapper
97499749

9750+
static void addRunTimeWrapperOpts(Compilation &C,
9751+
Action::OffloadKind DeviceOffloadKind,
9752+
const llvm::opt::ArgList &TCArgs,
9753+
ArgStringList &CmdArgs,
9754+
const ToolChain &TC,
9755+
const JobAction &JA) {
9756+
// Grab any Target specific options that need to be added to the wrapper
9757+
// information.
9758+
ArgStringList BuildArgs;
9759+
auto createArgString = [&](const char *Opt) {
9760+
if (BuildArgs.empty())
9761+
return;
9762+
SmallString<128> AL;
9763+
for (const char *A : BuildArgs) {
9764+
if (AL.empty()) {
9765+
AL = A;
9766+
continue;
9767+
}
9768+
AL += " ";
9769+
AL += A;
9770+
}
9771+
CmdArgs.push_back(C.getArgs().MakeArgString(Twine(Opt) + AL));
9772+
};
9773+
const toolchains::SYCLToolChain &SYCLTC =
9774+
static_cast<const toolchains::SYCLToolChain &>(TC);
9775+
llvm::Triple TT = SYCLTC.getTriple();
9776+
// TODO: Consider separating the mechanisms for:
9777+
// - passing standard-defined options to AOT/JIT compilation steps;
9778+
// - passing AOT-compiler specific options.
9779+
// This would allow retaining standard language options in the
9780+
// image descriptor, while excluding tool-specific options that
9781+
// have been known to confuse RT implementations.
9782+
if (TT.getSubArch() == llvm::Triple::NoSubArch) {
9783+
// Only store compile/link opts in the image descriptor for the SPIR-V
9784+
// target; AOT compilation has already been performed otherwise.
9785+
const ArgList &Args = C.getArgsForToolChain(nullptr, StringRef(),
9786+
DeviceOffloadKind);
9787+
const ToolChain *HostTC = C.getSingleOffloadToolChain<Action::OFK_Host>();
9788+
SYCLTC.AddImpliedTargetArgs(TT, Args, BuildArgs, JA, *HostTC);
9789+
SYCLTC.TranslateBackendTargetArgs(TT, Args, BuildArgs);
9790+
createArgString("-compile-opts=");
9791+
BuildArgs.clear();
9792+
SYCLTC.TranslateLinkerTargetArgs(TT, Args, BuildArgs);
9793+
createArgString("-link-opts=");
9794+
}
9795+
}
9796+
97509797
void OffloadWrapper::ConstructJob(Compilation &C, const JobAction &JA,
97519798
const InputInfo &Output,
97529799
const InputInfoList &Inputs,
@@ -9792,6 +9839,9 @@ void OffloadWrapper::ConstructJob(Compilation &C, const JobAction &JA,
97929839
if (A->getValue() == StringRef("image"))
97939840
WrapperArgs.push_back(C.getArgs().MakeArgString("--emit-reg-funcs=0"));
97949841
}
9842+
addRunTimeWrapperOpts(C, OffloadingKind, TCArgs, WrapperArgs,
9843+
getToolChain(), JA);
9844+
97959845
// When wrapping an FPGA device binary, we need to be sure to apply the
97969846
// appropriate triple that corresponds (fpga_aocr-intel-<os>)
97979847
// to the target triple setting.
@@ -9807,42 +9857,8 @@ void OffloadWrapper::ConstructJob(Compilation &C, const JobAction &JA,
98079857
TT.setVendorName("intel");
98089858
TargetTripleOpt = TT.str();
98099859
}
9810-
// Grab any Target specific options that need to be added to the wrapper
9811-
// information.
9812-
ArgStringList BuildArgs;
9813-
auto createArgString = [&](const char *Opt) {
9814-
if (BuildArgs.empty())
9815-
return;
9816-
SmallString<128> AL;
9817-
for (const char *A : BuildArgs) {
9818-
if (AL.empty()) {
9819-
AL = A;
9820-
continue;
9821-
}
9822-
AL += " ";
9823-
AL += A;
9824-
}
9825-
WrapperArgs.push_back(C.getArgs().MakeArgString(Twine(Opt) + AL));
9826-
};
98279860
const toolchains::SYCLToolChain &TC =
98289861
static_cast<const toolchains::SYCLToolChain &>(getToolChain());
9829-
// TODO: Consider separating the mechanisms for:
9830-
// - passing standard-defined options to AOT/JIT compilation steps;
9831-
// - passing AOT-compiler specific options.
9832-
// This would allow retaining standard language options in the
9833-
// image descriptor, while excluding tool-specific options that
9834-
// have been known to confuse RT implementations.
9835-
if (TC.getTriple().getSubArch() == llvm::Triple::NoSubArch) {
9836-
// Only store compile/link opts in the image descriptor for the SPIR-V
9837-
// target; AOT compilation has already been performed otherwise.
9838-
const ToolChain *HostTC = C.getSingleOffloadToolChain<Action::OFK_Host>();
9839-
TC.AddImpliedTargetArgs(TT, TCArgs, BuildArgs, JA, *HostTC);
9840-
TC.TranslateBackendTargetArgs(TT, TCArgs, BuildArgs);
9841-
createArgString("-compile-opts=");
9842-
BuildArgs.clear();
9843-
TC.TranslateLinkerTargetArgs(TT, TCArgs, BuildArgs);
9844-
createArgString("-link-opts=");
9845-
}
98469862
bool IsEmbeddedIR = cast<OffloadWrapperJobAction>(JA).isEmbeddedIR();
98479863
if (IsEmbeddedIR) {
98489864
// When the offload-wrapper is called to embed LLVM IR, add a prefix to
@@ -9984,8 +10000,18 @@ void OffloadWrapper::ConstructJob(Compilation &C, const JobAction &JA,
998410000
// And add it to the offload targets.
998510001
CmdArgs.push_back(C.getArgs().MakeArgString(
998610002
Twine("-kind=") + Action::GetOffloadKindName(DeviceKind)));
9987-
CmdArgs.push_back(TCArgs.MakeArgString(Twine("-target=") +
9988-
DeviceTC->getTriple().normalize()));
10003+
std::string TargetTripleOpt = DeviceTC->getTriple().normalize();
10004+
// SYCL toolchain target only uses the arch name.
10005+
if (DeviceKind == Action::OFK_SYCL)
10006+
TargetTripleOpt = DeviceTC->getTriple().getArchName();
10007+
CmdArgs.push_back(
10008+
TCArgs.MakeArgString(Twine("-target=") + TargetTripleOpt));
10009+
addRunTimeWrapperOpts(C, DeviceKind, TCArgs, CmdArgs, *DeviceTC, JA);
10010+
10011+
if (Inputs[I].getType() == types::TY_Tempfiletable ||
10012+
Inputs[I].getType() == types::TY_Tempfilelist)
10013+
// wrapper actual input files are passed via the batch job file table:
10014+
CmdArgs.push_back(C.getArgs().MakeArgString("-batch"));
998910015

999010016
// Add input.
999110017
assert(Inputs[I].isFilename() && "Invalid input.");

0 commit comments

Comments
 (0)