17 : world_(entry->world())
19 , exit_(world().exit()) {
28 if (
auto var = entry_->
has_var()) {
31 while (!queue.empty()) {
32 for (
auto use : queue.pop()->uses())
33 if (use != entry_ && use != exit_) queue.push(use);
38void Scope::calc_bound()
const {
39 if (has_bound_)
return;
43 unique_queue<DefSet&> queue(live);
45 auto enqueue = [&](
const Def* def) {
46 if (def ==
nullptr)
return;
47 if (def->dep_const())
return;
49 if (bound_.contains(def))
52 free_defs_.emplace(def);
55 for (
auto op :
entry()->partial_ops()) enqueue(op);
57 while (!queue.empty())
58 for (
auto op : queue.pop()->partial_ops()) enqueue(op);
63void Scope::calc_free()
const {
64 if (has_free_)
return;
67 unique_queue<DefSet> queue;
69 auto enqueue = [&](
const Def* def) {
70 if (def->dep_const())
return;
72 if (
auto var = def->isa<
Var>())
73 free_vars_.emplace(var);
74 else if (
auto mut = def->isa_mut())
75 free_muts_.emplace(mut);
80 for (
auto free :
free_defs()) enqueue(free);
82 while (!queue.empty())
83 for (
auto op : queue.pop()->extended_ops()) enqueue(op);
91 if (
auto v = mut->
var()) {
92 if (
auto var = v->isa<
Var>()) {
94 if (def->
num_ops() == 0)
return false;
95 if (var == def)
return true;
96 for (
auto v : var->mut()->tvars())
97 if (v == def)
return true;
100 return scope.
bound(def);
const B_CFG & b_cfg() const
const F_CFG & f_cfg() const
Ref var(nat_t a, nat_t i)
const Var * has_var()
Only returns not nullptr, if Var of this mutable has ever been created.
A Scope represents a region of Defs that are live from the view of an entry's Var.
Scope(const Scope &)=delete
const B_CFG & b_cfg() const
const DefSet & free_defs() const
All non-const Defs directly referenced but not bound within this Scope. May also include Vars or muts...
const F_CFG & f_cfg() const
static bool is_free(Def *mut, const Def *def)
Does mut's Var occurr free in def?
bool bound(const Def *def) const
T & lazy_init(const This *self, std::unique_ptr< T > &ptr)
GIDSet< const Def * > DefSet