source: icGREP/icgrep-devel/icgrep/object_cache.cpp @ 5391

Last change on this file since 5391 was 5391, checked in by cameron, 2 years ago

ParabixDriver/ObjectCache? separate compilation and linking: initial check-in with wc

File size: 3.6 KB
Line 
1#include <string>
2
3#include "object_cache.h"
4#include <llvm/Support/raw_ostream.h>
5#include <llvm/Support/FileSystem.h>
6#include <llvm/Support/Path.h>
7#include <llvm/IR/Module.h>
8
9
10#ifdef OBJECT_CACHE_DEBUG
11#include <iostream>
12#endif
13
14using namespace llvm;
15
16//===----------------------------------------------------------------------===//
17// Object cache (based on tools/lli/lli.cpp, LLVM 3.6.1)
18//
19// This object cache implementation writes cached objects to disk to the
20// directory specified by CacheDir, using a filename provided in the module
21// descriptor. The cache tries to load a saved object using that path if the
22// file exists.
23//
24ParabixObjectCache::ParabixObjectCache(const std::string &dir): CacheDir(dir) {}
25
26ParabixObjectCache::ParabixObjectCache() {
27    // $HOME/.cache/icgrep
28    // TODO use path::user_cache_directory once we have llvm >= 3.7.
29    sys::path::home_directory(CacheDir);
30    std::string Version = PARABIX_VERSION;
31    std::string Date = __DATE__;
32    std::string Time = __TIME__;
33    std::string DateStamp = Date.substr(7) + Date.substr(0,3) + (Date[4] == ' ' ? Date.substr(5,1) : Date.substr(4,2));
34    std::string CacheSubDir = "Parabix" + Version + "_" + DateStamp + "@" + Time;
35    sys::path::append(CacheDir, ".cache", CacheSubDir);
36}
37
38ParabixObjectCache::~ParabixObjectCache() {}
39
40void ParabixObjectCache::notifyObjectCompiled(const Module *M, MemoryBufferRef Obj) {
41    const std::string &ModuleID = M->getModuleIdentifier();
42   
43    Path CacheName(CacheDir);
44    if (!getCacheFilename(ModuleID, CacheName)) return;
45    if (!CacheDir.empty())      // Re-creating an existing directory is fine.
46        sys::fs::create_directories(Twine(CacheDir));
47    std::error_code EC;
48    raw_fd_ostream outfile(CacheName, EC, sys::fs::F_None);
49    outfile.write(Obj.getBufferStart(), Obj.getBufferSize());
50    outfile.close();
51#ifdef OBJECT_CACHE_DEBUG
52    std::cerr << "Cache created: " << CacheName.c_str() << std::endl;
53#endif
54}
55
56
57bool ParabixObjectCache::loadCachedObjectFile(const Module* M) {
58    const std::string ModuleID = M->getModuleIdentifier();
59    auto f = cachedObjectMap.find(ModuleID);
60    if (f != cachedObjectMap.end()) {
61        return true;
62    }
63    Path CachedObjectName(CacheDir);
64    if (!getCacheFilename(ModuleID, CachedObjectName)) return false;
65    ErrorOr<std::unique_ptr<MemoryBuffer>> KernelObjectBuffer = MemoryBuffer::getFile(CachedObjectName.c_str(), -1, false);
66    if (!KernelObjectBuffer) return false;
67    // Make a copy so that the JIT engine can freely modify it.
68    cachedObjectMap.emplace(ModuleID, std::move(KernelObjectBuffer.get()));
69    return true;
70}
71
72
73std::unique_ptr<MemoryBuffer> ParabixObjectCache::getObject(const Module* M) {
74    const std::string &ModuleID = M->getModuleIdentifier();
75    auto f = cachedObjectMap.find(ModuleID);
76    if (f == cachedObjectMap.end()) {
77        return nullptr;
78    }
79#ifdef OBJECT_CACHE_DEBUG
80    std::cerr << "Found cached object." << std::endl;
81#endif
82    // Return a copy of the buffer, for MCJIT to modify, if necessary.
83    return MemoryBuffer::getMemBufferCopy(f->second.get()->getBuffer());
84}
85
86bool ParabixObjectCache::getCacheFilename(const std::string &ModID, Path &CacheName) {
87#ifdef OBJECT_CACHE_DEBUG
88    std::cerr << "ModuleID: " << ModID << std::endl;
89#endif
90    const std::string Prefix("Parabix:");
91    size_t PrefixLength = Prefix.length();
92    if (ModID.substr(0, PrefixLength) != Prefix)
93        return false;
94
95    CacheName = CacheDir;
96    sys::path::append(CacheName, ModID.substr(PrefixLength) + ".o");
97#ifdef OBJECT_CACHE_DEBUG
98    std::cerr << "CacheName: " << CacheName.c_str() << std::endl;
99#endif
100    return true;
101}
Note: See TracBrowser for help on using the repository browser.