9bool interesting_type(Ref type,
DefSet& visited) {
10 if (type->isa_mut()) visited.insert(type);
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);
19bool interesting_type(Ref def) {
21 return interesting_type(def->type(), visited);
24void split(
DefSet& out, Ref def,
bool as_callee) {
25 if (
auto lam = def->isa<Lam>()) {
28 if (var->type()->isa<Pi>() || interesting_type(var)) out.insert(var);
30 split(out,
c.fnc(), as_callee);
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) {
44DefSet split(Ref def,
bool keep_others) {
46 split(out, def, keep_others);
52undo_t LowerTypedClosPrep::set_esc(Ref def) {
54 for (
auto d : split(def,
false)) {
55 if (is_esc(d))
continue;
56 if (
auto lam =
d->isa_mut<Lam>())
60 world().DLOG(
"set esc: {}", d);
68 auto fnc = closure.fnc();
71 return clos_pack(closure.env(), new_fnc, closure->type());
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());
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);
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));
95 undo = std::min(undo, set_esc(app->arg(i)));
undo_t undo_visit(Def *mut) const
static const Pi * isa_cn(Ref d)
Is this a continuation - i.e. is the Pi::codom mim::Bottom?
Helper class to retrieve Infer::arg if present.
const Def * call(Id id, Args &&... args)
undo_t analyze(Ref) override
Ref rewrite(Ref) override
ClosLit isa_clos_lit(Ref def, bool fn_isa_lam=true)
Tries to match a closure literal.
const Sigma * isa_clos_type(Ref def)
std::tuple< const Extract *, N * > ca_isa_var(Ref def)
Checks is def is the variable of a mut of type N.
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.
GIDSet< const Def * > DefSet
static constexpr undo_t No_Undo