diff --git a/src/borrow_check/moves_and_initialization/move_paths.md b/src/borrow_check/moves_and_initialization/move_paths.md
index 4afec42f8..ad9c75d62 100644
--- a/src/borrow_check/moves_and_initialization/move_paths.md
+++ b/src/borrow_check/moves_and_initialization/move_paths.md
@@ -54,13 +54,13 @@ move_data.move_paths[mpi].place
 One of the first things we do in the MIR borrow check is to construct
 the set of move paths. This is done as part of the
 [`MoveData::gather_moves`] function. This function uses a MIR visitor
-called [`Gatherer`] to walk the MIR and look at how each [`Place`]
+called [`MoveDataBuilder`] to walk the MIR and look at how each [`Place`]
 within is accessed. For each such [`Place`], it constructs a
 corresponding [`MovePathIndex`]. It also records when/where that
 particular move path is moved/initialized, but we'll get to that in a
 later section.
 
-[`Gatherer`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_dataflow/move_paths/builder/struct.Gatherer.html
+[`MoveDataBuilder`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_dataflow/move_paths/builder/struct.MoveDataBuilder.html
 [`MoveData::gather_moves`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_dataflow/move_paths/struct.MoveData.html#method.gather_moves
 
 ### Illegal move paths
@@ -82,7 +82,7 @@ those just discussed, the function returns an `Err`. This in turn
 means we don't have to bother tracking whether those places are
 initialized (which lowers overhead).
 
-[`move_path_for`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_dataflow/move_paths/builder/struct.Gatherer.html#method.move_path_for
+[`move_path_for`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_dataflow/move_paths/builder/struct.MoveDataBuilder.html#method.move_path_for
 
 ## Looking up a move-path
 
diff --git a/src/mir/dataflow.md b/src/mir/dataflow.md
index 7bd0f0aab..f31da5ca2 100644
--- a/src/mir/dataflow.md
+++ b/src/mir/dataflow.md
@@ -24,40 +24,14 @@ for the alternative lectures.
 
 ## Defining a Dataflow Analysis
 
-The interface for dataflow analyses is split into three traits. The first is
-[`AnalysisDomain`], which must be implemented by *all* analyses. In addition to
-the type of the dataflow state, this trait defines the initial value of that
-state at entry to each block, as well as the direction of the analysis, either
+A dataflow analysis is defined by the [`Analysis`] trait. In addition to the
+type of the dataflow state, this trait defines the initial value of that state
+at entry to each block, as well as the direction of the analysis, either
 forward or backward. The domain of your dataflow analysis must be a [lattice][]
 (strictly speaking a join-semilattice) with a well-behaved `join` operator. See
 documentation for the [`lattice`] module, as well as the [`JoinSemiLattice`]
 trait, for more information.
 
-You must then provide *either* a direct implementation of the [`Analysis`] trait
-*or* an implementation of the proxy trait [`GenKillAnalysis`]. The latter is for
-so-called ["gen-kill" problems], which have a simple class of transfer function
-that can be applied very efficiently. Analyses whose domain is not a `BitSet`
-of some index type, or whose transfer functions cannot be expressed through
-"gen" and "kill" operations, must implement `Analysis` directly, and will run
-slower as a result. All implementers of `GenKillAnalysis` also implement
-`Analysis` automatically via a default `impl`.
-
-
-```text
- AnalysisDomain
-       ^
-       |          | = has as a supertrait
-       |          . = provides a default impl for
-       |
-   Analysis
-     ^   ^
-     |   .
-     |   .
-     |   .
- GenKillAnalysis
-
-```
-
 ### Transfer Functions and Effects
 
 The dataflow framework in `rustc` allows each statement (and terminator) inside
@@ -69,12 +43,6 @@ particular outgoing edges of some terminators (e.g.
 [`apply_call_return_effect`] for the `success` edge of a `Call`
 terminator). Collectively, these are referred to as "per-edge effects".
 
-The only meaningful difference (besides the "apply" prefix) between the methods
-of the `GenKillAnalysis` trait and the `Analysis` trait is that an `Analysis`
-has direct, mutable access to the dataflow state, whereas a `GenKillAnalysis`
-only sees an implementer of the `GenKill` trait, which only allows the `gen`
-and `kill` operations for mutation.
-
 ### "Before" Effects
 
 Observant readers of the documentation may notice that there are actually *two*
@@ -143,25 +111,16 @@ println!("x: {}", x);
 
 ## Inspecting the Results of a Dataflow Analysis
 
-Once you have constructed an analysis, you must pass it to an [`Engine`], which
-is responsible for finding the steady-state solution to your dataflow problem.
-You should use the [`into_engine`] method defined on the `Analysis` trait for
-this, since it will use the more efficient `Engine::new_gen_kill` constructor
-when possible.
-
-Calling `iterate_to_fixpoint` on your `Engine` will return a `Results`, which
-contains the dataflow state at fixpoint upon entry of each block. Once you have
-a `Results`, you can inspect the dataflow state at fixpoint at any point in
-the CFG. If you only need the state at a few locations (e.g., each `Drop`
-terminator) use a [`ResultsCursor`]. If you need the state at *every* location,
-a [`ResultsVisitor`] will be more efficient.
+Once you have constructed an analysis, you must call `iterate_to_fixpoint`
+which will return a `Results`, which contains the dataflow state at fixpoint
+upon entry of each block. Once you have a `Results`, you can inspect the
+dataflow state at fixpoint at any point in the CFG. If you only need the state
+at a few locations (e.g., each `Drop` terminator) use a [`ResultsCursor`]. If
+you need the state at *every* location, a [`ResultsVisitor`] will be more
+efficient.
 
 ```text
                          Analysis
-                            |
-                            | into_engine(…)
-                            |
-                          Engine
                             |
                             | iterate_to_fixpoint()
                             |
@@ -181,9 +140,8 @@ let mut my_visitor = MyVisitor::new();
 
 // inspect the fixpoint state for every location within every block in RPO.
 let results = MyAnalysis::new()
-    .into_engine(tcx, body, def_id)
-    .iterate_to_fixpoint()
-    .visit_in_rpo_with(body, &mut my_visitor);
+    .iterate_to_fixpoint(tcx, body, None);
+results.visit_with(body, &mut my_visitor);`
 ```
 
 whereas this code uses [`ResultsCursor`]:
@@ -222,12 +180,10 @@ the example below:
 ["gen-kill" problems]: https://en.wikipedia.org/wiki/Data-flow_analysis#Bit_vector_problems
 [*Static Program Analysis*]: https://cs.au.dk/~amoeller/spa/
 [Debugging MIR]: ./debugging.md
-[`AnalysisDomain`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_dataflow/trait.AnalysisDomain.html
 [`Analysis`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_dataflow/trait.Analysis.html
-[`Engine`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_dataflow/struct.Engine.html
 [`GenKillAnalysis`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_dataflow/trait.GenKillAnalysis.html
 [`JoinSemiLattice`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_dataflow/lattice/trait.JoinSemiLattice.html
-[`NAME`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_dataflow/trait.AnalysisDomain.html#associatedconstant.NAME
+[`NAME`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_dataflow/trait.Analysis.html#associatedconstant.NAME
 [`ResultsCursor`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_dataflow/struct.ResultsCursor.html
 [`ResultsVisitor`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_dataflow/trait.ResultsVisitor.html
 [`apply_call_return_effect`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_dataflow/trait.Analysis.html#tymethod.apply_call_return_effect