Skip to content
Open
59 changes: 59 additions & 0 deletions clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@ static bool CanonicalPrefixes = true;

using OffloadingImage = OffloadBinary::OffloadingImage;

// TODO: Remove this once the linking and backend compilation have been fully
// migrated to clang-sycl-linker.
bool UseClangSYCLLinker = false;

namespace llvm {
// Provide DenseMapInfo so that OffloadKind can be used in a DenseMap.
template <> struct DenseMapInfo<OffloadKind> {
Expand Down Expand Up @@ -1714,6 +1718,50 @@ Error extractBundledObjects(StringRef Filename, const ArgList &Args,
} // namespace sycl

namespace generic {
// Forwards all required flags to the clang-sycl-linker via -Xlinker.
static void appendClangSYCLLinkerArgs(const ArgList &Args,
SmallVectorImpl<StringRef> &CmdArgs,
const llvm::Triple &Triple,
StringRef Arch) {
auto XLinker = [&](const Twine &Arg) {
CmdArgs.append({"-Xlinker", Args.MakeArgString(Arg)});
};

XLinker("--triple=" + Triple.getTriple());
if (!Arch.empty())
XLinker("--arch=" + Arch);

static const OptSpecifier DirectOpts[] = {
OPT_save_temps,
OPT_dry_run,
OPT_print_wrapped_module,
OPT_sycl_thin_lto,
OPT_sycl_allow_device_image_dependencies,
OPT_sycl_remove_unused_external_funcs,
OPT_no_sycl_remove_unused_external_funcs,
OPT_sycl_device_code_split_esimd,
OPT_no_sycl_device_code_split_esimd,
OPT_sycl_add_default_spec_consts_image,
OPT_no_sycl_add_default_spec_consts_image,
};
for (OptSpecifier Opt : DirectOpts) {
if (Arg *A = Args.getLastArg(Opt)) {
XLinker("--" + A->getOption().getName().str());
}
}

static const OptSpecifier ValueOpts[] = {
OPT_sycl_dump_device_code_EQ, OPT_llvm_spirv_options_EQ,
OPT_sycl_post_link_options_EQ, OPT_syclbin_EQ,
OPT_bitcode_library_EQ,
};
for (OptSpecifier Opt : ValueOpts) {
if (const opt::Arg *A = Args.getLastArg(Opt)) {
XLinker("--" + A->getOption().getName().str() + A->getValue());
}
}
}

Expected<StringRef> clang(ArrayRef<StringRef> InputFiles, const ArgList &Args,
bool IsSYCLKind = false) {
llvm::TimeTraceScope TimeScope("Clang");
Expand Down Expand Up @@ -1752,6 +1800,17 @@ Expected<StringRef> clang(ArrayRef<StringRef> InputFiles, const ArgList &Args,
(Triple.isNativeCPU() ? HostTriple : Triple).getTriple()),
};

if (UseClangSYCLLinker) {
CmdArgs.push_back("-fsycl");
CmdArgs.push_back("--sycl-link");
appendClangSYCLLinkerArgs(Args, CmdArgs, Triple, Arch);
for (StringRef InputFile : InputFiles)
CmdArgs.append({"-Xlinker", Args.MakeArgString(InputFile)});
if (Error Err = executeCommands(*ClangPath, CmdArgs))
return std::move(Err);
return *TempFileOrErr;
}

if (!Arch.empty())
Triple.isAMDGPU() ? CmdArgs.push_back(Args.MakeArgString("-mcpu=" + Arch))
: CmdArgs.push_back(Args.MakeArgString("-march=" + Arch));
Expand Down
45 changes: 45 additions & 0 deletions clang/tools/clang-sycl-linker/SYCLLinkOpts.td
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,48 @@ def ocloc_options_EQ : Joined<["--", "-"], "ocloc-options=">,
def opencl_aot_options_EQ : Joined<["--", "-"], "opencl-aot-options=">,
Flags<[LinkerOnlyOption]>,
HelpText<"Options passed to opencl-aot for Intel CPU AOT compilation">;

def llvm_spirv_options_EQ : Joined<["--", "-"], "llvm-spirv-options=">,
Flags<[LinkerOnlyOption]>,
HelpText<"Options passed to llvm-spirv for LLVM IR to SPIR-V translation">;

def sycl_post_link_options_EQ : Joined<["--", "-"], "sycl-post-link-options=">,
Flags<[LinkerOnlyOption]>,
HelpText<"Options passed to sycl-post-link tool">;

// Options to specify additional bitcode libraries linked with -only-needed.
def bitcode_library_EQ : Joined<["--"], "bitcode-library=">,
Flags<[LinkerOnlyOption]>, MetaVarName<"<kind>-<triple>-<arch>=<path>">,
HelpText<"Extra bitcode library to link">;

def no_canonical_prefixes : Flag<["--"], "no-canonical-prefixes">,
Flags<[LinkerOnlyOption]>,
HelpText<"Do not resolve symbolic links, turn relative paths into absolute ones, or do anything else to identify the executable">;

// Extra SYCL options to help generate sycl-post-link options that also depend
// on the target triple.
def sycl_remove_unused_external_funcs : Flag<["--", "-"], "sycl-remove-unused-external-funcs">,
Flags<[LinkerOnlyOption, HelpHidden]>;
def no_sycl_remove_unused_external_funcs : Flag<["--", "-"], "no-sycl-remove-unused-external-funcs">,
Flags<[LinkerOnlyOption, HelpHidden]>;
def sycl_device_code_split_esimd : Flag<["--", "-"], "sycl-device-code-split-esimd">,
Flags<[LinkerOnlyOption, HelpHidden]>;
def no_sycl_device_code_split_esimd : Flag<["--", "-"], "no-sycl-device-code-split-esimd">,
Flags<[LinkerOnlyOption, HelpHidden]>;
def sycl_add_default_spec_consts_image : Flag<["--", "-"], "sycl-add-default-spec-consts-image">,
Flags<[LinkerOnlyOption, HelpHidden]>;
def no_sycl_add_default_spec_consts_image : Flag<["--", "-"], "no-sycl-add-default-spec-consts-image">,
Flags<[LinkerOnlyOption, HelpHidden]>;

def sycl_thin_lto : Flag<["--", "-"], "sycl-thin-lto">,
Flags<[LinkerOnlyOption]>, HelpText<"Link SYCL device code using thinLTO">;

// Options to enable/disable device dynamic linking.
def sycl_allow_device_image_dependencies : Flag<["--", "-"], "sycl-allow-device-image-dependencies">,
Flags<[LinkerOnlyOption, HelpHidden]>,
HelpText<"Allow dependencies between device code images">;

// Options to force the output to be of the SYCLBIN format.
def syclbin_EQ : Joined<["--", "-"], "syclbin=">,
Flags<[LinkerOnlyOption]>,
HelpText<"Output in the SYCLBIN binary format in the state specified by <arg> (input, object or executable)">;
Loading