MimIR
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#include <utility>
5
6#include <absl/container/node_hash_map.h>
7
8#include "mim/flags.h"
9#include "mim/plugin.h"
10#include "mim/world.h"
11
12#include "mim/ast/tok.h"
13#include "mim/util/log.h"
14#include "mim/util/profile.h"
15
16namespace mim {
17
18/// Some "global" variables needed all over the place.
19/// Well, there are not really global - that's the point of this class.
20class Driver : public fe::SymPool {
21public:
22 /// @name Construction
23 ///@{
24 Driver(std::string name);
26 : Driver(std::string{}) {}
27
28 Driver(const Driver&) = delete;
29 Driver(Driver&&) = delete;
31 ///@}
32
33 /// @name Getters
34 ///@{
35 Flags& flags() { return flags_; }
36 const Flags& flags() const { return flags_; }
37 Log& log() const { return log_; }
38 Profiler& profiler() { return profiler_; }
39 const Profiler& profiler() const { return profiler_; }
40 World& world() { return world_; }
41 const Version& version() const { return version_; } ///< MimIR Version.
42 ///@}
43
44 /// @name Manage Search Paths
45 /// Search paths for plugins are in the following order:
46 /// 1. The empty path. Used as prefix to look into current working directory without resorting to an absolute path.
47 /// 2. All further user-specified paths via Driver::add_search_path; paths added first will also be searched first.
48 /// 3. All paths specified in the environment variable `MIM_PLUGIN_PATH`.
49 /// 4. The path derived from the location of `libmim` (`<libmim>/mim`)
50 /// 5. `CMAKE_INSTALL_PREFIX/lib/mim`
51 ///@{
52 const auto& search_paths() const { return search_paths_; }
53 void add_search_path(fs::path path) {
54 if (fs::exists(path) && fs::is_directory(path)) search_paths_.insert(insert_, std::move(path));
55 }
56 ///@}
57
58 /// @name Manage Imports
59 /// This tracks:
60 /// 1. The distinct files that have already been parsed to avoid reparsing them,
61 /// 2. The distinct import or plugin directives that should be emitted again later.
62 ///@{
63 class Imports {
64 public:
65 struct Entry {
66 fs::path path;
67 Sym sym;
69 };
70
71 Imports(Driver& driver)
72 : driver_(driver) {}
73
74 /// @name Get imports
75 ///@{
76 const auto& entries() const { return entries_; }
77 ///@}
78
79 /// @name Iterators
80 ///@{
81 auto begin() const { return entries_.cbegin(); }
82 auto end() const { return entries_.cend(); }
83 ///@}
84
85 /// Remembers an import or plugin directive and reports whether the resolved file is new.
86 std::pair<const fs::path*, bool> add(fs::path, Sym, ast::Tok::Tag);
87
88 private:
89 Driver& driver_;
90 std::deque<Entry> entries_;
91 std::deque<fs::path> parsed_paths_;
92 };
93
94 const Imports& imports() const { return imports_; }
95 Imports& imports() { return imports_; }
96 ///@}
97
98 /// @name Load Plugin
99 /// Finds and loads a shared object file that implements the MimIR Plugin @p name.
100 /// If \a name is an absolute path to a `.so`/`.dll` file, this is used.
101 /// Otherwise, "name", "libmim_name.so" (Linux, Mac), "mim_name.dll" (Win)
102 /// are searched for in Driver::search_paths().
103 ///@{
104 void load(Sym name);
105 void load(const std::string& name) { return load(sym(name)); }
106 bool is_loaded(Sym sym) const { return lookup(plugins_, sym); }
107 void* get_fun_ptr(Sym plugin, const char* name);
108
109 template<class F>
110 auto get_fun_ptr(Sym plugin, const char* name) {
111 return reinterpret_cast<F*>(get_fun_ptr(plugin, name));
112 }
113
114 template<class F>
115 auto get_fun_ptr(const char* plugin, const char* name) {
116 return get_fun_ptr<F>(sym(plugin), name);
117 }
118 ///@}
119
120 /// @name Manage Plugins
121 /// All these lookups yield `nullptr` if the key has not been found.
122 ///@{
123 auto phase(flags_t flags) { return lookup(phases_, flags); }
124 const auto& phases() const { return phases_; }
125 auto normalizer(flags_t flags) const { return lookup(normalizers_, flags); }
126 auto normalizer(plugin_t d, tag_t t, sub_t s) const { return normalizer(Annex::flags(d, t, s)); }
127 ///@}
128
129 /// @name Plugin/Phase Arguments
130 /// Freeform command-line arguments addressed to a plugin/phase (`-X <plugin>:<arg>`).
131 /// A Phase reads its own arguments via Phase::args().
132 ///@{
133 void add_arg(Sym plugin, std::string arg) { plugin_args_[plugin].emplace_back(std::move(arg)); }
134 const Vector<std::string>& args(Sym plugin) const; ///< Yields an empty Vector if @p plugin has none.
135 ///@}
136
137private:
138 // This must go *first* so plugins will be unloaded *last* in the d'tor; otherwise funny things might happen ...
139 absl::node_hash_map<Sym, Plugin::Handle> plugins_;
140 Version version_;
141 Flags flags_;
142 mutable Log log_;
143 Profiler profiler_;
144 World world_;
145 std::list<fs::path> search_paths_;
146 std::list<fs::path>::iterator insert_ = search_paths_.end();
147 Flags2Phases phases_;
148 Normalizers normalizers_;
149 fe::SymMap<Vector<std::string>> plugin_args_;
150 Imports imports_;
151};
152
153#define GET_FUN_PTR(plugin, f) get_fun_ptr<decltype(f)>(plugin, #f)
154
155} // namespace mim
auto end() const
Definition driver.h:82
Imports(Driver &driver)
Definition driver.h:71
auto begin() const
Definition driver.h:81
const auto & entries() const
Definition driver.h:76
std::pair< const fs::path *, bool > add(fs::path, Sym, ast::Tok::Tag)
Remembers an import or plugin directive and reports whether the resolved file is new.
Definition driver.cpp:14
void load(Sym name)
Definition driver.cpp:76
const Imports & imports() const
Definition driver.h:94
void add_search_path(fs::path path)
Definition driver.h:53
Profiler & profiler()
Definition driver.h:38
const Vector< std::string > & args(Sym plugin) const
Yields an empty Vector if plugin has none.
Definition driver.cpp:127
Driver(std::string name)
Definition driver.cpp:47
const Version & version() const
MimIR Version.
Definition driver.h:41
auto normalizer(plugin_t d, tag_t t, sub_t s) const
Definition driver.h:126
World & world()
Definition driver.h:40
Log & log() const
Definition driver.h:37
const Flags & flags() const
Definition driver.h:36
bool is_loaded(Sym sym) const
Definition driver.h:106
const Profiler & profiler() const
Definition driver.h:39
Driver & operator=(Driver)=delete
void * get_fun_ptr(Sym plugin, const char *name)
Definition driver.cpp:122
auto normalizer(flags_t flags) const
Definition driver.h:125
Imports & imports()
Definition driver.h:95
Driver(const Driver &)=delete
void load(const std::string &name)
Definition driver.h:105
Flags & flags()
Definition driver.h:35
auto get_fun_ptr(Sym plugin, const char *name)
Definition driver.h:110
auto get_fun_ptr(const char *plugin, const char *name)
Definition driver.h:115
const auto & phases() const
Definition driver.h:124
void add_arg(Sym plugin, std::string arg)
Definition driver.h:133
auto phase(flags_t flags)
Definition driver.h:123
Driver(Driver &&)=delete
const auto & search_paths() const
Definition driver.h:52
Facility to log what you are doing.
Definition log.h:18
Records wall-clock timings for (possibly nested) Phase runs and reports them in various formats.
Definition profile.h:24
This is a thin wrapper for absl::InlinedVector<T, N, A> which is a drop-in replacement for std::vecto...
Definition vector.h:18
The World represents the whole program and manages creation of MimIR nodes (Defs).
Definition world.h:36
Definition ast.h:14
u8 sub_t
Definition types.h:42
u64 flags_t
Definition types.h:39
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:99
absl::flat_hash_map< flags_t, std::function< std::unique_ptr< Phase >(World &)> > Flags2Phases
Maps an axiom of a Phase to a function that creates one.
Definition plugin.h:25
absl::flat_hash_map< flags_t, NormalizeFn > Normalizers
Definition plugin.h:22
u64 plugin_t
Definition types.h:40
u8 tag_t
Definition types.h:41
Definition span.h:126
static constexpr flags_t flags(plugin_t p, tag_t t, sub_t s=0)
Assembles the full flags from its plugin, tag, and sub fields.
Definition plugin.h:140
Compiler switches that must be saved and looked up in later phases of compilation.
Definition flags.h:11