Skip to content
← Back

src/syntax/process/narrowing_study.ghul

1
namespace Syntax.Process is
2
use IO.Std
3
4
use Function = Semantic.Symbols.Function
5
use Symbol = Semantic.Symbols.Symbol
6
7
// Env-gated measurement reporting for the narrowing analysis.
8
//
9
// GHUL_NARROWING_STUDY names the file the report is written to;
10
// unset, nothing here runs. Reporting-only: nothing in this class
11
// alters what the compiler concludes or reports. The report has
12
// two sections - a tally of the opaque function-value shapes that
13
// make a parameter invocation unboundable, and a per-function
14
// table of the effect facts the solve worked from.
15
class NARROWING_STUDY is
16
17
_enabled: bool static
18
_enabled_known: bool static
19
20
// Path the report is written to, or null.
21
_path: string? static
22
23
enabled: bool static is
24
if !_enabled_known then
25
_path = System.Environment.get_environment_variable("GHUL_NARROWING_STUDY")
26
_enabled = _path? /\ _path.length > 0
27
_enabled_known = true
28
fi
29
30
return _enabled
31
si
32
33
// ==== opaque function-value shapes ====
34
//
35
// A function-typed argument whose value cannot be traced to a
36
// set of concrete functions makes the receiving parameter's
37
// invocation unboundable. The tally names the value shapes
38
// responsible, which is what argues for (or against) tracing
39
// more of them.
40
_opaque_shapes: Collections.MutableMap[string, int]? static
41
42
opaque_shapes: Collections.MutableMap[string, int] static is
43
if !_opaque_shapes? then
44
_opaque_shapes = Collections.MAP[string, int]()
45
fi
46
47
return _opaque_shapes
48
si
49
50
note_opaque_shape(shape: string) static is
51
if !enabled then
52
return
53
fi
54
55
if opaque_shapes.contains_key(shape) then
56
opaque_shapes[shape] = opaque_shapes[shape] + 1
57
else
58
opaque_shapes[shape] = 1
59
fi
60
si
61
62
report() static is
63
if !enabled \/ !_path? then
64
return
65
fi
66
67
try
68
let writer = IO.StreamWriter(_path)
69
70
for key in opaque_shapes.keys do
71
writer.write_line("opaque_shape\t{key}\t{opaque_shapes[key]}")
72
od
73
74
writer.write_line(
75
"# role\towner\tname\tstore_free\tdisqualified\taliased\t"
76
"own_stores\town_unbounded\tcallees\toverriders\topenly_dispatchable\t"
77
"declared_pure\treason\tlocation")
78
79
for function in EFFECT_FACTS.records.keys do
80
let r = EFFECT_FACTS.records[function]
81
82
writer.write_line(
83
"{r.role}\t{r.owner_name}\t{r.name}\t"
84
"{function.is_store_free}\t"
85
"{r.is_disqualified}\t{r.aliased}\t"
86
"{r.own_stores}\t{r.own_unbounded}\t{r.callee_count}\t{r.overrider_count}\t"
87
"{r.openly_dispatchable}\t{r.declared_pure}\t"
88
"{r.unbounded_reason}\t"
89
"{r.location}")
90
od
91
92
writer.flush()
93
writer.close()
94
catch ex: System.Exception
95
IO.Std.error.write_line("narrowing study: report failed: {ex}")
96
yrt
97
si
98
si
99
si