Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions clang/docs/ClangLinkerWrapper.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ OPTIONS:
--linker-path=<path> The linker executable to invoke
-L <dir> Add <dir> to the library search path
-l <libname> Search for library <libname>
--ocloc-path=<dir> Path to the ocloc tool used for Intel GPU AOT compilation
--opt-level=<O0, O1, O2, or O3>
Optimization level for LTO
--override-image=<kind=file>
Expand Down
1 change: 1 addition & 0 deletions clang/docs/ClangSYCLLinker.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ OPTIONS:
-u <symbol> Force undefined symbol during linking
--module-split-mode=<mode> Module split mode: 'translation_unit' (default), 'kernel', or 'link_unit'
--ocloc-options=<value> Options passed to ocloc for Intel GPU AOT compilation
--ocloc-path=<dir> Path to the ocloc tool used for Intel GPU AOT compilation
--opencl-aot-options=<value> Options passed to opencl-aot for Intel CPU AOT compilation
-o <path> Path to file to write output
--save-temps Save intermediate results
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/Options/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -8002,6 +8002,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<"<dir>">,
HelpText<"Path to the ocloc tool, which is used for ahead of time "
"compilation targeting Intel GPUs">;
def fsycl_libspirv_path_EQ : Joined<["-"], "fsycl-libspirv-path=">,
HelpText<"Path to libspirv library">;
def fno_sycl_libspirv : Flag<["-"], "fno-sycl-libspirv">,
Expand Down
38 changes: 30 additions & 8 deletions clang/lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,16 @@ InputArgList Driver::ParseArgStrings(ArrayRef<const char *> ArgStrings,
diag::warn_drv_empty_joined_argument,
SourceLocation()) > DiagnosticsEngine::Warning;
}

// An empty --ocloc-path= is rejected here for consistent usage for areas
// that consume it.
if (A->getOption().matches(options::OPT_ocloc_path_EQ) &&
A->containsValue("")) {
Comment thread
mdtoguchi marked this conversation as resolved.
Diag(diag::err_drv_invalid_value) << A->getSpelling() << A->getValue();
ContainsError |= Diags.getDiagnosticLevel(diag::err_drv_invalid_value,
SourceLocation()) >
DiagnosticsEngine::Warning;
}
}

