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) {
22 if (
scope().bound(op)) {
24 if (
auto [_, ins] = done.emplace(op); ins) queue.push(op);
28 for (
auto n :
cfg().reverse_post_order()) {
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));
49Def* Scheduler::early(
const Def* def) {
50 if (
auto i = early_.find(def); i != early_.end())
return i->second;
51 if (def->
dep_const() || !scope().bound(def))
return early_[def] = scope().entry();
52 if (
auto var = def->isa<
Var>())
return early_[def] = var->mut();
54 auto result = scope().entry();
56 if (!op->
isa_mut() && def2uses_.find(op) != def2uses_.end()) {
58 if (domtree().depth(cfg(mut)) > domtree().depth(cfg(result))) result = mut;
62 return early_[def] = result;
auto assert_emplace(C &container, Args &&... args)
Invokes emplace on container, asserts that insertion actually happened, and returns the iterator.