Skip to content

Commit 1dcef2a

Browse files
committed
Add images too
1 parent b08f051 commit 1dcef2a

File tree

3 files changed

+20
-16
lines changed

3 files changed

+20
-16
lines changed

src/img/region-graphviz.png

33.7 KB
Loading

src/img/scc-graphviz.png

42 KB
Loading

src/mir/dataflow.md

+20-16
Original file line numberDiff line numberDiff line change
@@ -25,24 +25,23 @@ for the alternative lectures.
2525
## Defining a Dataflow Analysis
2626

2727
The interface for dataflow analyses is split into three traits. The first is
28-
[`AnalysisDomain`], which must be implemented by *all* analyses. In addition to
28+
[`AnalysisDomain`], which must be implemented by _all_ analyses. In addition to
2929
the type of the dataflow state, this trait defines the initial value of that
3030
state at entry to each block, as well as the direction of the analysis, either
3131
forward or backward. The domain of your dataflow analysis must be a [lattice][]
3232
(strictly speaking a join-semilattice) with a well-behaved `join` operator. See
3333
documentation for the [`lattice`] module, as well as the [`JoinSemiLattice`]
3434
trait, for more information.
3535

36-
You must then provide *either* a direct implementation of the [`Analysis`] trait
37-
*or* an implementation of the proxy trait [`GenKillAnalysis`]. The latter is for
36+
You must then provide _either_ a direct implementation of the [`Analysis`] trait
37+
_or_ an implementation of the proxy trait [`GenKillAnalysis`]. The latter is for
3838
so-called ["gen-kill" problems], which have a simple class of transfer function
3939
that can be applied very efficiently. Analyses whose domain is not a `BitSet`
4040
of some index type, or whose transfer functions cannot be expressed through
4141
"gen" and "kill" operations, must implement `Analysis` directly, and will run
4242
slower as a result. All implementers of `GenKillAnalysis` also implement
4343
`Analysis` automatically via a default `impl`.
4444

45-
4645
```text
4746
AnalysisDomain
4847
^
@@ -77,7 +76,7 @@ and `kill` operations for mutation.
7776

7877
### "Before" Effects
7978

80-
Observant readers of the documentation may notice that there are actually *two*
79+
Observant readers of the documentation may notice that there are actually _two_
8180
possible effects for each statement and terminator, the "before" effect and the
8281
unprefixed (or "primary") effect. The "before" effects are applied immediately
8382
before the unprefixed effect **regardless of the direction of the analysis**.
@@ -99,17 +98,18 @@ In order to reach equilibrium, your analysis must obey some laws. One of the
9998
laws it must obey is that the bottom value[^bottom-purpose] joined with some
10099
other value equals the second value. Or, as an equation:
101100

102-
> *bottom* join *x* = *x*
101+
> _bottom_ join _x_ = _x_
103102
104103
Another law is that your analysis must have a "top value" such that
105104

106-
> *top* join *x* = *top*
105+
> _top_ join _x_ = _top_
107106
108107
Having a top value ensures that your semilattice has a finite height, and the
109108
law state above ensures that once the dataflow state reaches top, it will no
110109
longer change (the fixpoint will be top).
111110

112-
[^bottom-purpose]: The bottom value's primary purpose is as the initial dataflow
111+
[^bottom-purpose]:
112+
The bottom value's primary purpose is as the initial dataflow
113113
state. Each basic block's entry state is initialized to bottom before the
114114
analysis starts.
115115

@@ -151,7 +151,7 @@ Calling `iterate_to_fixpoint` on your `Engine` will return a `Results`, which
151151
contains the dataflow state at fixpoint upon entry of each block. Once you have
152152
a `Results`, you can inspect the dataflow state at fixpoint at any point in
153153
the CFG. If you only need the state at a few locations (e.g., each `Drop`
154-
terminator) use a [`ResultsCursor`]. If you need the state at *every* location,
154+
terminator) use a [`ResultsCursor`]. If you need the state at _every_ location,
155155
a [`ResultsVisitor`] will be more efficient.
156156

157157
```text
@@ -172,7 +172,6 @@ a [`ResultsVisitor`] will be more efficient.
172172

173173
For example, the following code uses a [`ResultsVisitor`]...
174174

175-
176175
```rust,ignore
177176
// Assuming `MyVisitor` implements `ResultsVisitor<FlowState = MyAnalysis::Domain>`...
178177
let mut my_visitor = MyVisitor::new();
@@ -212,25 +211,30 @@ either "all" or the name of the MIR body you are interested in.
212211
These `.dot` files will be saved in your `mir_dump` directory and will have the
213212
[`NAME`] of the analysis (e.g. `maybe_inits`) as part of their filename. Each
214213
visualization will display the full dataflow state at entry and exit of each
215-
block, as well as any changes that occur in each statement and terminator. See
214+
block, as well as any changes that occur in each statement and terminator. See
216215
the example below:
217216

218217
![A graphviz diagram for a dataflow analysis](../img/dataflow-graphviz-example.png)
219218

220219
### Region Constraint Graphs and Their Strongly Connected Components
221220

221+
![A graph showing a small number of regions with their outlives relations](../img/region-graphviz.png)
222+
222223
With `-Z dump-mir-graphviz=yes`, you will also get Graphviz files for the outlives constraints
223224
of the MIR bodies you asked for, as well as the strongly connected components (SCCs) on them.
224-
They are available as
225+
They are available as
225226
`mir_dump/rs-file-name.function-name.-------.nll.0.regioncx.all.dot` and
226227
`mir_dump/rs-file-name.function-name.-------.nll.0.regioncx.scc.dot` respectively. For both
227228
graphs, named region variables will be shown with their external name (such as `'static`)
228229
shown in parenthesis. For region inference variables in universes other than the root universe,
229-
they will be shown as `/U13` (for universe 13). In the region graph, edges are labelled with
230-
the MIR locations where the relationship holds.
230+
they will be shown as `/U13` (for universe 13). In the region graph, edges are labelled with
231+
the MIR locations where the relationship holds, or `All` if it's everywhere.
232+
233+
![A graph showing a small number of strongly connected components on the region-outlives-graph above](../img/scc-graphviz.png)
231234

232-
**Note:** there are implicit edges from `'static` to every region, but those are not rendered
233-
in the region graph to avoid clutter. They *do* however show up in the SCC graph.
235+
**Note:** There are implicit edges from `'static` to every region, but those are not rendered
236+
in the region graph to avoid clutter. They _do_ however show up in the SCC graph. This is why there are outgoing edges from SCC(5) in the SCC graph above
237+
that do not seem to have corresponding edges in the region outlives graph above.
234238

235239
["gen-kill" problems]: https://en.wikipedia.org/wiki/Data-flow_analysis#Bit_vector_problems
236240
[*Static Program Analysis*]: https://cs.au.dk/~amoeller/spa/

0 commit comments

Comments
 (0)