Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions clang/include/clang/Options/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -7903,6 +7903,11 @@ def fsycl_help_EQ
def fsycl_help : Flag<["-"], "fsycl-help">, Alias<fsycl_help_EQ>,
Flags<[NoXarchOption]>, AliasArgs<["all"]>,
HelpText<"Emit help information from all of the offline compilation tools">;
def ocloc_path_EQ : Joined<["--"], "ocloc-path=">,
Visibility<[ClangOption, CLOption]>,
Flags<[NoXarchOption, NoArgumentUnused]>, MetaVarName<"<path>">,
HelpText<"Path to the ocloc tool, which is used for ahead of time "
"compilation targeting Intel GPUs">;
Comment thread
mdtoguchi marked this conversation as resolved.
def fsycl_libspirv_path_EQ : Joined<["-"], "fsycl-libspirv-path=">,
HelpText<"Path to libspirv library">;
def fno_sycl_libspirv : Flag<["-"], "fno-sycl-libspirv">,
Expand Down
10 changes: 8 additions & 2 deletions clang/lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2830,8 +2830,14 @@ void Driver::PrintSYCLToolHelp(const Compilation &C) const {
llvm::outs().flush();
std::vector<StringRef> ToolArgs = {std::get<1>(HA), std::get<2>(HA),
std::get<3>(HA)};
SmallString<128> ExecPath(
C.getDefaultToolChain().GetProgramPath(std::get<1>(HA).data()));
SmallString<128> ExecPath;
// A user provided --ocloc-path= overrides the usual tool lookup for ocloc.
if (Arg *A = C.getArgs().getLastArg(options::OPT_ocloc_path_EQ);
Comment thread
YuriPlyakhin marked this conversation as resolved.
Outdated
A && std::get<1>(HA) == "ocloc") {
Comment thread
YuriPlyakhin marked this conversation as resolved.
Outdated
ExecPath = A->getValue();
llvm::sys::path::append(ExecPath, std::get<1>(HA));
} else
ExecPath = C.getDefaultToolChain().GetProgramPath(std::get<1>(HA).data());
Comment thread
YuriPlyakhin marked this conversation as resolved.
Outdated
// do not run the tools with -###.
if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
llvm::errs() << "\"" << ExecPath << "\" \"" << ToolArgs[1] << "\"";
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12132,6 +12132,11 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA,
// Add any SYCL offloading specific options to the clang-linker-wrapper
if (C.hasOffloadToolChain<Action::OFK_SYCL>()) {

// Forward the user provided location for ocloc.
if (Arg *A = Args.getLastArg(options::OPT_ocloc_path_EQ))
CmdArgs.push_back(
Args.MakeArgString(Twine("--ocloc-path=") + A->getValue()));
Comment thread
mdtoguchi marked this conversation as resolved.

if (Args.hasArg(options::OPT_fsycl_link_EQ))
CmdArgs.push_back(Args.MakeArgString("--sycl-device-link"));

Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Driver/ToolChains/SPIRV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,10 @@ void SPIRV::Linker::ConstructJob(Compilation &C, const JobAction &JA,
Linker = ToolChain.GetProgramPath("clang-sycl-linker");
if (Args.hasArg(options::OPT_v))
CmdArgs.push_back("-v");
// Forward the user provided location to ocloc.
if (Arg *A = Args.getLastArg(options::OPT_ocloc_path_EQ))
CmdArgs.push_back(
Args.MakeArgString(Twine("--ocloc-path=") + A->getValue()));
} else if (!llvm::sys::fs::can_execute(Linker) &&
!C.getArgs().hasArg(clang::options::OPT__HASH_HASH_HASH)) {
C.getDriver().Diag(clang::diag::err_drv_no_spv_tools) << getShortName();
Expand Down
17 changes: 14 additions & 3 deletions clang/lib/Driver/ToolChains/SYCL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1054,6 +1054,19 @@ static const char *makeExeName(Compilation &C, StringRef Name) {
return C.getArgs().MakeArgString(ExeName);
}

const char *SYCL::gen::getOclocPath(Compilation &C, const ToolChain &TC,
const llvm::opt::ArgList &Args) {
const char *ExeName = makeExeName(C, "ocloc");
// A user provided --ocloc-path= takes precedence over any ocloc that is
// found via the program paths or the PATH environment variable.
if (Arg *A = Args.getLastArg(options::OPT_ocloc_path_EQ)) {
SmallString<128> OclocPath(A->getValue());
llvm::sys::path::append(OclocPath, ExeName);
return C.getArgs().MakeArgString(OclocPath);
}
return C.getArgs().MakeArgString(TC.GetProgramPath(ExeName));
Comment thread
YuriPlyakhin marked this conversation as resolved.
}

// Determine if any of the given arguments contain any PVC based values for
// the -device option.
static bool hasPVCDevice(const ArgStringList &CmdArgs, std::string &DevArg) {
Expand Down Expand Up @@ -1117,9 +1130,7 @@ void SYCL::gen::BackendCompiler::ConstructJob(Compilation &C,
Device);
TC.TranslateLinkerTargetArgs(getToolChain().getTriple(), Args, CmdArgs,
Device);
SmallString<128> ExecPath(
getToolChain().GetProgramPath(makeExeName(C, "ocloc")));
const char *Exec = C.getArgs().MakeArgString(ExecPath);
const char *Exec = SYCL::gen::getOclocPath(C, getToolChain(), Args);
auto Cmd = std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
Exec, CmdArgs, ArrayRef<InputInfo>{});
if (!ForeachInputs.empty()) {
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/Driver/ToolChains/SYCL.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ StringRef resolveGenDevice(StringRef DeviceName);
SmallString<64> getGenDeviceMacro(StringRef DeviceName);
StringRef getGenGRFFlag(StringRef GRFMode);

// Returns the full path of the ocloc tool to be used for AOT compilation. A
// user provided --ocloc-path= is honored above all other lookup locations.
// If not found, the tool (ocloc) is returned with no directory.
const char *getOclocPath(Compilation &C, const ToolChain &TC,
Comment thread
YuriPlyakhin marked this conversation as resolved.
Outdated
const llvm::opt::ArgList &Args);

// Prefix for GPU specific targets used for -fsycl-targets
constexpr char IntelGPU[] = "intel_gpu_";
constexpr char NvidiaGPU[] = "nvidia_gpu_";
Expand Down
11 changes: 11 additions & 0 deletions clang/test/Driver/clang-linker-wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,17 @@
// CHK-NO-CMDS-AOT-GEN-LINKERARG: sycl-post-link{{.*}} -o {{[^,]*}}.table {{.*}}.bc
// CHK-NO-CMDS-AOT-GEN-LINKERARG: ocloc{{.*}} -device pvc -output

// Check that --ocloc-path= provides the location of the ocloc tool.
// RUN: clang-linker-wrapper --ocloc-path=/my/ocloc/dir --linker-path=/usr/bin/ld -o /dev/null %t1.o --dry-run 2>&1 | FileCheck -check-prefix=CHK-OCLOC-PATH %s
// CHK-OCLOC-PATH: "/my/ocloc/dir{{[/\\]+}}ocloc" -output_no_suffix
// Check that --ocloc-path= is not forwarded on to the host linker.
Comment thread
mdtoguchi marked this conversation as resolved.
// CHK-OCLOC-PATH-NOT: ld{{.*}} --ocloc-path=

// Check the diagnostic emitted when ocloc cannot be found in the given
// directory.
// RUN: not clang-linker-wrapper --ocloc-path=%t.no-ocloc-here --linker-path=/usr/bin/ld -o /dev/null %t1.o 2>&1 | FileCheck -check-prefix=CHK-OCLOC-PATH-ERR %s
// CHK-OCLOC-PATH-ERR: Unable to find 'ocloc' in '{{.*}}no-ocloc-here'

/// Check for list of commands for standalone clang-linker-wrapper run for sycl (AOT for Intel CPU)
// -------
// Generate .o file as linker wrapper input.
Expand Down
67 changes: 67 additions & 0 deletions clang/test/Driver/sycl-ocloc-path.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
///
/// Tests for --ocloc-path=, which provides the location of the externally
/// acquired ocloc tool used for Intel GPU AOT compilation.
///

// REQUIRES: x86-registered-target

/// Check that --ocloc-path= is used for the old offloading model.
// RUN: %clang -### -fsycl --no-offload-new-driver -fsycl-targets=spir64_gen \
// RUN: --ocloc-path=/my/ocloc/dir %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHK-OCLOC-PATH-OLD %s
// RUN: %clang -### -fsycl --no-offload-new-driver \
// RUN: -fsycl-targets=intel_gpu_pvc --ocloc-path=/my/ocloc/dir %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHK-OCLOC-PATH-OLD %s
// CHK-OCLOC-PATH-OLD: "/my/ocloc/dir{{[/\\]+}}ocloc{{(\.exe)?}}" "-output"

/// Check that the user provided location wins over an ocloc that is visible
/// via the PATH. The fake ocloc must be findable, which means it needs the
/// execute bit set on linux and the executable extension on windows.
// RUN: rm -rf %t.dir && mkdir -p %t.dir
// RUN: %if system-windows %{ touch %t.dir/ocloc.exe %} \
// RUN: %else %{ touch %t.dir/ocloc && chmod +x %t.dir/ocloc %}
// RUN: env "PATH=%t.dir%{pathsep}%PATH%" %clang -### -fsycl \
// RUN: --no-offload-new-driver -fsycl-targets=spir64_gen \
// RUN: --ocloc-path=/my/ocloc/dir %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHK-OCLOC-PATH-OLD %s

/// Check that the 'exe' name is used for windows.
// RUN: %clang_cl -### -fsycl --no-offload-new-driver \
// RUN: -fsycl-targets=spir64_gen --ocloc-path=/my/ocloc/dir -- %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHK-OCLOC-PATH-OLD-WIN %s
// RUN: %clang -### -target x86_64-pc-windows-msvc -fsycl \
// RUN: --no-offload-new-driver -fsycl-targets=spir64_gen \
// RUN: --ocloc-path=/my/ocloc/dir %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHK-OCLOC-PATH-OLD-WIN %s
// CHK-OCLOC-PATH-OLD-WIN: "/my/ocloc/dir{{[/\\]+}}ocloc.exe" "-output"

/// Check that --ocloc-path= is forwarded to the clang-linker-wrapper for the
/// new offloading model.
// RUN: %clang -### -fsycl --offload-new-driver -fsycl-targets=spir64_gen \
// RUN: --sysroot=%S/Inputs/SYCL --ocloc-path=/my/ocloc/dir %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHK-OCLOC-PATH-NEW %s
// RUN: %clang -### -fsycl --offload-new-driver \
// RUN: -fsycl-targets=intel_gpu_pvc --sysroot=%S/Inputs/SYCL \
// RUN: --ocloc-path=/my/ocloc/dir %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHK-OCLOC-PATH-NEW %s
// CHK-OCLOC-PATH-NEW: clang-linker-wrapper{{.*}} "--ocloc-path=/my/ocloc/dir"

/// Check that --ocloc-path= is forwarded to the clang-sycl-linker.
// RUN: touch %t.bc
// RUN: %clangxx -### --target=spirv64 --sycl-link \
// RUN: --ocloc-path=/my/ocloc/dir %t.bc 2>&1 \
// RUN: | FileCheck -check-prefix=CHK-OCLOC-PATH-SYCL-LINK %s
// CHK-OCLOC-PATH-SYCL-LINK: clang-sycl-linker{{.*}} "--ocloc-path=/my/ocloc/dir"

/// Check that --ocloc-path= is used when emitting the ocloc help information.
// RUN: %clang -### -fsycl -fsycl-help=gen --ocloc-path=/my/ocloc/dir %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHK-OCLOC-PATH-HELP %s
// CHK-OCLOC-PATH-HELP: Emitting help information for ocloc
// CHK-OCLOC-PATH-HELP: "/my/ocloc/dir{{[/\\]+}}ocloc" "--help"

/// Check that --ocloc-path= does not warn as unused when no AOT compilation
/// for Intel GPU is being performed.
// RUN: %clang -### -fsycl -fsycl-targets=spir64 --ocloc-path=/my/ocloc/dir \
// RUN: --sysroot=%S/Inputs/SYCL %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHK-OCLOC-PATH-UNUSED %s
// CHK-OCLOC-PATH-UNUSED-NOT: warning: argument unused during compilation
13 changes: 13 additions & 0 deletions clang/test/OffloadTools/clang-sycl-linker/basic.ll
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,19 @@
; AOT-INTEL-GPU-NEXT: sycl-bundle: image kind: o, triple: spirv64, arch: bmg_g21
; AOT-INTEL-GPU-NOT: {{.+}}
;
; Test that --ocloc-path= provides the location of the ocloc tool.
; RUN: clang-sycl-linker --dry-run -v --module-split-mode=link_unit -arch=bmg_g21 %t/input1.bc %t/input2.bc -o %t/aot-gpu.out 2>&1 \
; RUN: --ocloc-path=/my/ocloc/dir \
; RUN: | FileCheck %s --check-prefix=AOT-OCLOC-PATH
; AOT-OCLOC-PATH: "/my/ocloc/dir{{[/\\]+}}ocloc" {{.*}}-device bmg_g21
;
Comment thread
mdtoguchi marked this conversation as resolved.
; Test the diagnostic emitted when ocloc cannot be found in the given
; directory.
; RUN: not clang-sycl-linker -v --module-split-mode=link_unit -arch=bmg_g21 %t/input1.bc %t/input2.bc -o %t/aot-gpu.out 2>&1 \
; RUN: --ocloc-path=%t/no-ocloc-here \
; RUN: | FileCheck %s --check-prefix=AOT-OCLOC-PATH-ERR
; AOT-OCLOC-PATH-ERR: unable to find 'ocloc' in '{{.*}}no-ocloc-here'
;
; Test AOT compilation for an Intel CPU.
; Test that IMG_Object image kind is set for AOT compilation (Intel CPU).
; RUN: clang-sycl-linker --dry-run -v --module-split-mode=link_unit -arch=graniterapids %t/input1.bc %t/input2.bc -o %t/aot-cpu.out 2>&1 \
Expand Down
22 changes: 20 additions & 2 deletions clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,25 @@ Expected<std::string> findProgram(StringRef Name, ArrayRef<StringRef> Paths) {
return *Path;
}

/// Locate the 'ocloc' tool used for Intel GPU AOT compilation.
Expected<std::string> findOcloc(const ArgList &Args) {
Comment thread
YuriPlyakhin marked this conversation as resolved.
if (Arg *A = Args.getLastArg(OPT_ocloc_path_EQ)) {
StringRef Dir = A->getValue();
// Only look in the given directory. The tool name is resolved by
// findProgramByName, which takes care of any platform specific executable
// extension.
if (ErrorOr<std::string> Path = sys::findProgramByName("ocloc", {Dir}))
return *Path;
if (DryRun) {
SmallString<128> OclocPath(Dir);
sys::path::append(OclocPath, "ocloc");
return std::string(OclocPath);
}
return createStringError("Unable to find 'ocloc' in '" + Dir + "'");
}
return findProgram("ocloc", {getExecutableDir("ocloc")});
}

bool linkerSupportsLTO(const ArgList &Args) {
llvm::Triple Triple(Args.getLastArgValue(OPT_triple_EQ));
return Triple.isNVPTX() || Triple.isAMDGPU() ||
Expand Down Expand Up @@ -1081,8 +1100,7 @@ runAOTCompileIntelGPU(StringRef InputFile, const ArgList &Args,
const llvm::Triple Triple(Args.getLastArgValue(OPT_triple_EQ));
StringRef Arch(Args.getLastArgValue(OPT_arch_EQ));
SmallVector<StringRef, 8> CmdArgs;
Expected<std::string> OclocPath =
findProgram("ocloc", {getExecutableDir("ocloc")});
Expected<std::string> OclocPath = findOcloc(Args);
if (!OclocPath)
return OclocPath.takeError();

Expand Down
4 changes: 4 additions & 0 deletions clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ def linker_path_EQ : Joined<["--"], "linker-path=">,
def cuda_path_EQ : Joined<["--"], "cuda-path=">,
Flags<[WrapperOnlyOption]>, MetaVarName<"<dir>">,
HelpText<"Set the system CUDA path">;
def ocloc_path_EQ : Joined<["--"], "ocloc-path=">,
Comment thread
YuriPlyakhin marked this conversation as resolved.
Flags<[WrapperOnlyOption]>, MetaVarName<"<dir>">,
HelpText<"Path to the ocloc tool, which is used for ahead of time "
"compilation targeting Intel GPUs">;
Comment thread
mdtoguchi marked this conversation as resolved.
def host_triple_EQ : Joined<["--"], "host-triple=">,
Flags<[WrapperOnlyOption]>,
MetaVarName<"<triple>">,
Expand Down
22 changes: 20 additions & 2 deletions clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,25 @@ static Expected<std::string> findProgram(const ArgList &Args, StringRef Name,
return *Path;
}

/// Locate the 'ocloc' tool used for Intel GPU AOT compilation.
static Expected<std::string> findOcloc(const ArgList &Args) {
if (Arg *A = Args.getLastArg(OPT_ocloc_path_EQ)) {
StringRef Dir = A->getValue();
if (DryRun) {
SmallString<128> OclocPath(Dir);
sys::path::append(OclocPath, "ocloc");
return std::string(OclocPath);
}
Comment thread
mdtoguchi marked this conversation as resolved.
// Only look in the given directory. The tool name is resolved by
// findProgramByName, which takes care of any platform specific executable
// extension.
if (ErrorOr<std::string> Path = sys::findProgramByName("ocloc", {Dir}))
return *Path;
return createStringError("unable to find 'ocloc' in '" + Dir + "'");
}
return findProgram(Args, "ocloc", {getMainExecutable("ocloc")});
}

static void printCommands(ArrayRef<StringRef> CmdArgs) {
if (CmdArgs.empty())
return;
Expand Down Expand Up @@ -710,8 +729,7 @@ static Error runAOTCompileIntelCPU(StringRef InputFile, StringRef OutputFile,
static Error runAOTCompileIntelGPU(StringRef InputFile, StringRef OutputFile,
const ArgList &Args) {
SmallVector<StringRef, 8> CmdArgs;
Expected<std::string> OclocPath =
findProgram(Args, "ocloc", {getMainExecutable("ocloc")});
Expected<std::string> OclocPath = findOcloc(Args);
if (!OclocPath)
return OclocPath.takeError();

Expand Down
5 changes: 5 additions & 0 deletions clang/tools/clang-sycl-linker/SYCLLinkOpts.td
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ def ocloc_options_EQ : Joined<["--", "-"], "ocloc-options=">,
Flags<[LinkerOnlyOption]>,
HelpText<"Options passed to ocloc for Intel GPU AOT compilation">;

def ocloc_path_EQ : Joined<["--", "-"], "ocloc-path=">,
Flags<[LinkerOnlyOption]>, MetaVarName<"<dir>">,
HelpText<"Path to the ocloc tool, which is used for ahead of time "
"compilation targeting Intel GPUs">;
Comment thread
mdtoguchi marked this conversation as resolved.

def opencl_aot_options_EQ : Joined<["--", "-"], "opencl-aot-options=">,
Flags<[LinkerOnlyOption]>,
HelpText<"Options passed to opencl-aot for Intel CPU AOT compilation">;
Expand Down
Loading