MimIR 0.1
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
driver.h
Go to the documentation of this file.
1#pragma once
2
3#include <list>
4
5#include <absl/container/node_hash_map.h>
6
7#include "mim/flags.h"
8#include "mim/plugin.h"
9#include "mim/world.h"
10
11#include "mim/util/log.h"
12
13namespace mim {
14
15/// Some "global" variables needed all over the place.
16/// Well, there are not really global - that's the point of this class.
17class Driver : public fe::SymPool {
18public:
19 Driver();
20
21 /// @name Getters
22 ///@{
23 Flags& flags() { return flags_; }
24 const Flags& flags() const { return flags_; }
25 Log& log() const { return log_; }
26 World& world() { return world_; }
27 ///@}
28
29 /// @name Manage Search Paths
30 /// Search paths for plugins are in the following order:
31 /// 1. The empty path. Used as prefix to look into current working directory without resorting to an absolute path.
32 /// 2. All further user-specified paths via Driver::add_search_path; paths added first will also be searched first.
33 /// 3. All paths specified in the environment variable `MIM_PLUGIN_PATH`.
34 /// 4. `path/to/mim.exe/../../lib/mim`
35 /// 5. `CMAKE_INSTALL_PREFIX/lib/mim`
36 ///@{
37 const auto& search_paths() const { return search_paths_; }
38 void add_search_path(fs::path path) {
39 if (fs::exists(path) && fs::is_directory(path)) search_paths_.insert(insert_, std::move(path));
40 }
41 ///@}
42
43 /// @name Manage Imports
44 /// This is a list of pairs where each pair contains:
45 /// 1. The `fs::path` used during import,
46 /// 2. The name as Sym%bol used in the `import` directive or in Parser::import.
47 ///@{
48 class Imports {
49 public:
50 Imports(Driver& driver)
51 : driver_(driver) {}
52
53 /// @name Get imports
54 ///@{
55 const auto& path2sym() { return path2sym_; }
56 auto paths() { return path2sym_ | std::views::keys; }
57 auto syms() { return path2sym_ | std::views::values; }
58 ///@}
59
60 /// @name Iterators
61 ///@{
62 auto begin() const { return path2sym_.cbegin(); }
63 auto end() const { return path2sym_.cbegin(); }
64 ///@}
65
66 /// Yields a `fs::path*`, if not already added that you can use in Loc%ation; returns `nullptr` otherwise.
67 const fs::path* add(fs::path, Sym);
68
69 private:
70 Driver& driver_;
71 std::deque<std::pair<fs::path, Sym>> path2sym_;
72 };
73
74 const Imports& imports() const { return imports_; }
75 Imports& imports() { return imports_; }
76 ///@}
77
78 /// @name Load Plugin
79 /// Finds and loads a shared object file that implements the MimIR Plugin @p name.
80 /// If \a name is an absolute path to a `.so`/`.dll` file, this is used.
81 /// Otherwise, "name", "libmim_name.so" (Linux, Mac), "mim_name.dll" (Win)
82 /// are searched for in Driver::search_paths().
83 ///@{
84 void load(Sym name);
85 void load(const std::string& name) { return load(sym(name)); }
86 bool is_loaded(Sym sym) const { return lookup(plugins_, sym); }
87 void* get_fun_ptr(Sym plugin, const char* name);
88
89 template<class F>
90 auto get_fun_ptr(Sym plugin, const char* name) {
91 return reinterpret_cast<F*>(get_fun_ptr(plugin, name));
92 }
93
94 template<class F>
95 auto get_fun_ptr(const char* plugin, const char* name) {
96 return get_fun_ptr<F>(sym(plugin), name);
97 }
98 ///@}
99
100 /// @name Manage Plugins
101 /// All these lookups yield `nullptr` if the key has not been found.
102 ///@{
103 auto stage(flags_t flags) { return lookup(stages_, flags); }
104 const auto& stages() const { return stages_; }
105 auto normalizer(flags_t flags) const { return lookup(normalizers_, flags); }
106 auto normalizer(plugin_t d, tag_t t, sub_t s) const { return normalizer(d | flags_t(t << 8u) | s); }
107 auto backend(std::string_view name) { return lookup(backends_, name); }
108 ///@}
109
110private:
111 // This must go *first* so plugins will be unloaded *last* in the d'tor; otherwise funny things might happen ...
112 absl::node_hash_map<Sym, Plugin::Handle> plugins_;
113 Flags flags_;
114 mutable Log log_;
115 World world_;
116 std::list<fs::path> search_paths_;
117 std::list<fs::path>::iterator insert_ = search_paths_.end();
118 Backends backends_;
119 Flags2Stages stages_;
120 Normalizers normalizers_;
121 Imports imports_;
122};
123
124#define GET_FUN_PTR(plugin, f) get_fun_ptr<decltype(f)>(plugin, #f)
125
126} // namespace mim
auto end() const
Definition driver.h:63
Imports(Driver &driver)
Definition driver.h:50
const auto & path2sym()
Definition driver.h:55
auto begin() const
Definition driver.h:62
const fs::path * add(fs::path, Sym)
Yields a fs::path*, if not already added that you can use in Location; returns nullptr otherwise.
Definition driver.cpp:10
const auto & stages() const
Definition driver.h:104
void load(Sym name)
Definition driver.cpp:50
const Imports & imports() const
Definition driver.h:74
void add_search_path(fs::path path)
Definition driver.h:38
auto backend(std::string_view name)
Definition driver.h:107
auto normalizer(plugin_t d, tag_t t, sub_t s) const
Definition driver.h:106
World & world()
Definition driver.h:26
Log & log() const
Definition driver.h:25
const Flags & flags() const
Definition driver.h:24
bool is_loaded(Sym sym) const
Definition driver.h:86
void * get_fun_ptr(Sym plugin, const char *name)
Definition driver.cpp:88
auto normalizer(flags_t flags) const
Definition driver.h:105
Imports & imports()
Definition driver.h:75
void load(const std::string &name)
Definition driver.h:85
Flags & flags()
Definition driver.h:23
auto get_fun_ptr(Sym plugin, const char *name)
Definition driver.h:90
auto get_fun_ptr(const char *plugin, const char *name)
Definition driver.h:95
auto stage(flags_t flags)
Definition driver.h:103
const auto & search_paths() const
Definition driver.h:37
Facility to log what you are doing.
Definition log.h:17
The World represents the whole program and manages creation of MimIR nodes (Defs).
Definition world.h:31
Definition ast.h:14
u8 sub_t
Definition types.h:48
u64 flags_t
Definition types.h:45
auto lookup(const C &container, const K &key)
Yields pointer to element (or the element itself if it is already a pointer), if found and nullptr ot...
Definition util.h:100
absl::btree_map< std::string, void(*)(World &, std::ostream &)> Backends
Definition plugin.h:24
absl::flat_hash_map< flags_t, std::function< std::unique_ptr< Stage >(World &)> > Flags2Stages
Maps an an axiom of a Stage to a function that creates one.
Definition plugin.h:22
absl::flat_hash_map< flags_t, NormalizeFn > Normalizers
Definition plugin.h:19
u64 plugin_t
Definition types.h:46
u8 tag_t
Definition types.h:47
Compiler switches that must be saved and looked up in later phases of compilation.
Definition flags.h:11