MimIR
0.5-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
for
(
auto
mut :
nest
.
muts
())
22
if
(mut) queue.push(mut);
23
24
while
(!queue.empty()) {
25
auto
def = queue.pop();
26
27
if
(!def->
is_set
())
continue
;
28
29
for
(
size_t
i = 0, e = def->
num_ops
(); i != e; ++i) {
30
// all reachable muts have already been registered above
31
// NOTE we might still see references to unreachable muts in the schedule
32
if
(!def->
op
(i)->
isa_mut
()) enqueue(def, i, def->
op
(i));
33
}
34
35
if
(!def->
type
()->
isa_mut
()) enqueue(def, -1, def->
type
());
36
}
37
}
38
39
const
Nest::Node
*
Scheduler::early
(
const
Def
* def) {
40
if
(
auto
n = fe::lookup(early_, def))
return
n;
41
if
(def->
is_closed
() || !
nest
().contains(def))
return
early_[def] =
nest
().
root
();
42
if
(
auto
var = def->isa<
Var
>())
return
early_[def] =
nest
()[var->binder()];
43
44
auto
result =
nest
().
root
();
45
for
(
auto
op : def->
deps
()) {
46
if
(!op->isa_mut() &&
nest
().contains(op)) {
47
auto
node =
early
(op);
48
if
(node->level() > result->level()) result = node;
49
}
50
}
51
52
return
early_[def] = result;
53
}
54
55
const
Nest::Node
*
Scheduler::late
(
Def
* curr_mut,
const
Def
* def) {
56
if
(
auto
n = fe::lookup(late_, def))
return
n;
57
if
(def->
is_closed
() || !
nest
().contains(def))
return
late_[def] =
nest
().
root
();
58
59
const
Nest::Node
* result =
nullptr
;
60
if
(
auto
mut = def->
isa_mut
()) {
61
result =
nest
()[mut];
62
}
else
if
(
auto
var = def->isa<
Var
>()) {
63
result =
nest
()[var->binder()];
64
}
else
{
65
for
(
auto
use :
uses
(def)) {
66
auto
mut =
late
(curr_mut, use);
67
result = result ?
Nest::lca
(result, mut) : mut;
68
}
69
}
70
71
if
(!result) result =
nest
()[curr_mut];
72
73
return
late_[def] = result;
74
}
75
76
const
Nest::Node
*
Scheduler::smart
(
Def
* curr_mut,
const
Def
* def) {
77
if
(
auto
n = fe::lookup(smart_, def))
return
n;
78
79
auto
e =
early
(def);
80
auto
l =
late
(curr_mut, def);
81
auto
s = l;
82
83
int
depth = l->loop_depth();
84
for
(
auto
i = l; i != e;) {
85
i = i->inest();
86
87
if
(i ==
nullptr
) {
88
world
().
log
().e(
"no place found for {}"
, def);
89
s = l;
90
break
;
91
}
92
93
if
(
int
curr_depth = i->loop_depth(); curr_depth < depth) {
94
s = i;
95
depth = curr_depth;
96
}
97
}
98
99
return
smart_[def] = s;
100
}
101
102
// until we have sth better ...
103
Scheduler::Schedule
Scheduler::schedule
(
const
Nest
&
nest
) {
104
auto
in_nest = [&
nest
](
Def
* mut) {
return
nest
[mut] !=
nullptr
; };
105
auto
done =
MutSet
();
106
auto
schedule
=
Schedule
();
107
108
// The mut of a virtual root is a nullptr.
109
if
(
auto
root
=
nest
.
root
()->
mut
())
110
post_order
(
root
, done,
schedule
, in_nest, in_nest);
111
else
112
for
(
auto
mut :
nest
.
root
()->
children
().
muts
())
113
post_order
(mut, done,
schedule
, in_nest, in_nest);
114
115
std::ranges::reverse(
schedule
);
// post-order → reverse post-order
116
return
schedule
;
117
}
118
119
}
// namespace mim
mim::Def
Base class for all Defs.
Definition
def.h:289
mim::Def::is_set
bool is_set() const
Definition
def.h:396
mim::Def::deps
Defs deps() const noexcept
Definition
def.cpp:486
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:588
mim::Def::op
const Def * op(size_t i) const noexcept
Definition
def.h:377
mim::Def::type
const Def * type() const noexcept
Yields the "raw" type of this Def (maybe nullptr).
Definition
def.h:1119
mim::Def::is_closed
bool is_closed() const
Same as !has_free_vars().
Definition
def.cpp:357
mim::Def::num_ops
constexpr size_t num_ops() const noexcept
Definition
def.h:378
mim::Nest::Node
Definition
nest.h:27
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:39
mim::Nest::Node::children
const Children & children() const
Definition
nest.h:82
mim::Nest
Builds a nesting tree for all mutables/binders.
Definition
nest.h:25
mim::Nest::lca
static const Node * lca(const Node *n, const Node *m)
Least common ancestor of n and m.
Definition
nest.cpp:174
mim::Nest::muts
auto muts() const
Definition
nest.h:204
mim::Nest::root
const Node * root() const
Definition
nest.h:195
mim::Nest::contains
bool contains(const Def *def) const
Definition
nest.h:197
mim::Scheduler::root
Def * root() const
Definition
schedule.h:61
mim::Scheduler::smart
const Nest::Node * smart(Def *curr, const Def *)
Definition
schedule.cpp:76
mim::Scheduler::Schedule
fe::Vector< Def * > Schedule
Definition
schedule.h:78
mim::Scheduler::late
const Nest::Node * late(Def *curr, const Def *)
Definition
schedule.cpp:55
mim::Scheduler::uses
const Uses & uses(const Def *def) const
Definition
schedule.h:62
mim::Scheduler::schedule
static Schedule schedule(const Nest &)
Definition
schedule.cpp:103
mim::Scheduler::world
World & world()
Definition
schedule.h:59
mim::Scheduler::nest
const Nest & nest() const
Definition
schedule.h:60
mim::Scheduler::early
const Nest::Node * early(const Def *)
Definition
schedule.cpp:39
mim::Scheduler::Scheduler
Scheduler()=default
mim::Var
A variable introduced by a binder (mutable).
Definition
def.h:857
mim::World::log
const fe::Log & log() const
Log via log().e("...", args) etc.; owned by the Driver.
Definition
world.cpp:224
mim
Definition
ast.h:16
mim::post_order
void post_order(Def *mut, MutSet &done, fe::Vector< Def * > &res, MutPred auto descend, MutPred auto collect)
Appends the mutables reachable from mut via Def::deps / Def::local_muts to res in post-order: callees...
Definition
def.h:1155
mim::MutSet
GIDSet< Def * > MutSet
Definition
def.h:106
schedule.h
mim::Nest::Node::Children::muts
auto muts() const
Definition
nest.h:56
world.h
src
mim
schedule.cpp
Generated by
1.18.0