]> git.lizzy.rs Git - rust.git/commitdiff
remove irrelevant comments
authorNiko Matsakis <niko@alum.mit.edu>
Mon, 1 May 2017 21:17:44 +0000 (17:17 -0400)
committerNiko Matsakis <niko@alum.mit.edu>
Tue, 2 May 2017 20:21:56 +0000 (16:21 -0400)
src/librustc/mir/README.md

index 143e6e70a82b36abda762c01e1f609ebd57cdfe0..e8ed8bf104cc8892fd60416a4fe752abff12ea48 100644 (file)
@@ -32,111 +32,59 @@ MIR and then iteratively optimize it by putting it through various
 pipeline stages. This section describes those pipeline stages and how
 you can extend them.
 
 pipeline stages. This section describes those pipeline stages and how
 you can extend them.
 
-Here is a diagram showing the various MIR queries involved in producing
-the final `optimized_mir()` for a single def-id `D`. The arrows here
-indicate how data flows from query to query.
+To produce the `optimized_mir(D)` for a given def-id `D`, the MIR
+passes through several suites of optimizations, each represented by a
+query. Each suite consists of multiple optimizations and
+transformations. These suites represent useful intermediate points
+where we want to access the MIR for type checking or other purposes:
 
 
-```
-mir_build(D)
-  -> mir_pass((0,0,D))              ---+ each suite consists of many passes
-    -> ...                             |
-      -> mir_pass((0,N,D))             |
-        -> mir_suite((0,D))         ---+ ---+ there are several suites
-          -> ...                            |
-            -> mir_suite((M,D))          ---+
-              -> mir_optimized(D)
-```
-
-The MIR transformation pipeline is organized into **suites**.  When
-you ask for `mir_optimized(D)`, it will turn around and request the
-result from the final **suite** of MIR passes
-(`mir_suite((M,D))`). This will in turn (eventually) trigger the MIR
-to be build and then passes through each of the optimization suites.
-Each suite internally triggers one query for each of its passes
-(`mir_pass(...)`).
-
-The reason for the suites is that they represent points in the MIR
-transformation pipeline where other bits of code are interested in
-observing. For example, the `MIR_CONST` suite defines the point where
-analysis for constant rvalues and expressions can take
-place. `MIR_OPTIMIZED` naturally represents the point where we
-actually generate machine code. Nobody should ever request the result
-of an individual *pass*, at least outside of the transformation
-pipeline: this allows us to add passes into the appropriate suite
-without having to modify anything else in the compiler.
+- `mir_build(D)` -- not a query, but this constructs the initial MIR
+- `mir_const(D)` -- applies some simple transformations to make MIR ready for constant evaluation;
+- `mir_validated(D)` -- applies some more transformations, making MIR ready for borrow checking;
+- `optimized_mir(D)` -- the final state, after all optimizations have been performed.
 
 ### Stealing
 
 
 ### Stealing
 
-Each of these intermediate queries yields up a `&'tcx
-Steal<Mir<'tcx>>`, allocated using `tcx.alloc_steal_mir()`. This
-indicates that the result may be **stolen** by the next pass -- this
-is an optimization to avoid cloning the MIR. Attempting to use a
-stolen result will cause a panic in the compiler. Therefore, it is
-important that you not read directly from these intermediate queries
-except as part of the MIR processing pipeline.
+The intermediate queries `mir_const()` and `mir_validated()` yield up
+a `&'tcx Steal<Mir<'tcx>>`, allocated using
+`tcx.alloc_steal_mir()`. This indicates that the result may be
+**stolen** by the next suite of optimizations -- this is an
+optimization to avoid cloning the MIR. Attempting to use a stolen
+result will cause a panic in the compiler. Therefore, it is important
+that you not read directly from these intermediate queries except as
+part of the MIR processing pipeline.
 
 Because of this stealing mechanism, some care must also be taken to
 ensure that, before the MIR at a particular phase in the processing
 pipeline is stolen, anyone who may want to read from it has already
 
 Because of this stealing mechanism, some care must also be taken to
 ensure that, before the MIR at a particular phase in the processing
 pipeline is stolen, anyone who may want to read from it has already
