6 for (
auto def :
old_world().externals().muts())
12 if (
auto [_, ins] = analyzed_.emplace(def); !ins)
return;
14 if (
auto app = def->isa<
App>())
15 if (
auto lam = app->callee()->isa_mut<
Lam>(); lam && lam->
has_var()) visit(app, lam);
17 for (
auto d : def->
deps())
21void StaticArgOpt::visit(
const App* app, Lam* lam) {
22 auto mask = fe::Bitset();
23 for (
size_t i = 0, n = lam->num_tdoms(); i != n; ++i)
24 if (app->targ(i) == lam->tvar(i)) mask.set(i);
25 if (mask.any()) lam2sites_[lam].emplace_back(std::move(mask));
29 if (
auto s = fe::lookup(lam2sieve_, lam))
return *
s;
31 auto n = lam->num_tdoms();
34 auto i = lam2sites_.find(lam);
35 if (i == lam2sites_.end() || !lam->is_set() || !lam->is_closed() || lam->type()->isa_mut<Pi>())
36 return lam2sieve_.emplace(lam,
Sieve(n)).first->second;
38 const auto& sites = i->second;
42 auto pool = fe::Bitset(sites.size(),
true);
43 for (
size_t d = n;
d-- != 0;) {
44 if (!lam->tdom(d)->isa<Pi>())
continue;
46 for (
const auto& mask : sites)
49 for (
size_t s = 0, e = sites.size(); s != e; ++s)
50 pool.set(s, sites[s][d]);
54 auto statics = fe::Bitset(n,
true);
55 for (
size_t s = 0, e = sites.size(); s != e; ++s)
56 if (pool[s]) statics &= sites[
s];
57 if (statics.none())
return lam2sieve_.emplace(lam,
Sieve(n)).first->second;
59 log().d(
"statics of {}: {}", lam, statics);
60 return lam2sieve_.emplace(lam,
Sieve(n, [&statics](
size_t d) {
return !statics[
d]; })).
first->second;
64 auto sieve = this->sieve(old_lam);
69 auto loop_doms =
rewrite(sieve.gather(old_lam->
tdoms()));
73 loop->debug_suffix(
"_loop");
74 log().d(
"{} → wrap {}, loop {}", old_lam, wrap, loop);
75 old2loop_[old_lam] = loop;
78 auto vars =
DefVec(n, [&](
size_t d) {
80 return j ==
Sieve::Gone ? wrap->tvar(d) : loop->var(sieve.num_new(), j);
86 wrap->app(
false, loop, sieve.gather(wrap->tvars()));
92 if (
auto sieve = this->sieve(old_lam); !sieve.all()) {
94 if (
auto loop = fe::lookup(old2loop_, old_lam)) {
95 for (
size_t d = 0, n = old_lam->num_tdoms(); d != n; ++d)
auto targs(Projector auto f) const noexcept
const Def * callee() const
const Def * targ(nat_t i) const noexcept
Defs deps() const noexcept
const Def * tvar(nat_t i) noexcept
T * isa_mut() const
If this is mutable, it will cast constness away and perform a dynamic_cast to T.
DbgKey dbg_key() const
Cheap handle for other->set(this->dbg_key()).
const Def * var(nat_t a, nat_t i) noexcept
const Var * has_var()
Only returns not nullptr, if Var of this mutable has ever been created.
const Def * filter() const
nat_t num_tdoms() const noexcept
auto tdoms(Projector auto f) const noexcept
const Def * codom() const
void invalidate(bool todo=true)
Signals that another round of fixed-point iteration is required, either as part of.
const fe::Log & log() const
A dependent function type.
World & new_world()
Create new Defs into this.
World & old_world()
Get old Defs from here.
const Def * rewrite_imm_App(const App *) override
const Def * map(const Def *old_def, const Def *new_def)
virtual const Def * rewrite_mut_Lam(Lam *)
virtual const Def * rewrite(const Def *)
Filters the components of an aggregate and keeps track of where the survivors end up.
static constexpr size_t Gone
const Def * rewrite_mut_Lam(Lam *) final
bool analyze() final
Runs the optional pre-analysis on old_world(), typically to a fixed point, before rewriting begins.
const Def * rewrite_imm_App(const App *) final
const Def * app(const Def *callee, const Def *arg)
fe::Vector< const Def * > DefVec