1#ifndef PROTEUS_FRONTEND_DISPATCHER_HIP_H
2#define PROTEUS_FRONTEND_DISPATCHER_HIP_H
11#include <llvm/Bitcode/BitcodeReader.h>
12#include <llvm/Linker/Linker.h>
13#include <llvm/Support/FileSystem.h>
14#include <llvm/Support/MemoryBuffer.h>
18class DispatcherHIP :
public DispatcherDevice<JitEngineDeviceHIP> {
20 static DispatcherHIP &instance() {
21 static DispatcherHIP D{
"DispatcherHIP", JitEngineDeviceHIP::instance()};
25 DispatcherHIP(
const std::string &Label, JitEngineDeviceHIP &Jit)
31 void linkDeviceLibraries(Module &M)
override {
32 TIMESCOPE(DispatcherHIP, linkDeviceLibraries);
35 auto LoadBitcode = [&](
const llvm::SmallString<256> &Path) {
36 auto BufferOrErr = llvm::MemoryBuffer::getFile(Path);
37 if (!BufferOrErr || !BufferOrErr.get())
39 Path.str().str() +
" (" + Toolchain.Origin +
")");
40 auto Parsed = llvm::parseBitcodeFile(
41 BufferOrErr->get()->getMemBufferRef(), M.getContext());
44 Path.str().str() +
" (" + Toolchain.Origin +
")");
45 return std::move(Parsed.get());
48 auto AppendBitcodePath =
49 [&](llvm::SmallVectorImpl<llvm::SmallString<256>> &Paths,
50 llvm::StringRef Filename) {
51 llvm::SmallString<256> Path{Toolchain.DeviceLibDir};
52 llvm::sys::path::append(Path, Filename);
53 Paths.push_back(std::move(Path));
56 auto Exists = [&](llvm::StringRef Filename) ->
bool {
57 llvm::SmallString<256> Path{Toolchain.DeviceLibDir};
58 llvm::sys::path::append(Path, Filename);
59 return llvm::sys::fs::exists(Path);
62 auto PickFirstExisting =
63 [&](std::initializer_list<llvm::StringRef> Candidates)
65 for (
auto C : Candidates) {
72 llvm::SmallVector<llvm::SmallString<256>, 8> LibsToLink;
73 AppendBitcodePath(LibsToLink,
"ocml.bc");
74 AppendBitcodePath(LibsToLink,
"ockl.bc");
77 if (
auto Abi = PickFirstExisting({
"oclc_abi_version_600.bc",
78 "oclc_abi_version_500.bc",
79 "oclc_abi_version_400.bc"});
81 AppendBitcodePath(LibsToLink, Abi);
84 std::string(
"DispatchHIP: missing oclc ABI bitcode under ") +
85 Toolchain.DeviceLibDir +
" (" + Toolchain.Origin +
86 "; expected oclc_abi_version_{600,500,400}.bc)");
90 const std::string DeviceArch = Jit.getDeviceArch().str();
91 if (!llvm::StringRef{DeviceArch}.starts_with(
"gfx"))
94 const llvm::StringRef IsaSuffix = llvm::StringRef{DeviceArch}.drop_front(3);
95 const std::string IsaFile = (
"oclc_isa_version_" + IsaSuffix +
".bc").str();
98 IsaFile +
" under " + Toolchain.DeviceLibDir +
" (" +
99 Toolchain.Origin +
"; DeviceArch=" + DeviceArch +
")");
100 AppendBitcodePath(LibsToLink, IsaFile);
103 AppendBitcodePath(LibsToLink,
"oclc_unsafe_math_off.bc");
104 AppendBitcodePath(LibsToLink,
"oclc_finite_only_off.bc");
105 AppendBitcodePath(LibsToLink,
"oclc_daz_opt_off.bc");
106 AppendBitcodePath(LibsToLink,
"oclc_correctly_rounded_sqrt_on.bc");
109 const bool IsWave32 = llvm::StringRef{DeviceArch}.starts_with(
"gfx10") ||
110 llvm::StringRef{DeviceArch}.starts_with(
"gfx11") ||
111 llvm::StringRef{DeviceArch}.starts_with(
"gfx12");
112 AppendBitcodePath(LibsToLink, IsWave32 ?
"oclc_wavefrontsize64_off.bc"
113 :
"oclc_wavefrontsize64_on.bc");
115 llvm::Linker Linker{M};
116 for (
const auto &Path : LibsToLink) {
117 auto LibMod = LoadBitcode(Path);
118 Linker.linkInModule(std::move(LibMod),
119 llvm::Linker::Flags::LinkOnlyNeeded);
#define TIMESCOPE(...)
Definition TimeTracing.h:66
Definition MemoryCache.h:27
TargetModelType
Definition TargetModel.h:8
void reportFatalError(const llvm::Twine &Reason, const char *FILE, unsigned Line)
Definition Error.cpp:14
const ResolvedHIPToolchain & resolveHIPToolchain()
Definition HIPToolchain.cpp:273