MimIR 0.1
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
rewrite.cpp
Go to the documentation of this file.
1#include "mim/rewrite.h"
2
3#include <absl/container/fixed_array.h>
4
5#include "mim/world.h"
6
7// Don't use fancy C++-lambdas; it's way too annoying stepping through them in a debugger.
8
9namespace mim {
10
11const Def* Rewriter::rewrite(const Def* old_def) {
12 if (old_def->isa<Univ>()) return world().univ();
13 if (auto i = old2new_.find(old_def); i != old2new_.end()) return i->second;
14 if (auto old_mut = old_def->isa_mut()) return rewrite_mut(old_mut);
15 return map(old_def, rewrite_imm(old_def));
16}
17
18const Def* Rewriter::rewrite_imm(const Def* old_def) {
19 // Extracts are used as conditional branches: make sure that we don't rewrite unreachable stuff.
20 if (auto extract = old_def->isa<Extract>()) {
21 if (auto index = Lit::isa(rewrite(extract->index()))) {
22 if (auto tuple = extract->tuple()->isa<Tuple>()) return rewrite(tuple->op(*index));
23 if (auto pack = extract->tuple()->isa_imm<Pack>(); pack && pack->shape()->is_closed())
24 return rewrite(pack->body());
25 }
26 }
27
28 auto new_type = old_def->isa<Type>() ? nullptr : rewrite(old_def->type());
29 auto size = old_def->num_ops();
30 auto new_ops = absl::FixedArray<const Def*>(size);
31 for (size_t i = 0; i != size; ++i) new_ops[i] = rewrite(old_def->op(i));
32 return old_def->rebuild(world(), new_type, new_ops);
33}
34
35const Def* Rewriter::rewrite_mut(Def* old_mut) {
36 auto new_type = rewrite(old_mut->type());
37 auto new_mut = old_mut->stub(world(), new_type);
38 map(old_mut, new_mut);
39
40 if (old_mut->is_set()) {
41 for (size_t i = 0, e = old_mut->num_ops(); i != e; ++i) new_mut->set(i, rewrite(old_mut->op(i)));
42 if (auto new_imm = new_mut->immutabilize()) return map(old_mut, new_imm);
43 }
44
45 return new_mut;
46}
47
48} // namespace mim
Base class for all Defs.
Definition def.h:198
bool is_set() const
Yields true if empty or the last op is set.
Definition def.cpp:304
T * isa_mut() const
If this is *mut*able, it will cast constness away and perform a dynamic_cast to T.
Definition def.h:430
const Def * op(size_t i) const noexcept
Definition def.h:264
const Def * type() const noexcept
Yields the "raw" type of this Def (maybe nullptr).
Definition def.h:242
const Def * rebuild(World &w, const Def *type, Defs ops) const
Def::rebuilds this Def while using new_op as substitute for its i'th Def::op.
Definition def.h:492
bool is_closed() const
Has no free_vars()?
Definition def.cpp:392
Def * stub(World &w, const Def *type)
Definition def.h:488
constexpr size_t num_ops() const noexcept
Definition def.h:265
Extracts from a Sigma or Array-typed Extract::tuple the element at position Extract::index.
Definition tuple.h:155
static std::optional< T > isa(const Def *def)
Definition def.h:730
A (possibly paramterized) Tuple.
Definition tuple.h:115
const Def * shape() const
Definition tuple.cpp:40
World & world()
Definition rewrite.h:14
virtual const Def * rewrite_mut(Def *)
Definition rewrite.cpp:35
const Def * map(const Def *old_def, const Def *new_def)
Map old_def to new_def and returns new_def;.
Definition rewrite.h:16
virtual const Def * rewrite_imm(const Def *)
Definition rewrite.cpp:18
virtual const Def * rewrite(const Def *)
Definition rewrite.cpp:11
Data constructor for a Sigma.
Definition tuple.h:50
const Univ * univ()
Definition world.h:200
Definition ast.h:14