MimIR
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
compile.cpp
Go to the documentation of this file.
2
3#include <memory>
4
5#include <mim/config.h>
6#include <mim/driver.h>
7#include <mim/pass.h>
8#include <mim/phase.h>
9
10#include <mim/pass/beta_red.h>
11#include <mim/pass/eta_exp.h>
12#include <mim/pass/eta_red.h>
13#include <mim/pass/lam_spec.h>
14#include <mim/pass/scalarize.h>
21#include <mim/phase/ret_wrap.h>
23
25
26using namespace mim;
27using namespace mim::plug;
28
29/// Stage hook for `%compile.named_phase`, `%compile.named_pass`, and `%compile.named_repl`.
30/// Reads the fully-qualified annex name (e.g. `"clos.clos_conv_phase"`) from the driving App at stage-build time,
31/// looks up the matching annex `Def` in the current `World`, and *redirects* Stage::create to that annex's own
32/// Stage. If the plugin part of the name is not loaded or the annex is missing, it elides (resolves to nothing),
33/// so the enclosing `%compile.phases`/`passes`/`repls` simply skips it.
34class Named : public Stage {
35public:
37 : Stage(w, a) {}
38
39 void apply(const App* app) final {
40 if (!app) return;
41 auto str = tuple2str(app->arg());
42 if (str.empty()) return;
43
44 auto dot = str.find('.');
45 if (dot == std::string::npos) return;
46 auto begin = str[0] == '%' ? 1uz : 0uz; // skip the leading '%' of the annex name
47 if (!driver().is_loaded(driver().sym(str.substr(begin, dot - begin)))) return;
48
49 if (auto def = world().annex(driver().sym(str))) resolved_ = Stage::create(driver().stages(), def);
50 }
51
52 bool redirects() const override { return true; }
53 std::unique_ptr<Stage> take_resolved() override { return std::move(resolved_); }
54
55private:
56 std::unique_ptr<Stage> resolved_;
57};
58
59void reg_stages(Flags2Stages& stages) {
60 // clang-format off
61 assert_emplace(stages, Annex::base<compile::null_phase>(), [](World&) { return std::unique_ptr<Phase>{}; });
62 assert_emplace(stages, Annex::base<compile::null_repl >(), [](World&) { return std::unique_ptr<Repl >{}; });
63 assert_emplace(stages, Annex::base<compile::null_pass >(), [](World&) { return std::unique_ptr<Pass >{}; });
64 // phases
78 // repls
80 // passes
89 // clang-format on
90}
91
void reg_stages(Flags2Stages &stages)
Definition affine.cpp:12
void apply(const App *app) final
Invoked if your Stage has additional args.
Definition compile.cpp:39
std::unique_ptr< Stage > take_resolved() override
The Stage to use instead; nullptr means elide.
Definition compile.cpp:53
bool redirects() const override
If true, Stage::create uses take_resolved().
Definition compile.cpp:52
Named(World &w, flags_t a)
Definition compile.cpp:36
World & world()
Definition pass.h:77
static void hook(Flags2Stages &stages)
Definition pass.h:70
Stage(World &world, std::string name)
Definition pass.h:30
Driver & driver()
Definition pass.h:78
static std::unique_ptr< Stage > create(const Flags2Stages &stages, const Def *def)
Definition pass.h:50
flags_t annex() const
Definition pass.h:81
The World represents the whole program and manages creation of MimIR nodes (Defs).
Definition world.h:36
void reg_stages(Flags2Stages &stages)
Definition compile.cpp:59
#define MIM_EXPORT
Definition config.h:19
void register_normalizers(Normalizers &normalizers)
Definition ast.h:14
auto assert_emplace(C &container, Args &&... args)
Invokes emplace on container, asserts that insertion actually happened, and returns the iterator.
Definition util.h:117
u64 flags_t
Definition types.h:39
std::string tuple2str(const Def *)
Definition tuple.cpp:83
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:25
mim::Plugin mim_get_plugin()
#define MIM_VERSION
Definition plugin.h:54
static consteval flags_t base()
Definition plugin.h:150
Basic info and registration function pointer to be returned from a specific plugin.
Definition plugin.h:59