diff --git a/src/backend/monomorph.md b/src/backend/monomorph.md index 7726daf4f..7ebb4d2b1 100644 --- a/src/backend/monomorph.md +++ b/src/backend/monomorph.md @@ -79,77 +79,3 @@ For more details about the partitioner read the module level [documentation]. [mono]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_monomorphize/partitioning/fn.collect_and_partition_mono_items.html [codegen1]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/base/fn.codegen_crate.html [documentation]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_monomorphize/partitioning/index.html - -## Polymorphization - -As mentioned above, monomorphization produces fast code, but it comes at the -cost of compile time and binary size. [MIR optimizations][miropt] can help a -bit with this. - -In addition to MIR optimizations, rustc attempts to determine when fewer -copies of functions are necessary and avoid making those copies - known -as "polymorphization". When a function-like item is found during -monomorphization collection, the -[`rustc_mir_monomorphize::polymorphize::unused_generic_params`][polymorph] -query is invoked, which traverses the MIR of the item to determine on which -generic parameters the item might not need duplicated. - -Currently, polymorphization only looks for unused generic parameters. These -are relatively rare in functions, but closures inherit the generic -parameters of their parent function and it is common for closures to not -use those inherited parameters. Without polymorphization, a copy of these -closures would be created for each copy of the parent function. By -creating fewer copies, less LLVM IR is generated; therefore less needs to be processed. - -`unused_generic_params` returns a `FiniteBitSet` where a bit is set if -the generic parameter of the corresponding index is unused. Any parameters -after the first sixty-four are considered used. - -The results of polymorphization analysis are used in the -[`Instance::polymorphize`][inst_polymorph] function to replace the -[`Instance`][inst]'s substitutions for the unused generic parameters with their -identity substitutions. - -Consider the example below: - -```rust -fn foo() { - let x: Option = None; -} - -fn main() { - foo::(); - foo::(); -} -``` - -During monomorphization collection, `foo` will be collected with the -substitutions `[u16, u32]` and `[u64, u32]` (from its invocations in `main`). -`foo` has the identity substitutions `[A, B]` (or -`[ty::Param(0), ty::Param(1)]`). - -Polymorphization will identify `A` as being unused and it will be replaced in -the substitutions with the identity parameter before being added to the set -of collected items - thereby reducing the copies from two (`[u16, u32]` and -`[u64, u32]`) to one (`[A, u32]`). - -`unused_generic_params` will also be invoked during code generation when the -symbol name for `foo` is being computed for use in the callsites of `foo` -(which have the regular substitutions present, otherwise there would be a -symbol mismatch between the caller and the function). - -As a result of polymorphization, items collected during monomorphization -cannot be assumed to be monomorphic. - -It is intended that polymorphization be extended to more advanced cases, -such as where only the size/alignment of a generic parameter are required. - -More details on polymorphization are available in the -[master's thesis][thesis] associated with polymorphization's initial -implementation. - -[miropt]: ../mir/optimizations.md -[polymorph]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_monomorphize/polymorphize/fn.unused_generic_params.html -[inst]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/instance/struct.Instance.html -[inst_polymorph]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/instance/struct.Instance.html#method.polymorphize -[thesis]: https://davidtw.co/media/masters_dissertation.pdf