Please use GitHub pull requests for new patches. Avoid migrating existing patches. Phabricator shutdown timeline
Changeset View
Changeset View
Standalone View
Standalone View
clang/lib/Driver/ToolChains/HIPAMD.cpp
- This file was moved from clang/lib/Driver/ToolChains/HIP.cpp.
//===--- HIP.cpp - HIP Tool and ToolChain Implementations -------*- C++ -*-===// | //===--- HIPAMD.cpp - HIP Tool and ToolChain Implementations ----*- C++ -*-===// | ||||
// | // | ||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||||
// See https://llvm.org/LICENSE.txt for license information. | // See https://llvm.org/LICENSE.txt for license information. | ||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||||
// | // | ||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||
#include "HIP.h" | #include "HIPAMD.h" | ||||
#include "AMDGPU.h" | #include "AMDGPU.h" | ||||
#include "CommonArgs.h" | #include "CommonArgs.h" | ||||
#include "HIPUtility.h" | |||||
#include "clang/Basic/Cuda.h" | #include "clang/Basic/Cuda.h" | ||||
#include "clang/Basic/TargetID.h" | #include "clang/Basic/TargetID.h" | ||||
#include "clang/Driver/Compilation.h" | #include "clang/Driver/Compilation.h" | ||||
#include "clang/Driver/Driver.h" | #include "clang/Driver/Driver.h" | ||||
#include "clang/Driver/DriverDiagnostic.h" | #include "clang/Driver/DriverDiagnostic.h" | ||||
#include "clang/Driver/InputInfo.h" | #include "clang/Driver/InputInfo.h" | ||||
#include "clang/Driver/Options.h" | #include "clang/Driver/Options.h" | ||||
#include "clang/Driver/SanitizerArgs.h" | #include "clang/Driver/SanitizerArgs.h" | ||||
▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | Diags.Report( | ||||
clang::diag::warn_drv_unsupported_option_for_offload_arch_req_feature) | clang::diag::warn_drv_unsupported_option_for_offload_arch_req_feature) | ||||
<< A->getAsString(DriverArgs) << TargetID << "xnack+"; | << A->getAsString(DriverArgs) << TargetID << "xnack+"; | ||||
return true; | return true; | ||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
void AMDGCN::Linker::constructLldCommand(Compilation &C, const JobAction &JA, | void AMDGCN::Linker::constructLldCommand(Compilation &C, const JobAction &JA, | ||||
const InputInfoList &Inputs, | const InputInfoList &Inputs, | ||||
const InputInfo &Output, | const InputInfo &Output, | ||||
const llvm::opt::ArgList &Args) const { | const llvm::opt::ArgList &Args) const { | ||||
// Construct lld command. | // Construct lld command. | ||||
// The output from ld.lld is an HSA code object file. | // The output from ld.lld is an HSA code object file. | ||||
ArgStringList LldArgs{"-flavor", "gnu", "--no-undefined", "-shared", | ArgStringList LldArgs{"-flavor", "gnu", "--no-undefined", "-shared", | ||||
"-plugin-opt=-amdgpu-internalize-symbols"}; | "-plugin-opt=-amdgpu-internalize-symbols"}; | ||||
auto &TC = getToolChain(); | auto &TC = getToolChain(); | ||||
auto &D = TC.getDriver(); | auto &D = TC.getDriver(); | ||||
assert(!Inputs.empty() && "Must have at least one input."); | assert(!Inputs.empty() && "Must have at least one input."); | ||||
Show All 34 Lines | void AMDGCN::Linker::constructLldCommand(Compilation &C, const JobAction &JA, | ||||
for (auto Input : Inputs) | for (auto Input : Inputs) | ||||
LldArgs.push_back(Input.getFilename()); | LldArgs.push_back(Input.getFilename()); | ||||
const char *Lld = Args.MakeArgString(getToolChain().GetProgramPath("lld")); | const char *Lld = Args.MakeArgString(getToolChain().GetProgramPath("lld")); | ||||
C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(), | C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(), | ||||
Lld, LldArgs, Inputs, Output)); | Lld, LldArgs, Inputs, Output)); | ||||
} | } | ||||
// Construct a clang-offload-bundler command to bundle code objects for | |||||
// different GPU's into a HIP fat binary. | |||||
void AMDGCN::constructHIPFatbinCommand(Compilation &C, const JobAction &JA, | |||||
StringRef OutputFileName, const InputInfoList &Inputs, | |||||
const llvm::opt::ArgList &Args, const Tool& T) { | |||||
// Construct clang-offload-bundler command to bundle object files for | |||||
// for different GPU archs. | |||||
ArgStringList BundlerArgs; | |||||
BundlerArgs.push_back(Args.MakeArgString("-type=o")); | |||||
BundlerArgs.push_back( | |||||
Args.MakeArgString("-bundle-align=" + Twine(HIPCodeObjectAlign))); | |||||
// ToDo: Remove the dummy host binary entry which is required by | |||||
// clang-offload-bundler. | |||||
std::string BundlerTargetArg = "-targets=host-x86_64-unknown-linux"; | |||||
std::string BundlerInputArg = "-inputs=" NULL_FILE; | |||||
// For code object version 2 and 3, the offload kind in bundle ID is 'hip' | |||||
// for backward compatibility. For code object version 4 and greater, the | |||||
// offload kind in bundle ID is 'hipv4'. | |||||
std::string OffloadKind = "hip"; | |||||
if (getAMDGPUCodeObjectVersion(C.getDriver(), Args) >= 4) | |||||
OffloadKind = OffloadKind + "v4"; | |||||
for (const auto &II : Inputs) { | |||||
const auto* A = II.getAction(); | |||||
BundlerTargetArg = BundlerTargetArg + "," + OffloadKind + | |||||
"-amdgcn-amd-amdhsa--" + | |||||
StringRef(A->getOffloadingArch()).str(); | |||||
BundlerInputArg = BundlerInputArg + "," + II.getFilename(); | |||||
} | |||||
BundlerArgs.push_back(Args.MakeArgString(BundlerTargetArg)); | |||||
BundlerArgs.push_back(Args.MakeArgString(BundlerInputArg)); | |||||
std::string Output = std::string(OutputFileName); | |||||
auto BundlerOutputArg = | |||||
Args.MakeArgString(std::string("-outputs=").append(Output)); | |||||
BundlerArgs.push_back(BundlerOutputArg); | |||||
const char *Bundler = Args.MakeArgString( | |||||
T.getToolChain().GetProgramPath("clang-offload-bundler")); | |||||
C.addCommand(std::make_unique<Command>( | |||||
JA, T, ResponseFileSupport::None(), Bundler, BundlerArgs, Inputs, | |||||
InputInfo(&JA, Args.MakeArgString(Output)))); | |||||
} | |||||
/// Add Generated HIP Object File which has device images embedded into the | |||||
/// host to the argument list for linking. Using MC directives, embed the | |||||
/// device code and also define symbols required by the code generation so that | |||||
/// the image can be retrieved at runtime. | |||||
void AMDGCN::Linker::constructGenerateObjFileFromHIPFatBinary( | |||||
Compilation &C, const InputInfo &Output, | |||||
const InputInfoList &Inputs, const ArgList &Args, | |||||
const JobAction &JA) const { | |||||
const ToolChain &TC = getToolChain(); | |||||
std::string Name = std::string(llvm::sys::path::stem(Output.getFilename())); | |||||
// Create Temp Object File Generator, | |||||
// Offload Bundled file and Bundled Object file. | |||||
// Keep them if save-temps is enabled. | |||||
const char *McinFile; | |||||
const char *BundleFile; | |||||
if (C.getDriver().isSaveTempsEnabled()) { | |||||
McinFile = C.getArgs().MakeArgString(Name + ".mcin"); | |||||
BundleFile = C.getArgs().MakeArgString(Name + ".hipfb"); | |||||
} else { | |||||
auto TmpNameMcin = C.getDriver().GetTemporaryPath(Name, "mcin"); | |||||
McinFile = C.addTempFile(C.getArgs().MakeArgString(TmpNameMcin)); | |||||
auto TmpNameFb = C.getDriver().GetTemporaryPath(Name, "hipfb"); | |||||
BundleFile = C.addTempFile(C.getArgs().MakeArgString(TmpNameFb)); | |||||
} | |||||
constructHIPFatbinCommand(C, JA, BundleFile, Inputs, Args, *this); | |||||
// Create a buffer to write the contents of the temp obj generator. | |||||
std::string ObjBuffer; | |||||
llvm::raw_string_ostream ObjStream(ObjBuffer); | |||||
auto HostTriple = | |||||
C.getSingleOffloadToolChain<Action::OFK_Host>()->getTriple(); | |||||
// Add MC directives to embed target binaries. We ensure that each | |||||
// section and image is 16-byte aligned. This is not mandatory, but | |||||
// increases the likelihood of data to be aligned with a cache block | |||||
// in several main host machines. | |||||
ObjStream << "# HIP Object Generator\n"; | |||||
ObjStream << "# *** Automatically generated by Clang ***\n"; | |||||
if (HostTriple.isWindowsMSVCEnvironment()) { | |||||
ObjStream << " .section .hip_fatbin, \"dw\"\n"; | |||||
} else { | |||||
ObjStream << " .protected __hip_fatbin\n"; | |||||
ObjStream << " .type __hip_fatbin,@object\n"; | |||||
ObjStream << " .section .hip_fatbin,\"a\",@progbits\n"; | |||||
} | |||||
ObjStream << " .globl __hip_fatbin\n"; | |||||
ObjStream << " .p2align " << llvm::Log2(llvm::Align(HIPCodeObjectAlign)) | |||||
<< "\n"; | |||||
ObjStream << "__hip_fatbin:\n"; | |||||
ObjStream << " .incbin "; | |||||
llvm::sys::printArg(ObjStream, BundleFile, /*Quote=*/true); | |||||
ObjStream << "\n"; | |||||
ObjStream.flush(); | |||||
// Dump the contents of the temp object file gen if the user requested that. | |||||
// We support this option to enable testing of behavior with -###. | |||||
if (C.getArgs().hasArg(options::OPT_fhip_dump_offload_linker_script)) | |||||
llvm::errs() << ObjBuffer; | |||||
// Open script file and write the contents. | |||||
std::error_code EC; | |||||
llvm::raw_fd_ostream Objf(McinFile, EC, llvm::sys::fs::OF_None); | |||||
if (EC) { | |||||
C.getDriver().Diag(clang::diag::err_unable_to_make_temp) << EC.message(); | |||||
return; | |||||
} | |||||
Objf << ObjBuffer; | |||||
ArgStringList McArgs{"-triple", Args.MakeArgString(HostTriple.normalize()), | |||||
"-o", Output.getFilename(), | |||||
McinFile, "--filetype=obj"}; | |||||
const char *Mc = Args.MakeArgString(TC.GetProgramPath("llvm-mc")); | |||||
C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(), | |||||
Mc, McArgs, Inputs, Output)); | |||||
} | |||||
// For amdgcn the inputs of the linker job are device bitcode and output is | // For amdgcn the inputs of the linker job are device bitcode and output is | ||||
// object file. It calls llvm-link, opt, llc, then lld steps. | // object file. It calls llvm-link, opt, llc, then lld steps. | ||||
void AMDGCN::Linker::ConstructJob(Compilation &C, const JobAction &JA, | void AMDGCN::Linker::ConstructJob(Compilation &C, const JobAction &JA, | ||||
const InputInfo &Output, | const InputInfo &Output, | ||||
const InputInfoList &Inputs, | const InputInfoList &Inputs, | ||||
const ArgList &Args, | const ArgList &Args, | ||||
const char *LinkingOutput) const { | const char *LinkingOutput) const { | ||||
if (Inputs.size() > 0 && | if (Inputs.size() > 0 && | ||||
Inputs[0].getType() == types::TY_Image && | Inputs[0].getType() == types::TY_Image && | ||||
JA.getType() == types::TY_Object) | JA.getType() == types::TY_Object) | ||||
return constructGenerateObjFileFromHIPFatBinary(C, Output, Inputs, Args, JA); | return HIP::constructGenerateObjFileFromHIPFatBinary(C, Output, Inputs, | ||||
Args, JA, *this); | |||||
if (JA.getType() == types::TY_HIP_FATBIN) | if (JA.getType() == types::TY_HIP_FATBIN) | ||||
return constructHIPFatbinCommand(C, JA, Output.getFilename(), Inputs, Args, *this); | return HIP::constructHIPFatbinCommand(C, JA, Output.getFilename(), Inputs, | ||||
Args, *this); | |||||
return constructLldCommand(C, JA, Inputs, Output, Args); | return constructLldCommand(C, JA, Inputs, Output, Args); | ||||
} | } | ||||
HIPToolChain::HIPToolChain(const Driver &D, const llvm::Triple &Triple, | HIPAMDToolChain::HIPAMDToolChain(const Driver &D, const llvm::Triple &Triple, | ||||
const ToolChain &HostTC, const ArgList &Args) | const ToolChain &HostTC, const ArgList &Args) | ||||
: ROCMToolChain(D, Triple, Args), HostTC(HostTC) { | : ROCMToolChain(D, Triple, Args), HostTC(HostTC) { | ||||
// Lookup binaries into the driver directory, this is used to | // Lookup binaries into the driver directory, this is used to | ||||
// discover the clang-offload-bundler executable. | // discover the clang-offload-bundler executable. | ||||
getProgramPaths().push_back(getDriver().Dir); | getProgramPaths().push_back(getDriver().Dir); | ||||
// Diagnose unsupported sanitizer options only once. | // Diagnose unsupported sanitizer options only once. | ||||
for (auto A : Args.filtered(options::OPT_fsanitize_EQ)) { | for (auto A : Args.filtered(options::OPT_fsanitize_EQ)) { | ||||
SanitizerMask K = parseSanitizerValue(A->getValue(), /*AllowGroups=*/false); | SanitizerMask K = parseSanitizerValue(A->getValue(), /*AllowGroups=*/false); | ||||
if (K != SanitizerKind::Address) | if (K != SanitizerKind::Address) | ||||
D.getDiags().Report(clang::diag::warn_drv_unsupported_option_for_target) | D.getDiags().Report(clang::diag::warn_drv_unsupported_option_for_target) | ||||
<< A->getAsString(Args) << getTriple().str(); | << A->getAsString(Args) << getTriple().str(); | ||||
} | } | ||||
} | } | ||||
void HIPToolChain::addClangTargetOptions( | void HIPAMDToolChain::addClangTargetOptions( | ||||
const llvm::opt::ArgList &DriverArgs, | const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, | ||||
llvm::opt::ArgStringList &CC1Args, | |||||
Action::OffloadKind DeviceOffloadingKind) const { | Action::OffloadKind DeviceOffloadingKind) const { | ||||
HostTC.addClangTargetOptions(DriverArgs, CC1Args, DeviceOffloadingKind); | HostTC.addClangTargetOptions(DriverArgs, CC1Args, DeviceOffloadingKind); | ||||
assert(DeviceOffloadingKind == Action::OFK_HIP && | assert(DeviceOffloadingKind == Action::OFK_HIP && | ||||
"Only HIP offloading kinds are supported for GPUs."); | "Only HIP offloading kinds are supported for GPUs."); | ||||
CC1Args.push_back("-fcuda-is-device"); | CC1Args.push_back("-fcuda-is-device"); | ||||
Show All 26 Lines | void HIPAMDToolChain::addClangTargetOptions( | ||||
llvm::for_each(getHIPDeviceLibs(DriverArgs), [&](auto BCFile) { | llvm::for_each(getHIPDeviceLibs(DriverArgs), [&](auto BCFile) { | ||||
CC1Args.push_back(BCFile.ShouldInternalize ? "-mlink-builtin-bitcode" | CC1Args.push_back(BCFile.ShouldInternalize ? "-mlink-builtin-bitcode" | ||||
: "-mlink-bitcode-file"); | : "-mlink-bitcode-file"); | ||||
CC1Args.push_back(DriverArgs.MakeArgString(BCFile.Path)); | CC1Args.push_back(DriverArgs.MakeArgString(BCFile.Path)); | ||||
}); | }); | ||||
} | } | ||||
llvm::opt::DerivedArgList * | llvm::opt::DerivedArgList * | ||||
HIPToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args, | HIPAMDToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args, | ||||
StringRef BoundArch, | StringRef BoundArch, | ||||
Action::OffloadKind DeviceOffloadKind) const { | Action::OffloadKind DeviceOffloadKind) const { | ||||
DerivedArgList *DAL = | DerivedArgList *DAL = | ||||
HostTC.TranslateArgs(Args, BoundArch, DeviceOffloadKind); | HostTC.TranslateArgs(Args, BoundArch, DeviceOffloadKind); | ||||
if (!DAL) | if (!DAL) | ||||
DAL = new DerivedArgList(Args.getBaseArgs()); | DAL = new DerivedArgList(Args.getBaseArgs()); | ||||
const OptTable &Opts = getDriver().getOpts(); | const OptTable &Opts = getDriver().getOpts(); | ||||
for (Arg *A : Args) { | for (Arg *A : Args) { | ||||
if (!shouldSkipArgument(A) && | if (!shouldSkipArgument(A) && | ||||
!shouldSkipSanitizeOption(*this, Args, BoundArch, A)) | !shouldSkipSanitizeOption(*this, Args, BoundArch, A)) | ||||
DAL->append(A); | DAL->append(A); | ||||
} | } | ||||
if (!BoundArch.empty()) { | if (!BoundArch.empty()) { | ||||
DAL->eraseArg(options::OPT_mcpu_EQ); | DAL->eraseArg(options::OPT_mcpu_EQ); | ||||
DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_mcpu_EQ), BoundArch); | DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_mcpu_EQ), BoundArch); | ||||
checkTargetID(*DAL); | checkTargetID(*DAL); | ||||
} | } | ||||
return DAL; | return DAL; | ||||
} | } | ||||
Tool *HIPToolChain::buildLinker() const { | Tool *HIPAMDToolChain::buildLinker() const { | ||||
assert(getTriple().getArch() == llvm::Triple::amdgcn); | assert(getTriple().getArch() == llvm::Triple::amdgcn); | ||||
return new tools::AMDGCN::Linker(*this); | return new tools::AMDGCN::Linker(*this); | ||||
} | } | ||||
void HIPToolChain::addClangWarningOptions(ArgStringList &CC1Args) const { | void HIPAMDToolChain::addClangWarningOptions(ArgStringList &CC1Args) const { | ||||
HostTC.addClangWarningOptions(CC1Args); | HostTC.addClangWarningOptions(CC1Args); | ||||
} | } | ||||
ToolChain::CXXStdlibType | ToolChain::CXXStdlibType | ||||
HIPToolChain::GetCXXStdlibType(const ArgList &Args) const { | HIPAMDToolChain::GetCXXStdlibType(const ArgList &Args) const { | ||||
return HostTC.GetCXXStdlibType(Args); | return HostTC.GetCXXStdlibType(Args); | ||||
} | } | ||||
void HIPToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, | void HIPAMDToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, | ||||
ArgStringList &CC1Args) const { | ArgStringList &CC1Args) const { | ||||
HostTC.AddClangSystemIncludeArgs(DriverArgs, CC1Args); | HostTC.AddClangSystemIncludeArgs(DriverArgs, CC1Args); | ||||
} | } | ||||
void HIPToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &Args, | void HIPAMDToolChain::AddClangCXXStdlibIncludeArgs( | ||||
ArgStringList &CC1Args) const { | const ArgList &Args, ArgStringList &CC1Args) const { | ||||
HostTC.AddClangCXXStdlibIncludeArgs(Args, CC1Args); | HostTC.AddClangCXXStdlibIncludeArgs(Args, CC1Args); | ||||
} | } | ||||
void HIPToolChain::AddIAMCUIncludeArgs(const ArgList &Args, | void HIPAMDToolChain::AddIAMCUIncludeArgs(const ArgList &Args, | ||||
ArgStringList &CC1Args) const { | ArgStringList &CC1Args) const { | ||||
HostTC.AddIAMCUIncludeArgs(Args, CC1Args); | HostTC.AddIAMCUIncludeArgs(Args, CC1Args); | ||||
} | } | ||||
void HIPToolChain::AddHIPIncludeArgs(const ArgList &DriverArgs, | void HIPAMDToolChain::AddHIPIncludeArgs(const ArgList &DriverArgs, | ||||
ArgStringList &CC1Args) const { | ArgStringList &CC1Args) const { | ||||
RocmInstallation.AddHIPIncludeArgs(DriverArgs, CC1Args); | RocmInstallation.AddHIPIncludeArgs(DriverArgs, CC1Args); | ||||
} | } | ||||
SanitizerMask HIPToolChain::getSupportedSanitizers() const { | SanitizerMask HIPAMDToolChain::getSupportedSanitizers() const { | ||||
// The HIPToolChain only supports sanitizers in the sense that it allows | // The HIPAMDToolChain only supports sanitizers in the sense that it allows | ||||
// sanitizer arguments on the command line if they are supported by the host | // sanitizer arguments on the command line if they are supported by the host | ||||
// toolchain. The HIPToolChain will actually ignore any command line | // toolchain. The HIPAMDToolChain will actually ignore any command line | ||||
// arguments for any of these "supported" sanitizers. That means that no | // arguments for any of these "supported" sanitizers. That means that no | ||||
// sanitization of device code is actually supported at this time. | // sanitization of device code is actually supported at this time. | ||||
// | // | ||||
// This behavior is necessary because the host and device toolchains | // This behavior is necessary because the host and device toolchains | ||||
// invocations often share the command line, so the device toolchain must | // invocations often share the command line, so the device toolchain must | ||||
// tolerate flags meant only for the host toolchain. | // tolerate flags meant only for the host toolchain. | ||||
return HostTC.getSupportedSanitizers(); | return HostTC.getSupportedSanitizers(); | ||||
} | } | ||||
VersionTuple HIPToolChain::computeMSVCVersion(const Driver *D, | VersionTuple HIPAMDToolChain::computeMSVCVersion(const Driver *D, | ||||
const ArgList &Args) const { | const ArgList &Args) const { | ||||
return HostTC.computeMSVCVersion(D, Args); | return HostTC.computeMSVCVersion(D, Args); | ||||
} | } | ||||
llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12> | llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12> | ||||
HIPToolChain::getHIPDeviceLibs(const llvm::opt::ArgList &DriverArgs) const { | HIPAMDToolChain::getHIPDeviceLibs(const llvm::opt::ArgList &DriverArgs) const { | ||||
llvm::SmallVector<BitCodeLibraryInfo, 12> BCLibs; | llvm::SmallVector<BitCodeLibraryInfo, 12> BCLibs; | ||||
if (DriverArgs.hasArg(options::OPT_nogpulib)) | if (DriverArgs.hasArg(options::OPT_nogpulib)) | ||||
return {}; | return {}; | ||||
ArgStringList LibraryPaths; | ArgStringList LibraryPaths; | ||||
// Find in --hip-device-lib-path and HIP_LIBRARY_PATH. | // Find in --hip-device-lib-path and HIP_LIBRARY_PATH. | ||||
for (auto Path : RocmInstallation.getRocmDeviceLibPathArg()) | for (auto Path : RocmInstallation.getRocmDeviceLibPathArg()) | ||||
LibraryPaths.push_back(DriverArgs.MakeArgString(Path)); | LibraryPaths.push_back(DriverArgs.MakeArgString(Path)); | ||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | if (llvm::sys::fs::exists(InstLib)) | ||||
BCLibs.push_back(InstLib); | BCLibs.push_back(InstLib); | ||||
else | else | ||||
getDriver().Diag(diag::err_drv_no_such_file) << InstLib; | getDriver().Diag(diag::err_drv_no_such_file) << InstLib; | ||||
} | } | ||||
return BCLibs; | return BCLibs; | ||||
} | } | ||||
void HIPToolChain::checkTargetID(const llvm::opt::ArgList &DriverArgs) const { | void HIPAMDToolChain::checkTargetID( | ||||
const llvm::opt::ArgList &DriverArgs) const { | |||||
auto PTID = getParsedTargetID(DriverArgs); | auto PTID = getParsedTargetID(DriverArgs); | ||||
if (PTID.OptionalTargetID && !PTID.OptionalGPUArch) { | if (PTID.OptionalTargetID && !PTID.OptionalGPUArch) { | ||||
getDriver().Diag(clang::diag::err_drv_bad_target_id) | getDriver().Diag(clang::diag::err_drv_bad_target_id) | ||||
<< PTID.OptionalTargetID.getValue(); | << PTID.OptionalTargetID.getValue(); | ||||
} | } | ||||
return; | return; | ||||
} | } |