for (const Arg *A : Args.filtered(options::OPT_UNKNOWN)) {
Expand Down Expand Up @@ -2817,6 +2827,10 @@ void Driver::PrintHelp(bool ShowHidden) const {
// Print the help from any of the given tools which are used for AOT
// compilation for SYCL
void Driver::PrintSYCLToolHelp(const Compilation &C) const {
// Do not run any external tools if the command line was already rejected.
if (C.containsError())
return;

SmallVector<std::tuple<llvm::Triple, StringRef, StringRef, StringRef>, 4>
HelpArgs;
// Populate the vector with the tools and help options
Expand All @@ -2841,15 +2855,22 @@ void Driver::PrintSYCLToolHelp(const Compilation &C) const {

// Go through the args and emit the help information for each.
for (auto &HA : HelpArgs) {
llvm::outs() << "Emitting help information for " << std::get<1>(HA) << '\n'
<< "Use triple of '" << std::get<0>(HA).normalize() <<
"' to enable ahead of time compilation\n";
StringRef ToolName = std::get<1>(HA);
llvm::outs() << "Emitting help information for " << ToolName << '\n'
<< "Use triple of '" << std::get<0>(HA).normalize()
<< "' to enable ahead of time compilation\n";
// Flush out the buffer before calling the external tool.
llvm::outs().flush();
std::vector<StringRef> ToolArgs = {std::get<1>(HA), std::get<2>(HA),
std::vector<StringRef> ToolArgs = {ToolName, std::get<2>(HA),
std::get<3>(HA)};
SmallString<128> ExecPath(
C.getDefaultToolChain().GetProgramPath(std::get<1>(HA).data()));
SmallString<128> ExecPath;
// The lookup for ocloc is shared with the AOT compilation step, which
// honors any user provided --ocloc-path=.
if (ToolName == "ocloc")
ExecPath = tools::SYCL::gen::getOclocPath(C, C.getDefaultToolChain(),
C.getArgs());
else
ExecPath = C.getDefaultToolChain().GetProgramPath(ToolName.data());
// do not run the tools with -###.
if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
llvm::errs() << "\"" << ExecPath << "\" \"" << ToolArgs[1] << "\"";
Expand All @@ -2859,12 +2880,13 @@ void Driver::PrintSYCLToolHelp(const Compilation &C) const {
continue;
}
auto ToolBinary = llvm::sys::findProgramByName(ExecPath);
if (ToolBinary.getError()) {
if (ToolBinary.getError() || !llvm::sys::fs::can_execute(*ToolBinary)) {
C.getDriver().Diag(diag::err_drv_command_failure) << ExecPath;
continue;
}
// Run the Tool.
llvm::sys::ExecuteAndWait(ToolBinary.get(), ToolArgs);
if (llvm::sys::ExecuteAndWait(ToolBinary.get(), ToolArgs))
C.getDriver().Diag(diag::err_drv_command_failure) << ExecPath;
}
}

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 @@ -12146,6 +12146,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
19 changes: 15 additions & 4 deletions clang/lib/Driver/ToolChains/SYCL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1044,14 +1044,27 @@ void SYCL::Linker::ConstructJob(Compilation &C, const JobAction &JA,
SpirvInputs);
}

static const char *makeExeName(Compilation &C, StringRef Name) {
static const char *makeExeName(const Compilation &C, StringRef Name) {
llvm::SmallString<8> ExeName(Name);
const ToolChain *HostTC = C.getSingleOffloadToolChain<Action::OFK_Host>();
if (HostTC->getTriple().isWindowsMSVCEnvironment())
ExeName.append(".exe");
return C.getArgs().MakeArgString(ExeName);
}

const char *SYCL::gen::getOclocPath(const 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 @@ -1115,9 +1128,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
7 changes: 7 additions & 0 deletions clang/lib/Driver/ToolChains/SYCL.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,13 @@ 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 and
// for emitting the ocloc help information. 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(const Compilation &C, const ToolChain &TC,
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
15 changes: 15 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,21 @@
// 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.
// 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 that an empty --ocloc-path= is rejected.
// RUN: not clang-linker-wrapper --ocloc-path= --linker-path=/usr/bin/ld -o /dev/null %t1.o --dry-run 2>&1 | FileCheck -check-prefix=CHK-OCLOC-PATH-NOARG %s
// CHK-OCLOC-PATH-NOARG: no directory given for '--ocloc-path='

/// 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
115 changes: 115 additions & 0 deletions clang/test/Driver/sycl-ocloc-path.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
///
/// 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{{(\.exe)?}}" "--help"

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

/// Check the diagnostic emitted when the given directory does not contain a
/// usable ocloc. Without -### the tool is actually launched, so the composed
/// path is expected to be diagnosed instead of being silently ignored.
// RUN: rm -rf %t.empty.dir && mkdir -p %t.empty.dir
// RUN: not %clang -fsycl -fsycl-help=gen --ocloc-path=%t.empty.dir %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHK-OCLOC-PATH-HELP-ERR %s
// CHK-OCLOC-PATH-HELP-ERR: error: unable to execute command: {{.*}}ocloc

/// Check that an empty --ocloc-path= is rejected instead of falling back to
/// another ocloc.
// RUN: not %clang -### -fsycl --no-offload-new-driver \
// RUN: -fsycl-targets=spir64_gen --ocloc-path= %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHK-OCLOC-PATH-EMPTY %s
// RUN: not %clang -fsycl -fsycl-help=gen --ocloc-path= %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHK-OCLOC-PATH-EMPTY %s
// CHK-OCLOC-PATH-EMPTY: error: invalid value '' in '--ocloc-path='
// CHK-OCLOC-PATH-EMPTY-NOT: Emitting help information

/// 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

/// Check that a --ocloc-path= directory whose name contains spaces is
/// composed and quoted correctly.
// RUN: %clang -### -fsycl --no-offload-new-driver -fsycl-targets=spir64_gen \
// RUN: --ocloc-path="/my/ocloc dir/with spaces" %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHK-OCLOC-PATH-SPACES-OLD %s
// CHK-OCLOC-PATH-SPACES-OLD: "/my/ocloc dir/with spaces{{[/\\]+}}ocloc{{(\.exe)?}}" "-output"
// RUN: %clang -### -fsycl --offload-new-driver -fsycl-targets=spir64_gen \
// RUN: --sysroot=%S/Inputs/SYCL --ocloc-path="/my/ocloc dir/with spaces" %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHK-OCLOC-PATH-SPACES-NEW %s
// CHK-OCLOC-PATH-SPACES-NEW: clang-linker-wrapper{{.*}} "--ocloc-path=/my/ocloc dir/with spaces"
// RUN: %clangxx -### --target=spirv64 --sycl-link \
// RUN: --ocloc-path="/my/ocloc dir/with spaces" %t.bc 2>&1 \
// RUN: | FileCheck -check-prefix=CHK-OCLOC-PATH-SPACES-SYCL-LINK %s
// CHK-OCLOC-PATH-SPACES-SYCL-LINK: clang-sycl-linker{{.*}} "--ocloc-path=/my/ocloc dir/with spaces"

/// Check that a real --ocloc-path= directory containing spaces is actually
/// located and used to launch the tool.
// RUN: rm -rf "%t.dir with spaces" && mkdir -p "%t.dir with spaces"
// RUN: not %clang -fsycl -fsycl-help=gen \
// RUN: --ocloc-path="%t.dir with spaces" %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHK-OCLOC-PATH-SPACES-ERR %s
// CHK-OCLOC-PATH-SPACES-ERR: error: unable to execute command: {{.*}}dir with spaces{{[/\\]+}}ocloc
16 changes: 16 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,22 @@
; 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 --ocloc-path=/my/ocloc/dir 2>&1 \
; RUN: | FileCheck %s --check-prefix=AOT-OCLOC-PATH
; AOT-OCLOC-PATH: "/my/ocloc/dir{{[/\\]+}}ocloc" {{.*}}-device bmg_g21
;
; 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 --ocloc-path=%t/no-ocloc-here 2>&1 \
; RUN: | FileCheck %s --check-prefix=AOT-OCLOC-PATH-ERR
; AOT-OCLOC-PATH-ERR: unable to find 'ocloc' in '{{.*}}no-ocloc-here'
;
; Test that an empty --ocloc-path= is rejected.
; RUN: not clang-sycl-linker --dry-run -v -arch=bmg_g21 %t/input1.bc --ocloc-path= -o %t/aot-gpu.out 2>&1 \
; RUN: | FileCheck %s --check-prefix=AOT-OCLOC-PATH-NOARG
; AOT-OCLOC-PATH-NOARG: no directory given for '--ocloc-path='

; Test that all --ocloc-options are passed to ocloc, even if they contain spaces or quotes.
; RUN: clang-sycl-linker --dry-run -v --module-split-mode=link_unit -arch=bmg_g21 %t/input1.bc -o %t/aot-gpu.out 2>&1 \
; RUN: --ocloc-options="-a -b" --ocloc-options=-c --ocloc-options="d" --ocloc-options='"-e -f"' \
Expand Down
27 changes: 24 additions & 3 deletions clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -334,10 +334,32 @@ Expected<std::string> findProgram(StringRef Name, ArrayRef<StringRef> Paths) {
return Name.str();
if (!Path)
return createStringError(Path.getError(),
"Unable to find '" + Name + "' in path");
"unable to find '" + Name + "' in path");
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();
if (Dir.empty())
return createStringError("no directory given for '" + A->getSpelling() +
"'");
if (DryRun) {
SmallString<128> OclocPath(Dir);
sys::path::append(OclocPath, "ocloc");
return std::string(OclocPath);
}
// 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("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 @@ -1082,8 +1104,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
Loading
Loading