|
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