Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove polymorphization #2158

Merged
merged 1 commit into from
Dec 10, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
remove polymorphization
Orion Gonzalez committed Dec 10, 2024

Verified

This commit was signed with the committer’s verified signature.
GromNaN Jérôme Tamarelle
commit 3e24863c207b552ad36214dfa7f7daa8c21ab7cf
74 changes: 0 additions & 74 deletions src/backend/monomorph.md
Original file line number Diff line number Diff line change
@@ -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<u64>` 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<A, B>() {
let x: Option<B> = None;
}

fn main() {
foo::<u16, u32>();
foo::<u64, u32>();
}
```

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