| chigraph master Systems programming language written for beginners in LLVM

DefaultModuleCache.cpp
Go to the documentation of this file.
1
3 #include "chi/DefaultModuleCache.hpp"
4 #include "chi/BitcodeParser.hpp"
5 #include "chi/Context.hpp"
6 #include "chi/LLVMVersion.hpp"
7 #include "chi/ModuleCache.hpp"
8 #include "chi/Support/Result.hpp"
9
10 #include <cassert>
11
12 #include <boost/filesystem/operations.hpp>
13
14 #if LLVM_VERSION_LESS_EQUAL(3, 9)
15 #include <llvm/Bitcode/ReaderWriter.h>
16 #else
17 #include <llvm/Bitcode/BitcodeWriter.h>
18 #endif
19
20 #include <llvm/IR/Module.h>
21 #include <llvm/Support/FileSystem.h>
22 #include <llvm/Support/raw_ostream.h>
23
24 namespace chi {
25
26 DefaultModuleCache::DefaultModuleCache(chi::Context& ctx) : ModuleCache{ctx} {}
27
28 Result DefaultModuleCache::cacheModule(const boost::filesystem::path& moduleName,
29 llvm::Module& compiledModule, std::time_t timeAtFileRead) {
30 assert(!moduleName.empty() &&
31 "Cannot pass a empty module name to DefaultModuleCache::cacheModule");
32
33 Result res;
34
35 auto cachePath = cachePathForModule(moduleName);
36
37 // make the directories
38 boost::filesystem::create_directories(cachePath.parent_path());
39
40 // open & write
41 {
42 // open the file
43 std::error_code errCode;
44 std::string errString;
45 llvm::raw_fd_ostream fileStream {
46 cachePath.string().c_str(),
47 #if LLVM_VERSION_LESS_EQUAL(3, 5)
48 errString,
49 #else
50 errCode,
51 #endif
52 llvm::sys::fs::F_RW
53 };
54
55 if (errCode || !errString.empty()) {
56 res.addEntry("EUKN", "Failed to open file", {{"Path", cachePath.string()}});
57 return res;
58 }
59
60 // write it
61 llvm::WriteBitcodeToFile(&compiledModule, fileStream);
62 }
63
64 // set age to be correct
65 boost::filesystem::last_write_time(cachePath, timeAtFileRead);
66
67 return res;
68 }
69
70 boost::filesystem::path DefaultModuleCache::cachePathForModule(
71 const boost::filesystem::path& moduleName) const {
72 return context().workspacePath() / "lib" / (moduleName.string() + ".bc");
73 }
74
75 void DefaultModuleCache::invalidateCache(const boost::filesystem::path& moduleName) {
76 assert(!moduleName.empty() && "Cannot pass empty path to DefaultModuleCache::invalidateCache");
77
78 auto cachePath = cachePathForModule(moduleName);
79
80 boost::filesystem::remove(cachePath);
81 }
82
83 std::time_t DefaultModuleCache::cacheUpdateTime(const boost::filesystem::path& moduleName) const {
84 return boost::filesystem::last_write_time(cachePathForModule(moduleName));
85 }
86
87 std::unique_ptr<llvm::Module> DefaultModuleCache::retrieveFromCache(
88 const boost::filesystem::path& moduleName, std::time_t atLeastThisNew) {
89 assert(!moduleName.empty() &&
90 "Cannot pass empty path to DefaultModuleCache::retrieveFromCache");
91
92 auto cachePath = cachePathForModule(moduleName);
93
94 // if there is no cache, then there is nothing to retrieve
95 if (!boost::filesystem::is_regular_file(cachePath)) { return nullptr; }
96
97 // see if the cache is new enough
98 auto cacheEditTime = cacheUpdateTime(moduleName);
99 if (cacheEditTime < atLeastThisNew) { return nullptr; }
100
101 // read the cache
102 std::unique_ptr<llvm::Module> fetchedMod;
103 auto res = parseBitcodeFile(cachePath, context().llvmContext(), &fetchedMod);
104
105 if (!res) { return nullptr; }
106
107 return fetchedMod;
108 }
109
110 } // namespace chi
BitcodeParser.hpp
LLVMVersion.hpp
chi::parseBitcodeFile
Result parseBitcodeFile(const boost::filesystem::path &file, llvm::LLVMContext &ctx, std::unique_ptr< llvm::Module > *toFill)
Parse a bitcode file.
Definition: BitcodeParser.cpp:56
chi::DefaultModuleCache::invalidateCache
void invalidateCache(const boost::filesystem::path &moduleName) override
Definition: DefaultModuleCache.cpp:75
Result.hpp
Defines the Result class and related functions.
chi::Context::workspacePath
boost::filesystem::path workspacePath() const
Get the workspace path of the Context.
Definition: Context.hpp:138
ModuleCache.hpp
chi::DefaultModuleCache::retrieveFromCache
std::unique_ptr< llvm::Module > retrieveFromCache(const boost::filesystem::path &moduleName, std::time_t atLeastThisNew) override
Retrieve a module from the cache.
Definition: DefaultModuleCache.cpp:87
chi::Context
The class that handles the loading, creation, storing, and compilation of modules It also stores a LL...
Definition: Context.hpp:55
chi::DefaultModuleCache::cachePathForModule
boost::filesystem::path cachePathForModule(const boost::filesystem::path &moduleName) const
Get the cache name for a module.
Definition: DefaultModuleCache.cpp:70
chi::DefaultModuleCache::cacheUpdateTime
std::time_t cacheUpdateTime(const boost::filesystem::path &moduleName) const override
Get the time that a cache was updated.
Definition: DefaultModuleCache.cpp:83
chi::ModuleCache
This class provides an interface for creating module caches.
Definition: ModuleCache.hpp:16
chi::DefaultModuleCache::cacheModule
Result cacheModule(const boost::filesystem::path &moduleName, llvm::Module &compiledModule, std::time_t timeAtFileRead) override
Cache a module.
Definition: DefaultModuleCache.cpp:28
chi::ModuleCache::context
Context & context() const
Get the context this cache is bound to.
Definition: ModuleCache.hpp:59
chi
The namespace where chigraph lives.
Definition: BitcodeParser.hpp:12
Context.hpp
Defines the Context class and related functions.
chi::Result
The result object, used for identifiying errors with good diagnostics.
Definition: Result.hpp:72
chi::DefaultModuleCache::DefaultModuleCache
DefaultModuleCache(Context &ctx)
Default constrcutor.
Definition: DefaultModuleCache.cpp:26