Proteus
Programmable JIT compilation and optimization for C/C++ using LLVM
Loading...
Searching...
No Matches
JitStorageCache.hpp
Go to the documentation of this file.
1//===-- JitStorageCache.hpp -- JIT storage-based cache header impl. --===//
2//
3// Part of the Proteus Project, under the Apache License v2.0 with LLVM
4// Exceptions. See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef PROTEUS_JITSTOREDCACHE_HPP
12#define PROTEUS_JITSTOREDCACHE_HPP
13
14#include <cstdint>
15#include <filesystem>
16#include <llvm/Bitcode/BitcodeWriter.h>
17#include <llvm/IR/Module.h>
18#include <llvm/Support/ErrorHandling.h>
19#include <llvm/Support/MemoryBuffer.h>
20#include <llvm/Support/MemoryBufferRef.h>
21
22#include <llvm/ADT/StringRef.h>
23
25#include "proteus/Config.hpp"
26#include "proteus/Hashing.hpp"
27#include "proteus/Utils.h"
28
29namespace proteus {
30
31using namespace llvm;
32
33// NOTE: Storage cache assumes that stored code is re-usable across runs!
34// TODO: Source code changes should invalidate the cache. Also, if storing
35// assembly (PTX) or binary (ELF), then device globals may have different
36// addresses that render it invalid. In this case, store LLVM IR to re-link
37// globals.
39public:
41 : StorageDirectory(Config::get().ProteusCacheDir
42 ? Config::get().ProteusCacheDir.value()
43 : ".proteus") {
44 std::filesystem::create_directory(StorageDirectory);
45 }
46
47 std::unique_ptr<CompiledLibrary> lookup(HashT &HashValue) {
48 TIMESCOPE("object lookup");
49 Accesses++;
50
51 std::string Filebase =
52 StorageDirectory + "/cache-jit-" + HashValue.toString();
53
54 // We first try to load a relocatable object file to create the code
55 // library. If that fails, we try to find a dynamic library file to setup
56 // the code library. If both fail, this hash is not cached.
57 auto CacheBuf = MemoryBuffer::getFileAsStream(Filebase + ".o");
58 if (CacheBuf) {
59 Hits++;
60 return std::make_unique<CompiledLibrary>(std::move(*CacheBuf));
61 }
62
63 if (std::filesystem::exists(Filebase + ".so")) {
64 Hits++;
65 return std::make_unique<CompiledLibrary>(
66 SmallString<128>{Filebase + ".so"});
67 }
68
69 return nullptr;
70 }
71
72 void store(HashT &HashValue, MemoryBufferRef ObjBufRef) {
73 TIMESCOPE("Store cache");
74
75 std::string Filebase =
76 StorageDirectory + "/cache-jit-" + HashValue.toString();
77
78 saveToFile(Filebase + ".o", StringRef{ObjBufRef.getBufferStart(),
79 ObjBufRef.getBufferSize()});
80 }
81
82 void storeDynamicLibrary(HashT &HashValue, const SmallString<128> &Path) {
83 TIMESCOPE("Store cache");
84
85 std::string Filebase =
86 StorageDirectory + "/cache-jit-" + HashValue.toString();
87
88 sys::fs::copy_file(Path, Filebase + ".so");
89 }
90
91 void printStats() {
92 // Use printf to avoid re-ordering outputs by outs() in HIP.
93 printf("JitStorageCache hits %lu total %lu\n", Hits, Accesses);
94 }
95
96private:
97 uint64_t Hits = 0;
98 uint64_t Accesses = 0;
99 const std::string StorageDirectory;
100};
101
102} // namespace proteus
103
104#endif
#define TIMESCOPE(x)
Definition TimeTracing.hpp:64
void saveToFile(llvm::StringRef Filepath, T &&Data)
Definition Utils.h:23
Definition Config.hpp:112
Definition Hashing.hpp:20
std::string toString() const
Definition Hashing.hpp:28
Definition JitStorageCache.hpp:38
void store(HashT &HashValue, MemoryBufferRef ObjBufRef)
Definition JitStorageCache.hpp:72
void storeDynamicLibrary(HashT &HashValue, const SmallString< 128 > &Path)
Definition JitStorageCache.hpp:82
void printStats()
Definition JitStorageCache.hpp:91
JitStorageCache()
Definition JitStorageCache.hpp:40
std::unique_ptr< CompiledLibrary > lookup(HashT &HashValue)
Definition JitStorageCache.hpp:47
Definition Helpers.h:76
Definition BuiltinsCUDA.cpp:4