MimIR
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
single_erasure.cpp
Go to the documentation of this file.
2
3namespace mim {
4
5/*
6 * SingleErasure
7 */
8
9Sieve SingleErasure::sieve(const Sigma* sigma) {
10 // A foreign declaration has no components to inspect.
11 if (!sigma->is_set()) return Sieve(sigma->num_ops());
12 return Sieve(sigma->ops(), [this](const Def* op) { return !old_world().inhabitant(op); });
13}
14
15const Def* SingleErasure::erase(const Single* single) {
16 if (is_unit(single)) return new_world().sigma();
17 return rewrite(single->op())->unfold_type();
18}
19
20const Def* SingleErasure::inhabitant(const Def* type) {
21 if (auto single = type->isa<Single>(); single && !is_unit(single)) return rewrite(single->op());
22 return new_world().inhabitant(rewrite(type));
23}
24
25size_t SingleErasure::remap(const Sieve& keep, const Def* index) {
26 auto i = Lit::isa(index);
27 if (!i)
28 index->blame("index is not a literal")
29 .n("dropping an information-free component shifts the indices of its successors")
30 .bail();
31
32 auto j = keep[*i];
33 assert(j != Sieve::Gone && "an Extract/Insert of a dropped component is erased before it is remapped");
34 return j;
35}
36
38 auto type = erase(single);
39 log().d("single-erasure `{}` → `{}`", single, type);
40 profile_count("singletons eliminated");
41 return type;
42}
43
45 profile_count("singletons eliminated");
46 return inhabitant(wrap->type());
47}
48
50 if (auto lone = Variant::isa_lone(variant)) return rewrite(lone);
51 return RWPhase::rewrite_imm_Variant(variant);
52}
53
55 if (Variant::isa_lone(inj->type())) return rewrite(inj->value());
56 return RWPhase::rewrite_imm_Inj(inj);
57}
58
61 return new_world().app(rewrite(match->arm(0)), rewrite(match->scrutinee()));
62 return RWPhase::rewrite_imm_Match(match);
63}
64
66 auto keep = sieve(sigma);
67 if (keep.all()) return RWPhase::rewrite_imm_Sigma(sigma);
68 return new_world().sigma(rewrite(keep.gather(sigma->ops())));
69}
70
72 auto keep = sieve(old_sigma);
73 if (keep.all()) return RWPhase::rewrite_mut_Sigma(old_sigma);
74
75 auto new_sigma = new_world().mut_sigma(rewrite(old_sigma->type()), keep.num_new());
76 return rewrite_stub(old_sigma, new_sigma, keep.new2old());
77}
78
80 if (old_world().inhabitant(tuple->type())) return inhabitant(tuple->type());
81 return RWPhase::rewrite_imm_Tuple(tuple);
82}
83
85 if (old_world().inhabitant(extract->type())) return inhabitant(extract->type());
86
87 if (auto sigma = extract->tuple()->type()->isa<Sigma>()) {
88 auto keep = sieve(sigma);
89 if (!keep.all())
90 return new_world().extract(rewrite(extract->tuple()), keep.num_new(), remap(keep, extract->index()));
91 }
92
93 return RWPhase::rewrite_imm_Extract(extract);
94}
95
97 if (old_world().inhabitant(insert->value()->type())) return rewrite(insert->tuple());
98
99 if (auto sigma = insert->tuple()->type()->isa<Sigma>()) {
100 auto keep = sieve(sigma);
101 if (!keep.all())
102 return new_world().insert(rewrite(insert->tuple()), keep.num_new(), remap(keep, insert->index()),
103 rewrite(insert->value()));
104 }
105
106 return RWPhase::rewrite_imm_Insert(insert);
107}
108
110 if (old_world().inhabitant(seq->is_intro() ? seq->type() : seq)) return new_world().prod(seq->is_intro());
111 return RWPhase::rewrite_imm_Seq(seq);
112}
113
115 // A mutable Seq has no immutable type to ask, so inspect its body directly.
116 if (seq->is_set() && old_world().inhabitant(seq->is_intro() ? seq->body()->type() : seq->body()))
117 return new_world().prod(seq->is_intro());
118 return RWPhase::rewrite_mut_Seq(seq);
119}
120
121} // namespace mim
Base class for all Defs.
Definition def.h:289
bool is_set() const
Definition def.h:396
bool is_intro() const noexcept
Definition def.h:347
constexpr auto ops() const noexcept
Definition def.h:374
const Def * unfold_type() const
Yields the type of this Def and builds a new Type (LSucc n) if necessary.
Definition def.cpp:469
const Def * type() const noexcept
Yields the "raw" type of this Def (maybe nullptr).
Definition def.h:1119
Extracts from a Sigma or Array-typed Extract::tuple the element at position Extract::index.
Definition tuple.h:360
const Def * tuple() const
Definition tuple.h:370
const Def * index() const
Definition tuple.h:371
Constructs a Join or Variant value.
Definition union.h:60
const Def * value() const
Definition union.h:70
Creates a new Tuple / Pack by inserting Insert::value at position Insert::index into Insert::tuple.
Definition tuple.h:385
static std::optional< T > isa(const Def *def)
Definition def.h:976
Scrutinize Match::scrutinee() and dispatch to Match::arms.
Definition union.h:123
const Def * scrutinee() const
Definition union.h:135
const Def * arm(size_t i) const
Definition union.h:140
const fe::Log & log() const
Definition phase.h:60
void profile_count(std::string_view key, uint64_t n=1)
Adds n to the custom fe::Profiler counter key of the current run; no-op unless profiling is enabled.
Definition phase.cpp:60
World & new_world()
Create new Defs into this.
Definition phase.h:379
const Def * rewrite_imm_Tuple(const Tuple *) override
Definition phase.cpp:237
const Def * rewrite_stub(Def *, Def *) override
Definition phase.cpp:250
World & old_world()
Get old Defs from here.
Definition phase.h:378
virtual const Def * rewrite_imm_Match(const Match *)
virtual const Def * rewrite_imm_Seq(const Seq *seq)
Definition rewrite.cpp:230
virtual const Def * rewrite_imm_Extract(const Extract *)
virtual const Def * rewrite_mut_Sigma(Sigma *)
virtual const Def * rewrite_imm_Insert(const Insert *)
virtual const Def * rewrite_mut_Seq(Seq *seq)
Definition rewrite.cpp:236
virtual const Def * rewrite_imm_Sigma(const Sigma *)
virtual const Def * rewrite_imm_Inj(const Inj *)
virtual const Def * rewrite(const Def *)
Definition rewrite.cpp:62
virtual const Def * rewrite_imm_Variant(const Variant *)
Base class for Arr and Pack.
Definition tuple.h:267
const Def * body() const
Definition tuple.h:280
Filters the components of an aggregate and keeps track of where the survivors end up.
Definition tuple.h:116
Sieve(size_t num)
Definition tuple.h:123
static constexpr size_t Gone
Definition tuple.h:118
A dependent tuple type.
Definition tuple.h:39
const Def * rewrite_imm_Tuple(const Tuple *) final
const Def * rewrite_imm_Variant(const Variant *) final
const Def * rewrite_mut_Seq(Seq *) final
const Def * rewrite_mut_Sigma(Sigma *) final
const Def * rewrite_imm_Wrap(const Wrap *) final
const Def * rewrite_imm_Match(const Match *) final
const Def * rewrite_imm_Insert(const Insert *) final
const Def * rewrite_imm_Sigma(const Sigma *) final
const Def * rewrite_imm_Extract(const Extract *) final
const Def * rewrite_imm_Inj(const Inj *) final
const Def * rewrite_imm_Single(const Single *) final
const Def * rewrite_imm_Seq(const Seq *) final
Singleton type formation.
Definition single.h:10
Data constructor for a Sigma.
Definition tuple.h:84
A sum type whose cases are positional: unlike a Join, they are neither sorted nor deduplicated.
Definition union.h:86
static const Def * isa_lone(const Def *d)
The payload A of a single-case Variant | A, which is isomorphic to A.
Definition union.h:109
const Def * insert(const Def *d, const Def *i, const Def *val)
Definition world.cpp:802
const Def * inhabitant(const Def *type)
The sole inhabitant of type, if it has exactly one, nullptr otherwise.
Definition world.h:342
const Def * sigma(Defs ops)
Definition world.cpp:506
const Def * app(const Def *callee, const Def *arg)
Definition world.cpp:416
const Def * extract(const Def *d, const Def *i)
Definition world.cpp:598
const Def * prod(bool term, Defs ops)
Definition world.h:497
Sigma * mut_sigma(const Def *type, size_t size)
Definition world.h:464
Singleton term introduction.
Definition single.h:32
Definition ast.h:16