16 , cfg_(&scope().f_cfg())
17 , domtree_(&cfg().domtree()) {
18 std::queue<const Def*> queue;
21 auto enqueue = [&](
const Def* def,
size_t i,
const Def* op) {
24 if (
auto [_, ins] = done.emplace(op); ins) queue.push(op);
33 while (!queue.empty()) {
34 auto def = queue.front();
37 if (!def->
is_set())
continue;
39 for (
size_t i = 0, e = def->
num_ops(); i != e; ++i) {
42 if (!def->
op(i)->
isa_mut()) enqueue(def, i, def->
op(i));
50 if (
auto i = early_.find(def); i != early_.end())
return i->second;
52 if (
auto var = def->isa<
Var>())
return early_[def] = var->mut();
56 if (!op->
isa_mut() && def2uses_.find(op) != def2uses_.end()) {
62 return early_[def] = result;
66 if (
auto i = late_.find(def); i != late_.end())
return i->second;
69 Def* result =
nullptr;
70 if (
auto mut = def->
isa_mut()) {
72 }
else if (
auto var = def->isa<
Var>()) {
75 for (
auto use :
uses(def)) {
81 return late_[def] = result;
85 if (
auto i = smart_.find(def); i != smart_.end())
return i->second;
92 for (
auto i = l; i != e;) {
98 scope_->
world().WLOG(
"this should never occur - don't know where to put {}", def);
103 if (
int cur_depth =
cfg().looptree()[i]->depth(); cur_depth < depth) {
109 return smart_[def] = s->mut();
const LoopTree< forward > & looptree() const
auto reverse_post_order() const
Defs extended_ops() const
bool is_set() const
Yields true if empty or the last op is set.
const Def * op(size_t i) const
const Def * type() const
Yields the raw type of this Def, i.e. maybe nullptr.
T * isa_mut() const
If this is *mut*able, it will cast constness away and perform a dynamic_cast to T.
const CFNode * idom(const CFNode *n) const
const CFNode * least_common_ancestor(const CFNode *i, const CFNode *j) const
Returns the least common ancestor of i and j.
const Uses & uses(const Def *def) const
const Scope & scope() const
std::vector< Def * > Schedule
const F_CFG & cfg() const
const DomTree & domtree() const
static Schedule schedule(const Scope &)
A Scope represents a region of Defs that are live from the view of an entry's Var.
const F_CFG & f_cfg() const
bool bound(const Def *def) const
GIDSet< const Def * > DefSet
auto assert_emplace(C &container, Args &&... args)
Invokes emplace on container, asserts that insertion actually happened, and returns the iterator.