Skip to content
← Back

src/syntax/process/infer-effects/effect_dependants.ghul

1
namespace Syntax.Process is
2
use Function = Semantic.Symbols.Function
3
4
// The reverse of the dispatch edges the effect solvers propagate
5
// along: for each target, the walked functions whose relations
6
// absorb it - its callers, the functions it is passed to as a
7
// value, and the function it overrides. A solver seeds every row
8
// once, then re-absorbs a target only into the rows that depend
9
// on it, whenever that target's row changes.
10
class EFFECT_DEPENDANTS is
11
_dependants: Collections.MutableMap[Function, Collections.MutableList[Function]]
12
13
// The rows reading an unwalked target's in-assembly overriders
14
// through it, kept apart: only the store-free relation looks
15
// through an unwalked target.
16
_through_unwalked: Collections.MutableMap[Function, Collections.MutableList[Function]]
17
18
init(
19
facts: Collections.MutableMap[Function, STORE_FREE_FACTS],
20
param_invokers: Collections.SET[Function]
21
) is
22
_dependants = Collections.MAP[Function, Collections.MutableList[Function]]()
23
_through_unwalked = Collections.MAP[Function, Collections.MutableList[Function]]()
24
25
for function in facts.keys do
26
for callee in facts[function].callees do
27
_add(callee, function, facts)
28
od
29
30
for callee in facts[function].construction_callees do
31
_add(callee, function, facts)
32
od
33
34
if param_invokers.contains(function) then
35
let passed = EFFECT_FACTS.passed_functions_for(function)
36
37
if passed? then
38
for value in passed do
39
_add(value, function, facts)
40
od
41
fi
42
fi
43
44
let overriders = function.overriders
45
46
if overriders? then
47
for overrider in overriders do
48
if isa Function(overrider) then
49
_add(cast Function(overrider), function, facts)
50
fi
51
od
52
fi
53
od
54
si
55
56
// A target not walked here is judged by its declaration and
57
// never changes, but its in-assembly overriders have rows of
58
// their own that the store-free relation reads through it.
59
_add(
60
target: Function,
61
dependant: Function,
62
facts: Collections.MutableMap[Function, STORE_FREE_FACTS]
63
) is
64
_add_edge(_dependants, target, dependant)
65
66
if facts.contains_key(target) then
67
return
68
fi
69
70
let overriders = target.overriders
71
72
if overriders? then
73
for overrider in overriders do
74
if isa Function(overrider) then
75
_add_edge(_through_unwalked, cast Function(overrider), dependant)
76
fi
77
od
78
fi
79
si
80
81
_add_edge(
82
map: Collections.MutableMap[Function, Collections.MutableList[Function]],
83
target: Function,
84
dependant: Function
85
) static is
86
if !map.contains_key(target) then
87
map[target] = Collections.LIST[Function]()
88
fi
89
90
map[target].add(dependant)
91
si
92
93
// The rows that absorb `target` directly.
94
dependants_of(target: Function) -> Collections.Iterable[Function]? is
95
if _dependants.contains_key(target) then
96
return _dependants[target]
97
fi
98
99
return null
100
si
101
102
// The rows that read `target` as an overrider of an unwalked
103
// callee of theirs.
104
dependants_through_unwalked(target: Function) -> Collections.Iterable[Function]? is
105
if _through_unwalked.contains_key(target) then
106
return _through_unwalked[target]
107
fi
108
109
return null
110
si
111
si
112
si