MimIR
0.4-dev
MimIR is my Intermediate Representation
Toggle main menu visibility
Loading...
Searching...
No Matches
schedule.cpp
Go to the documentation of this file.
1
#include "
mim/schedule.h
"
2
3
#include <fe/container.h>
4
#include <fe/worklist.h>
5
6
#include "
mim/world.h
"
7
8
namespace
mim
{
9
10
Scheduler::Scheduler
(
const
Nest
&
nest
)
11
: nest_(&
nest
) {
12
auto
queue = fe::BFSWorklist<DefSet>();
13
14
auto
enqueue = [&](
const
Def
* def,
size_t
i,
const
Def
* op) {
15
if
(
nest
.
contains
(op)) {
16
fe::assert_emplace(def2uses_[op], def, i);
17
queue.push(op);
18
}
19
};
20
21
queue.push(
nest
.
muts
());
22
23
while
(!queue.empty()) {
24
auto
def = queue.pop();
25
26
if
(!def->
is_set
())
continue
;
27
28
for
(
size_t
i = 0, e = def->
num_ops
(); i != e; ++i) {
29
// all reachable muts have already been registered above
30
// NOTE we might still see references to unreachable muts in the schedule
31
if
(!def->
op
(i)->
isa_mut
()) enqueue(def, i, def->
op
(i));
32
}
33
34
if
(!def->
type
()->
isa_mut
()) enqueue(def, -1, def->
type
());
35
}
36
}
37
38
const
Nest::Node
*
Scheduler::early
(
const
Def
* def) {
39
if
(
auto
i = early_.find(def); i != early_.end())
return
i->second;
40
if
(def->
is_closed
() || !
nest
().contains(def))
return
early_[def] =
nest
().
root
();
41
if
(
auto
var = def->isa<
Var
>())
return
early_[def] =
nest
()[var->binder()];
42
43
auto
result =
nest
().
root
();
44
for
(
auto
op : def->
deps
()) {
45
if
(!op->isa_mut() &&
nest
().contains(op)) {
46
auto
node =
early
(op);
47
if
(node->level() > result->level()) result = node;
48
}
49
}
50
51
return
early_[def] = result;
52
}
53
54
const
Nest::Node
*
Scheduler::late
(
Def
* curr_mut,
const
Def
* def) {
55
if
(
auto
i = late_.find(def); i != late_.end())
return
i->second;
56
if
(def->
is_closed
() || !
nest
().contains(def))
return
late_[def] =
nest
().
root
();
57
58
const
Nest::Node
* result =
nullptr
;
59
if
(
auto
mut = def->
isa_mut
()) {
60
result =
nest
()[mut];
61
}
else
if
(
auto
var = def->isa<
Var
>()) {
62
result =
nest
()[var->binder()];
63
}
else
{
64
for
(
auto
use :
uses
(def)) {
65
auto
mut =
late
(curr_mut, use);
66
result = result ?
Nest::lca
(result, mut) : mut;
67
}
68
}
69
70
if
(!result) result =
nest
()[curr_mut];
71
72
return
late_[def] = result;
73
}
74
75
const
Nest::Node
*
Scheduler::smart
(
Def
* curr_mut,
const
Def
* def) {
76
if
(
auto
i = smart_.find(def); i != smart_.end())
return
i->second;
77
78
auto
e =
early
(def);
79
auto
l =
late
(curr_mut, def);
80
auto
s = l;
81
82
int
depth = l->loop_depth();
83
for
(
auto
i = l; i != e;) {
84
i = i->inest();
85
86
if
(i ==
nullptr
) {
87
world
().
log
().e(
"no place found for {}"
, def);
88
s = l;
89
break
;
90
}
91
92
if
(
int
curr_depth = i->loop_depth(); curr_depth < depth) {
93
s = i;
94
depth = curr_depth;
95
}
96
}
97
98
return
smart_[def] = s;
99
}
100
101
static
void
post_order
(
const
Nest
& nest,
const
Nest::Node
* node,
Scheduler::Schedule
& res,
MutSet
& done) {
102
// The mut of a virtual root is a nullptr
103
if
(!node->
mut
()) {
104
for
(
auto
child : node->
children
().
nodes
())
105
post_order
(nest, child, res, done);
106
return
;
107
}
108
109
if
(!node->
mut
()->isa<
Lam
>())
return
;
110
if
(
auto
[_, ins] = done.emplace(node->
mut
()); !ins)
return
;
111
112
for
(
auto
op : node->
mut
()->
deps
()) {
113
for
(
auto
mut : op->local_muts())
114
if
(
auto
next = nest[mut])
post_order
(nest, next, res, done);
115
}
116
117
res.emplace_back(node->
mut
());
118
}
119
120
// until we have sth better ...
121
Scheduler::Schedule
Scheduler::schedule
(
const
Nest
&
nest
) {
122
Schedule
schedule
;
123
MutSet
done;
124
post_order
(
nest
,
nest
.
root
(),
schedule
, done);
125
std::ranges::reverse(
schedule
);
// post-order → reverse post-order
126
return
schedule
;
127
}
128
129
}
// namespace mim
mim::Def
Base class for all Defs.
Definition
def.h:273
mim::Def::is_set
bool is_set() const
Definition
def.h:370
mim::Def::deps
Defs deps() const noexcept
Definition
def.cpp:468
mim::Def::isa_mut
T * isa_mut() const
If this is mutable, it will cast constness away and perform a dynamic_cast to T.
Definition
def.h:580
mim::Def::op
const Def * op(size_t i) const noexcept
Definition
def.h:351
mim::Def::type
const Def * type() const noexcept
Yields the "raw" type of this Def (maybe nullptr).
Definition
def.h:1111
mim::Def::is_closed
bool is_closed() const
Same as !has_free_vars().
Definition
def.cpp:353
mim::Def::num_ops
constexpr size_t num_ops() const noexcept
Definition
def.h:352
mim::Lam
A function.
Definition
lam.h:113
mim::Nest::Node
Definition
nest.h:33
mim::Nest::Node::mut
Def * mut() const
The mutable capsulated in this Node or nullptr, if it's a virtual root comprising several Nodes.
Definition
nest.h:46
mim::Nest::Node::children
const Children & children() const
Definition
nest.h:95
mim::Nest
Builds a nesting tree for all mutables/binders.
Definition
nest.h:31
mim::Nest::lca
static const Node * lca(const Node *n, const Node *m)
Least common ancestor of n and m.
Definition
nest.cpp:107
mim::Nest::muts
auto muts() const
Definition
nest.h:234
mim::Nest::root
const Node * root() const
Definition
nest.h:224
mim::Nest::contains
bool contains(const Def *def) const
Definition
nest.h:226
mim::Scheduler::smart
const Nest::Node * smart(Def *curr, const Def *)
Definition
schedule.cpp:75
mim::Scheduler::Schedule
fe::Vector< Def * > Schedule
Definition
schedule.h:79
mim::Scheduler::late
const Nest::Node * late(Def *curr, const Def *)
Definition
schedule.cpp:54
mim::Scheduler::uses
const Uses & uses(const Def *def) const
Definition
schedule.h:63
mim::Scheduler::schedule
static Schedule schedule(const Nest &)
Definition
schedule.cpp:121
mim::Scheduler::world
World & world()
Definition
schedule.h:60
mim::Scheduler::nest
const Nest & nest() const
Definition
schedule.h:61
mim::Scheduler::early
const Nest::Node * early(const Def *)
Definition
schedule.cpp:38
mim::Scheduler::Scheduler
Scheduler()=default
mim::Var
A variable introduced by a binder (mutable).
Definition
def.h:825
mim::World::log
const fe::Log & log() const
Log via log().e("...", args) etc.; owned by the Driver.
Definition
world.cpp:129
mim
Definition
ast.h:16
mim::MutSet
GIDSet< Def * > MutSet
Definition
def.h:101
mim::post_order
static void post_order(const Nest &nest, const Nest::Node *node, Scheduler::Schedule &res, MutSet &done)
Definition
schedule.cpp:101
schedule.h
mim::Nest::Node::Children::nodes
auto nodes() const
Definition
nest.h:65
world.h
src
mim
schedule.cpp
Generated by
1.18.0