Thorin 1.9.0
The Higher ORder INtermediate representation
Loading...
Searching...
No Matches
lower_typed_clos_prep.cpp
Go to the documentation of this file.
2
4
5namespace thorin::plug::clos {
6
7namespace {
8
9bool interesting_type(Ref type, DefSet& visited) {
10 if (type->isa_mut()) visited.insert(type);
11 if (isa_clos_type(type)) return true;
12 if (auto sigma = type->isa<Sigma>())
13 return std::any_of(sigma->ops().begin(), sigma->ops().end(),
14 [&](auto d) { return !visited.contains(d) && interesting_type(d, visited); });
15 if (auto arr = type->isa<Arr>()) return interesting_type(arr->body(), visited);
16 return false;
17}
18
19bool interesting_type(Ref def) {
20 auto visited = DefSet();
21 return interesting_type(def->type(), visited);
22}
23
24void split(DefSet& out, Ref def, bool as_callee) {
25 if (auto lam = def->isa<Lam>()) {
26 out.insert(lam);
27 } else if (auto [var, lam] = ca_isa_var<Lam>(def); var && lam) {
28 if (var->type()->isa<Pi>() || interesting_type(var)) out.insert(var);
29 } else if (auto c = isa_clos_lit(def, false)) {
30 split(out, c.fnc(), as_callee);
31 } else if (auto a = match<attr>(def)) {
32 split(out, a->arg(), as_callee);
33 } else if (auto proj = def->isa<Extract>()) {
34 split(out, proj->tuple(), as_callee);
35 } else if (auto pack = def->isa<Pack>()) {
36 split(out, pack->body(), as_callee);
37 } else if (auto tuple = def->isa<Tuple>()) {
38 for (auto op : tuple->ops()) split(out, op, as_callee);
39 } else if (as_callee) {
40 out.insert(def);
41 }
42}
43
44DefSet split(Ref def, bool keep_others) {
45 DefSet out;
46 split(out, def, keep_others);
47 return out;
48}
49
50} // namespace
51
52undo_t LowerTypedClosPrep::set_esc(Ref def) {
53 auto undo = No_Undo;
54 for (auto d : split(def, false)) {
55 if (is_esc(d)) continue;
56 if (auto lam = d->isa_mut<Lam>())
57 undo = std::min(undo, undo_visit(lam));
58 else if (auto [var, lam] = ca_isa_var<Lam>(d); var && lam)
59 undo = std::min(undo, undo_visit(lam));
60 world().DLOG("set esc: {}", d);
61 esc_.emplace(d);
62 }
63 return undo;
64}
65
67 if (auto closure = isa_clos_lit(def, false)) {
68 auto fnc = closure.fnc();
69 if (!match<attr>(fnc)) {
70 auto new_fnc = world().call(esc_.contains(fnc) ? attr::esc : attr::bot, fnc);
71 return clos_pack(closure.env(), new_fnc, closure->type());
72 }
73 }
74 return def;
75}
76
78 auto& w = world();
79 if (auto c = isa_clos_lit(def, false)) {
80 w.DLOG("closure ({}, {})", c.env(), c.fnc());
81 if (!c.fnc_as_lam() || is_esc(c.fnc_as_lam()) || is_esc(c.env_var())) return set_esc(c.env());
82 } else if (auto store = match<mem::store>(def)) {
83 w.DLOG("store {}", store->arg(2));
84 return set_esc(store->arg(2));
85 } else if (auto app = def->isa<App>(); app && Pi::isa_cn(app->callee_type())) {
86 w.DLOG("app {}", def);
87 auto undo = No_Undo;
88 auto callees = split(app->callee(), true);
89 for (auto i = 0_u64; i < app->num_args(); i++) {
90 if (!interesting_type(app->arg(i))) continue;
91 if (std::any_of(callees.begin(), callees.end(), [&](Ref callee) {
92 if (auto lam = callee->isa_mut<Lam>()) return is_esc(lam->var(i));
93 return true;
94 }))
95 undo = std::min(undo, set_esc(app->arg(i)));
96 }
97 return undo;
98 }
99 return No_Undo;
100}
101
102} // namespace thorin::plug::clos
undo_t undo_visit(Def *mut) const
Retrieves the point to backtrack to just before mut was seen the very first time.
Definition pass.h:273
World & world()
Definition pass.h:296
static const Pi * isa_cn(Ref d)
Is this a continuation - i.e. is the Pi::codom thorin::Bottom?
Definition lam.h:50
Helper class to retrieve Infer::arg if present.
Definition def.h:87
const Def * call(Id id, Args &&... args)
Definition world.h:497
The clos Plugin
Definition clos.h:7
Ref clos_pack(Ref env, Ref fn, Ref ct=nullptr)
Pack a typed closure. This assumes that fn expects the environment as its Clos_Env_Paramth argument.
Definition clos.cpp:78
const Sigma * isa_clos_type(Ref def)
Returns def if def is a closure and nullptr otherwise.
Definition clos.cpp:111
ClosLit isa_clos_lit(Ref def, bool fn_isa_lam=true)
Tries to match a closure literal.
Definition clos.cpp:64
Ref op(trait o, Ref type)
Definition core.h:35
static constexpr undo_t No_Undo
Definition pass.h:15
GIDSet< const Def * > DefSet
Definition def.h:60
size_t undo_t
Definition pass.h:14