-done so. Sometimes this requires **forcing** queries
-(`ty::queries::foo::force(...)`) during an optimization pass -- this
-will force a query to execute even though you don't directly require
-its result. The query can then read the MIR it needs, and -- once it
-is complete -- you can steal it.
+done so. Concretely, this means that if you have some query `foo(D)`
+that wants to access the result of `mir_const(D)` or
+`mir_validated(D)`, you need to have the successor pass either "force"
+`foo(D)` using `ty::queries::foo::force(...)`. This will force a query
+to execute even though you don't directly require its result.
 
 As an example, consider MIR const qualification. It wants to read the
 
 As an example, consider MIR const qualification. It wants to read the
-result produced by the `MIR_CONST` suite. However, that result will be
-**stolen** by the first pass in the next suite (that pass performs
-const promotion):
+result produced by the `mir_const()` suite. However, that result will
+be **stolen** by the `mir_validated()` suite. If nothing was done,
+then `mir_const_qualif(D)` would succeed if it came before
+`mir_validated(D)`, but fail otherwise. Therefore, `mir_validated(D)`
+will **force** `mir_const_qualif` before it actually steals, thus
+ensuring that the reads have already happened:
 
 ```
 
 ```
-mir_suite((MIR_CONST,D)) --read-by--> mir_const_qualif(D)
-            |
-        stolen-by
-            |
-            v
-mir_pass((MIR_VALIDATED,0,D))
+mir_const(D) --read-by--> mir_const_qualif(D)
+     |                       ^
+  stolen-by                  |
+     |                    (forces)
+     v                       |
+mir_validated(D) ------------+
 ```
 
 ```
 
-Therefore, the const promotion pass (the `mir_pass()` in the diagram)
-will **force** `mir_const_qualif` before it actually steals, thus
-ensuring that the reads have already happened (and the final result is
-cached).
-
 ### Implementing and registering a pass
 
 ### Implementing and registering a pass
 
-To create a new MIR pass, you have to implement one of the MIR pass
-traits. There are several traits, and you want to pick the most
-specific one that applies to your pass. They are described here in
-order of preference. Once you have implemented a trait for your type
-`Foo`, you then have to insert `Foo` into one of the suites; this is
-done in `librustc_driver/driver.rs` by invoking `push_pass()` with the
-appropriate suite.
-
-**The `MirPass` trait.** For the most part, a MIR pass works by taking
-as input the MIR for a single function and mutating it imperatively to
-perform an optimization. To write such a pass, you can implement the
-`MirPass` trait, which has a single callback that takes an `&mut Mir`.
-
-**The `DefIdPass` trait.** When a `MirPass` trait is executed, the
-system will automatically steal the result of the previous pass and
-supply it to you. (See the section on queries and stealing below.)
-Sometimes you don't want to steal the result of the previous pass
-right away. In such cases, you can define a `DefIdPass`, which simply
-gets a callback and lets you decide when to steal the previous result.
-
-**The `Pass` trait.** The most primitive but flexible trait is `Pass`.
-Unlike the other pass types, it returns a `Multi` result, which means
-it scan be used for interprocedural passes which mutate more than one
-MIR at a time (e.g., `inline`).
-
-### The MIR Context
-
-All of the passes when invoked take a `MirCtxt` object. This contains
-various methods to find out (e.g.) the current pass suite and pass
-index, the def-id you are operating on, and so forth. You can also
-access the MIR for the current def-id using `read_previous_mir()`; the
-"previous" refers to the fact that this will be the MIR that was
-output by the previous pass. Finally, you can `steal_previous_mir()`
-to steal the output of the current pass (in which case you get
-ownership of the MIR).
+To create a new MIR pass, you simply implement the `MirPass` trait for
+some fresh singleton type `Foo`. Once you have implemented a trait for
+your type `Foo`, you then have to insert `Foo` into one of the suites;
+this is done in `librustc_driver/driver.rs` by invoking `push_pass(S,
+Foo)` with the appropriate suite substituted for `S`.
+