Skip to content

Commit e6a487d

Browse files
committed
Improve MIR sections in appendix
Add a new graphical representation of one of the examples of MIR and basic blocks! And make other minor improvements.
1 parent d4ae7b0 commit e6a487d

File tree

1 file changed

+54
-27
lines changed

1 file changed

+54
-27
lines changed

src/appendix/background.md

Lines changed: 54 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ Rust-specific context.
88

99
## What is a control-flow graph?
1010

11-
A control-flow graph is a common term from compilers. If you've ever
11+
A control-flow graph (CFG) is a common term from compilers. If you've ever
1212
used a flow-chart, then the concept of a control-flow graph will be
1313
pretty familiar to you. It's a representation of your program that
14-
exposes the underlying control flow in a very clear way.
14+
clearly exposes the underlying control flow.
1515

1616
A control-flow graph is structured as a set of **basic blocks**
1717
connected by edges. The key idea of a basic block is that it is a set
@@ -44,12 +44,17 @@ if some_variable {
4444
d = 1;
4545
```
4646

47-
This would compile into four basic blocks:
47+
This would compile into four basic blocks in MIR. In textual form, it looks like
48+
this:
4849

4950
```mir
5051
BB0: {
5152
a = 1;
52-
if some_variable { goto BB1 } else { goto BB2 }
53+
if some_variable {
54+
goto BB1;
55+
} else {
56+
goto BB2;
57+
}
5358
}
5459

5560
BB1: {
@@ -64,10 +69,33 @@ BB2: {
6469

6570
BB3: {
6671
d = 1;
67-
...;
72+
...
6873
}
6974
```
7075

76+
In graphical form, it looks like this:
77+
78+
```
79+
BB0
80+
+--------------------+
81+
| a = 1; |
82+
+--------------------+
83+
/ \
84+
if some_variable else
85+
/ \
86+
BB1 / \ BB2
87+
+-----------+ +-----------+
88+
| b = 1; | | c = 1; |
89+
+-----------+ +-----------+
90+
\ /
91+
\ /
92+
\ BB3 /
93+
+----------+
94+
| d = 1; |
95+
| ... |
96+
+----------+
97+
```
98+
7199
When using a control-flow graph, a loop simply appears as a cycle in
72100
the graph, and the `break` keyword translates into a path out of that
73101
cycle.
@@ -82,10 +110,10 @@ and Michael I. Schwartzbach is an incredible resource!
82110
_Dataflow analysis_ is a type of static analysis that is common in many
83111
compilers. It describes a general technique, rather than a particular analysis.
84112

85-
The basic idea is that we can walk over a [CFG](#cfg) and keep track of what
86-
some value could be. At the end of the walk, we might have shown that some
87-
claim is true or not necessarily true (e.g. "this variable must be
88-
initialized"). `rustc` tends to do dataflow analyses over the MIR, since that
113+
The basic idea is that we can walk over a [control-flow graph (CFG)](#cfg) and
114+
keep track of what some value could be. At the end of the walk, we might have
115+
shown that some claim is true or not necessarily true (e.g. "this variable must
116+
be initialized"). `rustc` tends to do dataflow analyses over the MIR, since MIR
89117
is already a CFG.
90118

91119
For example, suppose we want to check that `x` is initialized before it is used
@@ -207,17 +235,17 @@ such that the function is well-typed: `∃ T: (T: Debug) and well_typed(foo)`.
207235

208236
<a name="variance"></a>
209237

210-
## What is a DeBruijn Index?
238+
## What is a de Bruijn Index?
211239

212-
DeBruijn indices are a way of representing which variables are bound in
213-
which binders using only integers. They were [originally invented][wikideb] for
214-
use in lambda calculus evaluation. In `rustc`, we use a similar idea for the
215-
[representation of generic types][sub].
240+
[De Bruijn indices][wikideb] are a way of representing using only integers which
241+
variables are bound in which binders. They were originally invented for use in
242+
lambda calculus evaluation (see [this Wikipedia article][wikideb] for more). In
243+
`rustc`, we use a similar idea for the [representation of generic types][sub].
216244

217245
[wikideb]: https://en.wikipedia.org/wiki/De_Bruijn_index
218246
[sub]: ../generics.md
219247

220-
Here is a basic example of how DeBruijn indices might be used for closures (we
248+
Here is a basic example of how de Bruijn indices might be used for closures (we
221249
don't actually do this in `rustc` though):
222250

223251
```rust,ignore
@@ -231,7 +259,7 @@ don't actually do this in `rustc` though):
231259
}
232260
```
233261

234-
## What is co- and contra-variance?
262+
## What are co- and contra-variance?
235263

236264
Check out the subtyping chapter from the
237265
[Rust Nomicon](https://doc.rust-lang.org/nomicon/subtyping.html).
@@ -246,17 +274,16 @@ the type checker handles variance.
246274
Let's describe the concepts of free vs bound in terms of program
247275
variables, since that's the thing we're most familiar with.
248276

249-
- Consider this expression, which creates a closure: `|a,
250-
b| a + b`. Here, the `a` and `b` in `a + b` refer to the arguments
251-
that the closure will be given when it is called. We say that the
252-
`a` and `b` there are **bound** to the closure, and that the closure
253-
signature `|a, b|` is a **binder** for the names `a` and `b`
254-
(because any references to `a` or `b` within refer to the variables
255-
that it introduces).
256-
- Consider this expression: `a + b`. In this expression, `a` and `b`
257-
refer to local variables that are defined *outside* of the
258-
expression. We say that those variables **appear free** in the
259-
expression (i.e., they are **free**, not **bound** (tied up)).
277+
- Consider this expression, which creates a closure: `|a, b| a + b`.
278+
Here, the `a` and `b` in `a + b` refer to the arguments that the closure will
279+
be given when it is called. We say that the `a` and `b` there are **bound** to
280+
the closure, and that the closure signature `|a, b|` is a **binder** for the
281+
names `a` and `b` (because any references to `a` or `b` within refer to the
282+
variables that it introduces).
283+
- Consider this expression: `a + b`. In this expression, `a` and `b` refer to
284+
local variables that are defined *outside* of the expression. We say that
285+
those variables **appear free** in the expression (i.e., they are **free**,
286+
not **bound** (tied up)).
260287

261288
So there you have it: a variable "appears free" in some
262289
expression/statement/whatever if it refers to something defined

0 commit comments

Comments
 (0)