Thorin 1.9.0
The Higher ORder INtermediate representation
Loading...
Searching...
No Matches
check.h
Go to the documentation of this file.
1#pragma once
2
3#include <deque>
4
5#include "thorin/def.h"
6
7namespace thorin {
8
9/// This node is a hole in the IR that is inferred by its context later on.
10/// It is modelled as a *mut*able Def.
11/// If inference was successful, it's Infer::op will be set to the inferred Def.
12class Infer : public Def {
13private:
14 Infer(const Def* type)
15 : Def(Node, type, 1, 0) {}
16
17public:
18 /// @name op
19 ///@{
20 const Def* op() const { return Def::op(0); }
21 Infer* set(const Def* op) { return Def::set(0, op)->as<Infer>(); }
22 Infer* reset(const Def* op) { return Def::reset(0, op)->as<Infer>(); }
23 Infer* unset() { return Def::unset()->as<Infer>(); }
24 ///@}
25
26 /// Eliminate Infer%s that may have been resolved in the meantime by rebuilding.
27 /// @returns `true`, if one of the arguements was in fact updated.
28 static bool eliminate(Vector<Ref*>);
29 static bool should_eliminate(Ref def) { return def->isa_imm() && def->has_dep(Dep::Infer); }
30
31 /// [Union-Find](https://en.wikipedia.org/wiki/Disjoint-set_data_structure) to unify Infer nodes.
32 /// Def::flags is used to keep track of rank for
33 /// [Union by rank](https://en.wikipedia.org/wiki/Disjoint-set_data_structure#Union_by_rank).
34 static const Def* find(const Def*);
35
36 Infer* stub(Ref type) { return stub_(world(), type)->set(dbg()); }
37
38private:
39 Infer* stub_(World&, Ref) override;
40 flags_t rank() const { return flags(); }
41 flags_t& rank() { return flags_; }
42
43 THORIN_DEF_MIXIN(Infer)
44 friend class Check;
45};
46
47class Check {
48public:
50 : world_(world) {}
51
52 World& world() { return world_; }
53
54 /// Are d1 and d2 α-equivalent?
55 /// * In @p infer mode, type inference is happening and Infer%s will be resolved, if possible.
56 /// Also, two *free* but *different* Var%s **are** considered α-equivalent.
57 /// * When **not* in @p infer mode, no type inference is happening and Infer%s will not be touched.
58 /// Also, Two *free* but *different* Var%s are **not** considered α-equivalent.
59 template<bool infer = true> static bool alpha(Ref d1, Ref d2) { return Check(d1->world()).alpha_<infer>(d1, d2); }
60
61 /// Can @p value be assigned to sth of @p type?
62 /// @note This is different from `equiv(type, value->type())` since @p type may be dependent.
63 static bool assignable(Ref type, Ref value) { return Check(type->world()).assignable_(type, value); }
64
65 /// Yields `defs.front()`, if all @p defs are Check::alpha-equivalent (`infer = false`) and `nullptr` otherwise.
66 static Ref is_uniform(Defs defs);
67
68private:
69#ifdef THORIN_ENABLE_CHECKS
70 template<bool> bool fail();
71#else
72 template<bool> bool fail() { return false; }
73#endif
74
75 template<bool infer> bool alpha_(Ref d1, Ref d2);
76 template<bool infer> bool alpha_internal(Ref, Ref);
77 bool assignable_(Ref type, Ref value);
78
79 World& world_;
80 using Vars = MutMap<Def*>;
81 Vars vars_;
82 MutMap<Ref> done_;
83};
84
85} // namespace thorin
static bool alpha(Ref d1, Ref d2)
Are d1 and d2 α-equivalent?
Definition check.h:59
static bool assignable(Ref type, Ref value)
Can value be assigned to sth of type?
Definition check.h:63
World & world()
Definition check.h:52
Check(World &world)
Definition check.h:49
Base class for all Defs.
Definition def.h:222
Def * reset(size_t i, const Def *def)
Successively reset from left to right.
Definition def.h:291
flags_t flags_
Definition def.h:577
bool has_dep(Dep d) const
Definition def.h:336
friend class World
Definition def.h:608
const T * isa_imm() const
Definition def.h:443
const Def * op(size_t i) const
Definition def.h:269
Def * unset()
Unsets all Def::ops; works even, if not set at all or partially.
Definition def.cpp:272
const Def * type() const
Yields the raw type of this Def, i.e. maybe nullptr.
Definition def.h:248
Dbg dbg() const
Definition def.h:468
flags_t flags() const
Definition def.h:237
Def * set(size_t i, const Def *def)
Successively set from left to right.
Definition def.cpp:254
World & world() const
Definition def.cpp:421
This node is a hole in the IR that is inferred by its context later on.
Definition check.h:12
static const Def * find(const Def *)
Union-Find to unify Infer nodes.
Definition check.cpp:29
Infer * reset(const Def *op)
Definition check.h:22
friend class Check
Definition check.h:44
Infer * set(const Def *op)
Definition check.h:21
static bool eliminate(Vector< Ref * >)
Eliminate Infers that may have been resolved in the meantime by rebuilding.
Definition check.cpp:62
const Def * op() const
Definition check.h:20
Infer * stub_(World &, Ref) override
Definition def.cpp:138
Infer * stub(Ref type)
Definition check.h:36
static bool should_eliminate(Ref def)
Definition check.h:29
Infer * unset()
Definition check.h:23
Helper class to retrieve Infer::arg if present.
Definition def.h:87
This is a thin wrapper for std::span<T, N> with the following additional features:
Definition span.h:28
This is a thin wrapper for absl::InlinedVector<T, N, A> which in turn is a drop-in replacement for st...
Definition vector.h:16
The World represents the whole program and manages creation of Thorin nodes (Defs).
Definition world.h:35
#define THORIN_DEF_MIXIN(T)
Definition def.h:198
Definition cfg.h:11
u64 flags_t
Definition types.h:46
PooledSet< const Var * > Vars
Definition def.h:81