|
1 | 1 | # Dataflow Analysis
|
2 | 2 |
|
3 | 3 | If you work on the MIR, you will frequently come across various flavors of
|
4 |
| -[dataflow analysis][wiki]. For example, `rustc` uses dataflow to find |
5 |
| -uninitialized variables, determine what variables are live across a generator |
6 |
| -`yield` statement, and compute which `Place`s are borrowed at a given point in |
7 |
| -the control-flow graph. Dataflow analysis is a fundamental concept in modern |
| 4 | +[dataflow analysis][wiki]. `rustc` uses dataflow to find uninitialized |
| 5 | +variables, determine what variables are live across a generator `yield` |
| 6 | +statement, and compute which `Place`s are borrowed at a given point in the |
| 7 | +control-flow graph. Dataflow analysis is a fundamental concept in modern |
8 | 8 | compilers, and knowledge of the subject will be helpful to prospective
|
9 | 9 | contributors.
|
10 | 10 |
|
11 | 11 | However, this documentation is not a general introduction to dataflow analysis.
|
12 | 12 | It is merely a description of the framework used to define these analyses in
|
13 |
| -`rustc`. It assumes that the reader is familiar with some basic terminology, |
14 |
| -such as "transfer function", "fixpoint" and "lattice". If you're unfamiliar |
15 |
| -with these terms, or if you want a quick refresher, [*Static Program Analysis*] |
16 |
| -by Anders Møller and Michael I. Schwartzbach is an excellent, freely available |
17 |
| -textbook. For those who prefer audiovisual learning, the Goethe University |
18 |
| -Frankfurt has published a series of short [youtube lectures][goethe] in English |
19 |
| -that are very approachable. |
| 13 | +`rustc`. It assumes that the reader is familiar with the core ideas as well as |
| 14 | +some basic terminology, such as "transfer function", "fixpoint" and "lattice". |
| 15 | +If you're unfamiliar with these terms, or if you want a quick refresher, |
| 16 | +[*Static Program Analysis*] by Anders Møller and Michael I. Schwartzbach is an |
| 17 | +excellent, freely available textbook. For those who prefer audiovisual |
| 18 | +learning, the Goethe University Frankfurt has published a series of short |
| 19 | +[lectures on YouTube][goethe] in English that are very approachable. |
20 | 20 |
|
21 | 21 | ## Defining a Dataflow Analysis
|
22 | 22 |
|
@@ -56,31 +56,36 @@ slower as a result. All implementers of `GenKillAnalysis` also implement
|
56 | 56 |
|
57 | 57 | ### Transfer Functions and Effects
|
58 | 58 |
|
59 |
| -The dataflow framework in `rustc` allows each statement inside a basic block as |
60 |
| -well as the terminator to define its own transfer function. For brevity, these |
| 59 | +The dataflow framework in `rustc` allows each statement (and terminator) inside |
| 60 | +a basic block define its own transfer function. For brevity, these |
61 | 61 | individual transfer functions are known as "effects". Each effect is applied
|
62 | 62 | successively in dataflow order, and together they define the transfer function
|
63 | 63 | for the entire basic block. It's also possible to define an effect for
|
64 | 64 | particular outgoing edges of some terminators (e.g.
|
65 | 65 | [`apply_call_return_effect`] for the `success` edge of a `Call`
|
66 |
| -terminator). Collectively, these are known as per-edge effects. |
| 66 | +terminator). Collectively, these are referred to as "per-edge effects". |
67 | 67 |
|
68 | 68 | The only meaningful difference (besides the "apply" prefix) between the methods
|
69 | 69 | of the `GenKillAnalysis` trait and the `Analysis` trait is that an `Analysis`
|
70 | 70 | has direct, mutable access to the dataflow state, whereas a `GenKillAnalysis`
|
71 | 71 | only sees an implementer of the `GenKill` trait, which only allows the `gen`
|
72 | 72 | and `kill` operations for mutation.
|
73 | 73 |
|
74 |
| -Observant readers of the documentation for these traits may notice that there |
75 |
| -are actually *two* possible effects for each statement and terminator, the |
76 |
| -"before" effect and the unprefixed (or "primary") effect. The "before" effects |
77 |
| -are applied immediately before the unprefixed effect **regardless of whether |
78 |
| -the analysis is backward or forward**. The vast majority of analyses should use |
79 |
| -only the unprefixed effects: Having multiple effects for each statement makes |
80 |
| -it difficult for consumers to know where they should be looking. However, the |
81 |
| -"before" variants can be useful in some scenarios, such as when the effect of |
82 |
| -the right-hand side of an assignment statement must be considered separately |
83 |
| -from the left-hand side. |
| 74 | +### "Before" Effects |
| 75 | + |
| 76 | +Observant readers of the documentation may notice that there are actually *two* |
| 77 | +possible effects for each statement and terminator, the "before" effect and the |
| 78 | +unprefixed (or "primary") effect. The "before" effects are applied immediately |
| 79 | +before the unprefixed effect **regardless of the direction of the analysis**. |
| 80 | +In other words, a backward analysis will apply the "before" effect and then the |
| 81 | +the "primary" effect when computing the transfer function for a basic block, |
| 82 | +just like a forward analysis. |
| 83 | + |
| 84 | +The vast majority of analyses should use only the unprefixed effects: Having |
| 85 | +multiple effects for each statement makes it difficult for consumers to know |
| 86 | +where they should be looking. However, the "before" variants can be useful in |
| 87 | +some scenarios, such as when the effect of the right-hand side of an assignment |
| 88 | +statement must be considered separately from the left-hand side. |
84 | 89 |
|
85 | 90 | ### Convergence
|
86 | 91 |
|
|
0 commit comments