aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Driver
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Driver')
-rw-r--r--clang/lib/Driver/OffloadBundler.cpp40
-rw-r--r--clang/lib/Driver/ToolChain.cpp23
-rw-r--r--clang/lib/Driver/ToolChains/Arch/ARM.cpp24
-rw-r--r--clang/lib/Driver/ToolChains/CommonArgs.cpp37
-rw-r--r--clang/lib/Driver/ToolChains/Cuda.cpp43
-rw-r--r--clang/lib/Driver/ToolChains/HIPUtility.cpp258
-rw-r--r--clang/lib/Driver/ToolChains/RISCVToolchain.cpp5
-rw-r--r--clang/lib/Driver/ToolChains/RISCVToolchain.h2
8 files changed, 379 insertions, 53 deletions
diff --git a/clang/lib/Driver/OffloadBundler.cpp b/clang/lib/Driver/OffloadBundler.cpp
index b1091ac..99a34d2 100644
--- a/clang/lib/Driver/OffloadBundler.cpp
+++ b/clang/lib/Driver/OffloadBundler.cpp
@@ -588,8 +588,15 @@ public:
StringRef Content = *ContentOrErr;
// Copy fat object contents to the output when extracting host bundle.
- if (Content.size() == 1u && Content.front() == 0)
- Content = StringRef(Input.getBufferStart(), Input.getBufferSize());
+ std::string ModifiedContent;
+ if (Content.size() == 1u && Content.front() == 0) {
+ auto HostBundleOrErr = getHostBundle();
+ if (!HostBundleOrErr)
+ return HostBundleOrErr.takeError();
+
+ ModifiedContent = std::move(*HostBundleOrErr);
+ Content = ModifiedContent;
+ }
OS.write(Content.data(), Content.size());
return Error::success();
@@ -692,6 +699,35 @@ private:
}
return Error::success();
}
+
+ Expected<std::string> getHostBundle() {
+ TempFileHandlerRAII TempFiles;
+
+ auto ModifiedObjPathOrErr = TempFiles.Create(std::nullopt);
+ if (!ModifiedObjPathOrErr)
+ return ModifiedObjPathOrErr.takeError();
+ StringRef ModifiedObjPath = *ModifiedObjPathOrErr;
+
+ BumpPtrAllocator Alloc;
+ StringSaver SS{Alloc};
+ SmallVector<StringRef, 16> ObjcopyArgs{"llvm-objcopy"};
+
+ ObjcopyArgs.push_back("--regex");
+ ObjcopyArgs.push_back("--remove-section=__CLANG_OFFLOAD_BUNDLE__.*");
+ ObjcopyArgs.push_back("--");
+ ObjcopyArgs.push_back(BundlerConfig.InputFileNames.front());
+ ObjcopyArgs.push_back(ModifiedObjPath);
+
+ if (Error Err = executeObjcopy(BundlerConfig.ObjcopyPath, ObjcopyArgs))
+ return std::move(Err);
+
+ auto BufOrErr = MemoryBuffer::getFile(ModifiedObjPath);
+ if (!BufOrErr)
+ return createStringError(BufOrErr.getError(),
+ "Failed to read back the modified object file");
+
+ return BufOrErr->get()->getBuffer().str();
+ }
};
/// Handler for text files. The bundled file will have the following format.
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 3880305..f8c13c8 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -77,10 +77,19 @@ static ToolChain::RTTIMode CalculateRTTIMode(const ArgList &Args,
return NoRTTI ? ToolChain::RM_Disabled : ToolChain::RM_Enabled;
}
+static ToolChain::ExceptionsMode CalculateExceptionsMode(const ArgList &Args) {
+ if (Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions,
+ true)) {
+ return ToolChain::EM_Enabled;
+ }
+ return ToolChain::EM_Disabled;
+}
+
ToolChain::ToolChain(const Driver &D, const llvm::Triple &T,
const ArgList &Args)
: D(D), Triple(T), Args(Args), CachedRTTIArg(GetRTTIArgument(Args)),
- CachedRTTIMode(CalculateRTTIMode(Args, Triple, CachedRTTIArg)) {
+ CachedRTTIMode(CalculateRTTIMode(Args, Triple, CachedRTTIArg)),
+ CachedExceptionsMode(CalculateExceptionsMode(Args)) {
auto addIfExists = [this](path_list &List, const std::string &Path) {
if (getVFS().exists(Path))
List.push_back(Path);
@@ -264,6 +273,18 @@ ToolChain::getMultilibFlags(const llvm::opt::ArgList &Args) const {
break;
}
+ // Include fno-exceptions and fno-rtti
+ // to improve multilib selection
+ if (getRTTIMode() == ToolChain::RTTIMode::RM_Disabled)
+ Result.push_back("-fno-rtti");
+ else
+ Result.push_back("-frtti");
+
+ if (getExceptionsMode() == ToolChain::ExceptionsMode::EM_Disabled)
+ Result.push_back("-fno-exceptions");
+ else
+ Result.push_back("-fexceptions");
+
// Sort and remove duplicates.
std::sort(Result.begin(), Result.end());
Result.erase(std::unique(Result.begin(), Result.end()), Result.end());
diff --git a/clang/lib/Driver/ToolChains/Arch/ARM.cpp b/clang/lib/Driver/ToolChains/Arch/ARM.cpp
index e6ee2f8..ba158b9 100644
--- a/clang/lib/Driver/ToolChains/Arch/ARM.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/ARM.cpp
@@ -890,25 +890,25 @@ fp16_fml_fallthrough:
// SCTLR.U bit, which is architecture-specific. We assume ARMv6
// Darwin and NetBSD targets support unaligned accesses, and others don't.
//
- // ARMv7 always has SCTLR.U set to 1, but it has a new SCTLR.A bit
- // which raises an alignment fault on unaligned accesses. Linux
- // defaults this bit to 0 and handles it as a system-wide (not
- // per-process) setting. It is therefore safe to assume that ARMv7+
- // Linux targets support unaligned accesses. The same goes for NaCl
- // and Windows.
+ // ARMv7 always has SCTLR.U set to 1, but it has a new SCTLR.A bit which
+ // raises an alignment fault on unaligned accesses. Assume ARMv7+ supports
+ // unaligned accesses, except ARMv6-M, and ARMv8-M without the Main
+ // Extension. This aligns with the default behavior of ARM's downstream
+ // versions of GCC and Clang.
//
- // The above behavior is consistent with GCC.
+ // Users can change the default behavior via -m[no-]unaliged-access.
int VersionNum = getARMSubArchVersionNumber(Triple);
if (Triple.isOSDarwin() || Triple.isOSNetBSD()) {
if (VersionNum < 6 ||
Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m)
Features.push_back("+strict-align");
- } else if (Triple.isOSLinux() || Triple.isOSNaCl() ||
- Triple.isOSWindows()) {
- if (VersionNum < 7)
- Features.push_back("+strict-align");
- } else
+ } else if (VersionNum < 7 ||
+ Triple.getSubArch() ==
+ llvm::Triple::SubArchType::ARMSubArch_v6m ||
+ Triple.getSubArch() ==
+ llvm::Triple::SubArchType::ARMSubArch_v8m_baseline) {
Features.push_back("+strict-align");
+ }
}
// llvm does not support reserving registers in general. There is support
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index e5196bd..347b250 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1087,10 +1087,41 @@ static void addOpenMPDeviceLibC(const ToolChain &TC, const ArgList &Args,
"llvm-libc-decls");
bool HasLibC = llvm::sys::fs::exists(LibCDecls) &&
llvm::sys::fs::is_directory(LibCDecls);
- if (Args.hasFlag(options::OPT_gpulibc, options::OPT_nogpulibc, HasLibC)) {
- CmdArgs.push_back("-lcgpu");
- CmdArgs.push_back("-lmgpu");
+ if (!Args.hasFlag(options::OPT_gpulibc, options::OPT_nogpulibc, HasLibC))
+ return;
+
+ // We don't have access to the offloading toolchains here, so determine from
+ // the arguments if we have any active NVPTX or AMDGPU toolchains.
+ llvm::DenseSet<const char *> Libraries;
+ if (const Arg *Targets = Args.getLastArg(options::OPT_fopenmp_targets_EQ)) {
+ if (llvm::any_of(Targets->getValues(),
+ [](auto S) { return llvm::Triple(S).isAMDGPU(); })) {
+ Libraries.insert("-lcgpu-amdgpu");
+ Libraries.insert("-lmgpu-amdgpu");
+ }
+ if (llvm::any_of(Targets->getValues(),
+ [](auto S) { return llvm::Triple(S).isNVPTX(); })) {
+ Libraries.insert("-lcgpu-nvptx");
+ Libraries.insert("-lmgpu-nvptx");
+ }
}
+
+ for (StringRef Arch : Args.getAllArgValues(options::OPT_offload_arch_EQ)) {
+ if (llvm::any_of(llvm::split(Arch, ","), [](StringRef Str) {
+ return IsAMDGpuArch(StringToCudaArch(Str));
+ })) {
+ Libraries.insert("-lcgpu-amdgpu");
+ Libraries.insert("-lmgpu-amdgpu");
+ }
+ if (llvm::any_of(llvm::split(Arch, ","), [](StringRef Str) {
+ return IsNVIDIAGpuArch(StringToCudaArch(Str));
+ })) {
+ Libraries.insert("-lcgpu-nvptx");
+ Libraries.insert("-lmgpu-nvptx");
+ }
+ }
+
+ llvm::append_range(CmdArgs, Libraries);
}
void tools::addOpenMPRuntimeLibraryPath(const ToolChain &TC,
diff --git a/clang/lib/Driver/ToolChains/Cuda.cpp b/clang/lib/Driver/ToolChains/Cuda.cpp
index ed5924c..94d4982 100644
--- a/clang/lib/Driver/ToolChains/Cuda.cpp
+++ b/clang/lib/Driver/ToolChains/Cuda.cpp
@@ -623,35 +623,34 @@ void NVPTX::Linker::ConstructJob(Compilation &C, const JobAction &JA,
continue;
}
- // Currently, we only pass the input files to the linker, we do not pass
- // any libraries that may be valid only for the host.
- if (!II.isFilename())
- continue;
-
// The 'nvlink' application performs RDC-mode linking when given a '.o'
// file and device linking when given a '.cubin' file. We always want to
// perform device linking, so just rename any '.o' files.
// FIXME: This should hopefully be removed if NVIDIA updates their tooling.
- auto InputFile = getToolChain().getInputFilename(II);
- if (llvm::sys::path::extension(InputFile) != ".cubin") {
- // If there are no actions above this one then this is direct input and we
- // can copy it. Otherwise the input is internal so a `.cubin` file should
- // exist.
- if (II.getAction() && II.getAction()->getInputs().size() == 0) {
- const char *CubinF =
- Args.MakeArgString(getToolChain().getDriver().GetTemporaryPath(
- llvm::sys::path::stem(InputFile), "cubin"));
- if (llvm::sys::fs::copy_file(InputFile, C.addTempFile(CubinF)))
- continue;
+ if (II.isFilename()) {
+ auto InputFile = getToolChain().getInputFilename(II);
+ if (llvm::sys::path::extension(InputFile) != ".cubin") {
+ // If there are no actions above this one then this is direct input and
+ // we can copy it. Otherwise the input is internal so a `.cubin` file
+ // should exist.
+ if (II.getAction() && II.getAction()->getInputs().size() == 0) {
+ const char *CubinF =
+ Args.MakeArgString(getToolChain().getDriver().GetTemporaryPath(
+ llvm::sys::path::stem(InputFile), "cubin"));
+ if (llvm::sys::fs::copy_file(InputFile, C.addTempFile(CubinF)))
+ continue;
- CmdArgs.push_back(CubinF);
+ CmdArgs.push_back(CubinF);
+ } else {
+ SmallString<256> Filename(InputFile);
+ llvm::sys::path::replace_extension(Filename, "cubin");
+ CmdArgs.push_back(Args.MakeArgString(Filename));
+ }
} else {
- SmallString<256> Filename(InputFile);
- llvm::sys::path::replace_extension(Filename, "cubin");
- CmdArgs.push_back(Args.MakeArgString(Filename));
+ CmdArgs.push_back(Args.MakeArgString(InputFile));
}
- } else {
- CmdArgs.push_back(Args.MakeArgString(InputFile));
+ } else if (!II.isNothing()) {
+ II.getInputArg().renderAsInput(Args, CmdArgs);
}
}
diff --git a/clang/lib/Driver/ToolChains/HIPUtility.cpp b/clang/lib/Driver/ToolChains/HIPUtility.cpp
index f692458..fcecf2e 100644
--- a/clang/lib/Driver/ToolChains/HIPUtility.cpp
+++ b/clang/lib/Driver/ToolChains/HIPUtility.cpp
@@ -9,13 +9,24 @@
#include "HIPUtility.h"
#include "CommonArgs.h"
#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Options.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Object/Archive.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/MD5.h"
+#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/TargetParser/Triple.h"
+#include <deque>
+#include <set>
+using namespace clang;
using namespace clang::driver;
using namespace clang::driver::tools;
using namespace llvm::opt;
+using llvm::dyn_cast;
#if defined(_WIN32) || defined(_WIN64)
#define NULL_FILE "nul"
@@ -36,6 +47,169 @@ static std::string normalizeForBundler(const llvm::Triple &T,
: T.normalize();
}
+// Collect undefined __hip_fatbin* and __hip_gpubin_handle* symbols from all
+// input object or archive files.
+class HIPUndefinedFatBinSymbols {
+public:
+ HIPUndefinedFatBinSymbols(const Compilation &C)
+ : C(C), DiagID(C.getDriver().getDiags().getCustomDiagID(
+ DiagnosticsEngine::Error,
+ "Error collecting HIP undefined fatbin symbols: %0")),
+ Quiet(C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)),
+ Verbose(C.getArgs().hasArg(options::OPT_v)) {
+ populateSymbols();
+ if (Verbose) {
+ for (auto Name : FatBinSymbols)
+ llvm::errs() << "Found undefined HIP fatbin symbol: " << Name << "\n";
+ for (auto Name : GPUBinHandleSymbols)
+ llvm::errs() << "Found undefined HIP gpubin handle symbol: " << Name
+ << "\n";
+ }
+ }
+
+ const std::set<std::string> &getFatBinSymbols() const {
+ return FatBinSymbols;
+ }
+
+ const std::set<std::string> &getGPUBinHandleSymbols() const {
+ return GPUBinHandleSymbols;
+ }
+
+private:
+ const Compilation &C;
+ unsigned DiagID;
+ bool Quiet;
+ bool Verbose;
+ std::set<std::string> FatBinSymbols;
+ std::set<std::string> GPUBinHandleSymbols;
+ std::set<std::string> DefinedFatBinSymbols;
+ std::set<std::string> DefinedGPUBinHandleSymbols;
+ const std::string FatBinPrefix = "__hip_fatbin";
+ const std::string GPUBinHandlePrefix = "__hip_gpubin_handle";
+
+ void populateSymbols() {
+ std::deque<const Action *> WorkList;
+ std::set<const Action *> Visited;
+
+ for (const auto &Action : C.getActions())
+ WorkList.push_back(Action);
+
+ while (!WorkList.empty()) {
+ const Action *CurrentAction = WorkList.front();
+ WorkList.pop_front();
+
+ if (!CurrentAction || !Visited.insert(CurrentAction).second)
+ continue;
+
+ if (const auto *IA = dyn_cast<InputAction>(CurrentAction)) {
+ std::string ID = IA->getId().str();
+ if (!ID.empty()) {
+ ID = llvm::utohexstr(llvm::MD5Hash(ID), /*LowerCase=*/true);
+ FatBinSymbols.insert(Twine(FatBinPrefix + "_" + ID).str());
+ GPUBinHandleSymbols.insert(
+ Twine(GPUBinHandlePrefix + "_" + ID).str());
+ continue;
+ }
+ if (IA->getInputArg().getNumValues() == 0)
+ continue;
+ const char *Filename = IA->getInputArg().getValue();
+ if (!Filename)
+ continue;
+ auto BufferOrErr = llvm::MemoryBuffer::getFile(Filename);
+ // Input action could be options to linker, therefore, ignore it
+ // if cannot read it. If it turns out to be a file that cannot be read,
+ // the error will be caught by the linker.
+ if (!BufferOrErr)
+ continue;
+
+ processInput(BufferOrErr.get()->getMemBufferRef());
+ } else
+ WorkList.insert(WorkList.end(), CurrentAction->getInputs().begin(),
+ CurrentAction->getInputs().end());
+ }
+ }
+
+ void processInput(const llvm::MemoryBufferRef &Buffer) {
+ // Try processing as object file first.
+ auto ObjFileOrErr = llvm::object::ObjectFile::createObjectFile(Buffer);
+ if (ObjFileOrErr) {
+ processSymbols(**ObjFileOrErr);
+ return;
+ }
+
+ // Then try processing as archive files.
+ llvm::consumeError(ObjFileOrErr.takeError());
+ auto ArchiveOrErr = llvm::object::Archive::create(Buffer);
+ if (ArchiveOrErr) {
+ llvm::Error Err = llvm::Error::success();
+ llvm::object::Archive &Archive = *ArchiveOrErr.get();
+ for (auto &Child : Archive.children(Err)) {
+ auto ChildBufOrErr = Child.getMemoryBufferRef();
+ if (ChildBufOrErr)
+ processInput(*ChildBufOrErr);
+ else
+ errorHandler(ChildBufOrErr.takeError());
+ }
+
+ if (Err)
+ errorHandler(std::move(Err));
+ return;
+ }
+
+ // Ignore other files.
+ llvm::consumeError(ArchiveOrErr.takeError());
+ }
+
+ void processSymbols(const llvm::object::ObjectFile &Obj) {
+ for (const auto &Symbol : Obj.symbols()) {
+ auto FlagOrErr = Symbol.getFlags();
+ if (!FlagOrErr) {
+ errorHandler(FlagOrErr.takeError());
+ continue;
+ }
+
+ auto NameOrErr = Symbol.getName();
+ if (!NameOrErr) {
+ errorHandler(NameOrErr.takeError());
+ continue;
+ }
+ llvm::StringRef Name = *NameOrErr;
+
+ bool isUndefined =
+ FlagOrErr.get() & llvm::object::SymbolRef::SF_Undefined;
+ bool isFatBinSymbol = Name.starts_with(FatBinPrefix);
+ bool isGPUBinHandleSymbol = Name.starts_with(GPUBinHandlePrefix);
+
+ // Handling for defined symbols
+ if (!isUndefined) {
+ if (isFatBinSymbol) {
+ DefinedFatBinSymbols.insert(Name.str());
+ FatBinSymbols.erase(Name.str());
+ } else if (isGPUBinHandleSymbol) {
+ DefinedGPUBinHandleSymbols.insert(Name.str());
+ GPUBinHandleSymbols.erase(Name.str());
+ }
+ continue;
+ }
+
+ // Add undefined symbols if they are not in the defined sets
+ if (isFatBinSymbol &&
+ DefinedFatBinSymbols.find(Name.str()) == DefinedFatBinSymbols.end())
+ FatBinSymbols.insert(Name.str());
+ else if (isGPUBinHandleSymbol &&
+ DefinedGPUBinHandleSymbols.find(Name.str()) ==
+ DefinedGPUBinHandleSymbols.end())
+ GPUBinHandleSymbols.insert(Name.str());
+ }
+ }
+
+ void errorHandler(llvm::Error Err) {
+ if (Quiet)
+ return;
+ C.getDriver().Diag(DiagID) << llvm::toString(std::move(Err));
+ }
+};
+
// Construct a clang-offload-bundler command to bundle code objects for
// different devices into a HIP fat binary.
void HIP::constructHIPFatbinCommand(Compilation &C, const JobAction &JA,
@@ -130,26 +304,84 @@ void HIP::constructGenerateObjFileFromHIPFatBinary(
auto HostTriple =
C.getSingleOffloadToolChain<Action::OFK_Host>()->getTriple();
+ HIPUndefinedFatBinSymbols Symbols(C);
+
+ std::string PrimaryHipFatbinSymbol;
+ std::string PrimaryGpuBinHandleSymbol;
+ bool FoundPrimaryHipFatbinSymbol = false;
+ bool FoundPrimaryGpuBinHandleSymbol = false;
+
+ std::vector<std::string> AliasHipFatbinSymbols;
+ std::vector<std::string> AliasGpuBinHandleSymbols;
+
+ // Iterate through symbols to find the primary ones and collect others for
+ // aliasing
+ for (const auto &Symbol : Symbols.getFatBinSymbols()) {
+ if (!FoundPrimaryHipFatbinSymbol) {
+ PrimaryHipFatbinSymbol = Symbol;
+ FoundPrimaryHipFatbinSymbol = true;
+ } else
+ AliasHipFatbinSymbols.push_back(Symbol);
+ }
+
+ for (const auto &Symbol : Symbols.getGPUBinHandleSymbols()) {
+ if (!FoundPrimaryGpuBinHandleSymbol) {
+ PrimaryGpuBinHandleSymbol = Symbol;
+ FoundPrimaryGpuBinHandleSymbol = true;
+ } else
+ AliasGpuBinHandleSymbols.push_back(Symbol);
+ }
+
// 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";
+ if (FoundPrimaryGpuBinHandleSymbol) {
+ // Define the first gpubin handle symbol
+ if (HostTriple.isWindowsMSVCEnvironment())
+ ObjStream << " .section .hip_gpubin_handle,\"dw\"\n";
+ else {
+ ObjStream << " .protected " << PrimaryGpuBinHandleSymbol << "\n";
+ ObjStream << " .type " << PrimaryGpuBinHandleSymbol << ",@object\n";
+ ObjStream << " .section .hip_gpubin_handle,\"aw\"\n";
+ }
+ ObjStream << " .globl " << PrimaryGpuBinHandleSymbol << "\n";
+ ObjStream << " .p2align 3\n"; // Align 8
+ ObjStream << PrimaryGpuBinHandleSymbol << ":\n";
+ ObjStream << " .zero 8\n"; // Size 8
+
+ // Generate alias directives for other gpubin handle symbols
+ for (const auto &AliasSymbol : AliasGpuBinHandleSymbols) {
+ ObjStream << " .globl " << AliasSymbol << "\n";
+ ObjStream << " .set " << AliasSymbol << "," << PrimaryGpuBinHandleSymbol
+ << "\n";
+ }
+ }
+ if (FoundPrimaryHipFatbinSymbol) {
+ // Define the first fatbin symbol
+ if (HostTriple.isWindowsMSVCEnvironment())
+ ObjStream << " .section .hip_fatbin,\"dw\"\n";
+ else {
+ ObjStream << " .protected " << PrimaryHipFatbinSymbol << "\n";
+ ObjStream << " .type " << PrimaryHipFatbinSymbol << ",@object\n";
+ ObjStream << " .section .hip_fatbin,\"a\",@progbits\n";
+ }
+ ObjStream << " .globl " << PrimaryHipFatbinSymbol << "\n";
+ ObjStream << " .p2align " << llvm::Log2(llvm::Align(HIPCodeObjectAlign))
+ << "\n";
+ // Generate alias directives for other fatbin symbols
+ for (const auto &AliasSymbol : AliasHipFatbinSymbols) {
+ ObjStream << " .globl " << AliasSymbol << "\n";
+ ObjStream << " .set " << AliasSymbol << "," << PrimaryHipFatbinSymbol
+ << "\n";
+ }
+ ObjStream << PrimaryHipFatbinSymbol << ":\n";
+ ObjStream << " .incbin ";
+ llvm::sys::printArg(ObjStream, BundleFile, /*Quote=*/true);
+ ObjStream << "\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";
if (HostTriple.isOSLinux() && HostTriple.isOSBinFormatELF())
ObjStream << " .section .note.GNU-stack, \"\", @progbits\n";
ObjStream.flush();
diff --git a/clang/lib/Driver/ToolChains/RISCVToolchain.cpp b/clang/lib/Driver/ToolChains/RISCVToolchain.cpp
index 85beb94..624099d 100644
--- a/clang/lib/Driver/ToolChains/RISCVToolchain.cpp
+++ b/clang/lib/Driver/ToolChains/RISCVToolchain.cpp
@@ -86,6 +86,11 @@ RISCVToolChain::GetUnwindLibType(const llvm::opt::ArgList &Args) const {
return ToolChain::UNW_None;
}
+ToolChain::UnwindTableLevel RISCVToolChain::getDefaultUnwindTableLevel(
+ const llvm::opt::ArgList &Args) const {
+ return UnwindTableLevel::None;
+}
+
void RISCVToolChain::addClangTargetOptions(
const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args,
diff --git a/clang/lib/Driver/ToolChains/RISCVToolchain.h b/clang/lib/Driver/ToolChains/RISCVToolchain.h
index cec817e..fa0aa26 100644
--- a/clang/lib/Driver/ToolChains/RISCVToolchain.h
+++ b/clang/lib/Driver/ToolChains/RISCVToolchain.h
@@ -28,6 +28,8 @@ public:
RuntimeLibType GetDefaultRuntimeLibType() const override;
UnwindLibType
GetUnwindLibType(const llvm::opt::ArgList &Args) const override;
+ UnwindTableLevel
+ getDefaultUnwindTableLevel(const llvm::opt::ArgList &Args) const override;
void
AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const override;