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

Update doc to add a section for LTO #937

Merged
merged 1 commit into from
Sep 4, 2023
Merged
Show file tree
Hide file tree
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
2 changes: 2 additions & 0 deletions docs/userguide/src/portingguide/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@
- [How to Undertake a Port](./howto/prefix.md)
- [NoGC](./howto/nogc.md)
- [Next Steps](./howto/next_steps.md)
- [Performance Tuning]()
- [Link Time Optimization](./perf_tuning/lto.md)
38 changes: 38 additions & 0 deletions docs/userguide/src/portingguide/perf_tuning/lto.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Enabling Link Time Optimization (LTO) with MMTk

MMTk's API is designed with an assumption that LTO will be enabled for a performant build.
It is essential to allow the Rust compiler to optimize across the crate boundary between the binding crate and mmtk-core.
LTO allows inlining for both directions (from mmtk-core to the binding, and from the binding to mmtk-core),
and allows further optimization such as specializing and constant folding for the `VMBinding` trait.

We suggest enabling LTO for the release build in the binding's manifest (`Cargo.toml`) by adding a profile for the release build,
so LTO is always enabled for a release build.

```toml
[profile.release]
lto = true
```

If your binding project is a Rust binary (e.g. the VM is written in Rust), this should be enough. However, if your binding project
is a library, there are some limitations with cargo that you should be aware of.


## Binding as a library

Cargo only allows LTO for certain crate types. You will need to specify the crate type properly, otherwise cargo may skip LTO without
any warning or error.

```toml
[lib]
...
# be careful - LTO is only allowed for certain crate types
crate-type = ["cdylib"]
```

At the time of writing, cargo has some limitations about LTO with different crate types:
1. LTO is only allowed with `cdylib` and `staticlib` (other than `bin`).
Check the code of [`can_lto`](https://github.com/rust-lang/cargo/blob/5f40a97e5c85affecfbc4fde67fc06bf188c07db/src/cargo/core/compiler/crate_type.rs#L33)
for your Rust version to clarify.
2. If the `crate-type` field includes any type that LTO is not allowed, LTO will be skipped for all the libraries generated (https://github.com/rust-lang/rust/issues/51009).
For example, if you have `crate-type = ["cdylib", "rlib"]` and cargo cannot do LTO for `rlib`, LTO will be skipped for `cdylib` as well.
So only keep the crate type that you actually need in the `crate-type` field.