MimIR 0.1
MimIR is my Intermediate Representation
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages Concepts
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/check.h"
6#include "mim/world.h"
7
8// Don't use fancy C++-lambdas; it's way too annoying stepping through them in a debugger.
9
10namespace mim {
11
12const Def* Rewriter::rewrite(const Def* old_def) {
13 old_def = Hole::find(old_def);
14 if (old_def->isa<Univ>()) return world().univ();
15 if (auto i = old2new_.find(old_def); i != old2new_.end()) return i->second;
16 if (auto old_mut = old_def->isa_mut()) return rewrite_mut(old_mut);
17 return map(old_def, rewrite_imm(old_def));
18}
19
20const Def* Rewriter::rewrite_imm(const Def* old_def) {
21 // Extracts are used as conditional branches: make sure that we don't rewrite unreachable stuff.
22 if (auto extract = old_def->isa<Extract>()) {
23 if (auto index = Lit::isa(rewrite(extract->index()))) {
24 if (auto tuple = extract->tuple()->isa<Tuple>()) return rewrite(tuple->op(*index));
25 if (auto pack = extract->tuple()->isa_imm<Pack>(); pack && pack->shape()->is_closed())
26 return rewrite(pack->body());
27 }
28 }
29
30 auto new_type = old_def->isa<Type>() ? nullptr : rewrite(old_def->type());
31 auto size = old_def->num_ops();
32 auto new_ops = absl::FixedArray<const Def*>(size);
33 for (size_t i = 0; i != size; ++i) new_ops[i] = rewrite(old_def->op(i));
34 return old_def->rebuild(world(), new_type, new_ops);
35}
36
37const Def* Rewriter::rewrite_mut(Def* old_mut) {
38 auto new_type = rewrite(old_mut->type());
39 auto new_mut = old_mut->stub(world(), new_type);
40 map(old_mut, new_mut);
41
42 if (old_mut->is_set()) {
43 for (size_t i = 0, e = old_mut->num_ops(); i != e; ++i) new_mut->set(i, rewrite(old_mut->op(i)));
44 if (auto new_imm = new_mut->immutabilize()) return map(old_mut, new_imm);
45 }
46
47 return new_mut;
48}
49
50} // 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:262
T * isa_mut() const
If this is mutable, it will cast constness away and perform a dynamic_cast to T.
Definition def.h:425
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:487
bool is_closed() const
Has no free_vars()?
Definition def.cpp:350
Def * stub(World &w, const Def *type)
Definition def.h:483
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:163
static const Def * find(const Def *)
Union-Find to unify Holes.
Definition check.cpp:44
static std::optional< T > isa(const Def *def)
Definition def.h:719
A (possibly paramterized) Tuple.
Definition tuple.h:122
const Def * shape() const
Definition tuple.cpp:40
World & world()
Definition rewrite.h:14
virtual const Def * rewrite_mut(Def *)
Definition rewrite.cpp:37
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:20
virtual const Def * rewrite(const Def *)
Definition rewrite.cpp:12
Data constructor for a Sigma.
Definition tuple.h:56
const Univ * univ()
Definition world.h:200
Definition ast.h:14