diff options
| author | flip1995 <philipp.krones@embecosm.com> | 2022-05-02 10:55:39 +0100 |
|---|---|---|
| committer | Philipp Krones <hello@philkrones.com> | 2022-06-14 14:50:53 +0200 |
| commit | a93ea7ebc83560c2c62243a9190eff09dd3a7e62 (patch) | |
| tree | 95768ee8a3f29bc239b353e7717ac4c9138dd26f /src/doc | |
| parent | 996c6b7964a5d587f253a9b469cb00e20dc1b5fe (diff) | |
| download | rust-a93ea7ebc83560c2c62243a9190eff09dd3a7e62.tar.gz rust-a93ea7ebc83560c2c62243a9190eff09dd3a7e62.zip | |
Add user documentation for -Zvirtual-function-elimination
Diffstat (limited to 'src/doc')
| -rw-r--r-- | src/doc/unstable-book/src/compiler-flags/virtual-function-elimination.md | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/src/doc/unstable-book/src/compiler-flags/virtual-function-elimination.md b/src/doc/unstable-book/src/compiler-flags/virtual-function-elimination.md new file mode 100644 index 00000000000..c6516d838dd --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/virtual-function-elimination.md @@ -0,0 +1,39 @@ +# `virtual-function-elimination` + +This option controls whether LLVM runs the Virtual Function Elimination (VFE) +optimization. This optimization in only available with LTO, so this flag can +only be passed if [`-Clto`][Clto] is also passed. + +VFE makes it possible to remove functions from vtables that are never +dynamically called by the rest of the code. Without this flag, LLVM makes the +really conservative assumption, that if any function in a vtable is called, no +function that is referenced by this vtable can be removed. With this flag +additional information are given to LLVM, so that it can determine which +functions are actually called and remove the unused functions. + +## Limitations + +At the time of writing this flag may remove vtable functions too eagerly. One +such example is in this code: + +```rust +trait Foo { fn foo(&self) { println!("foo") } } + +impl Foo for usize {} + +pub struct FooBox(Box<dyn Foo>); + +pub fn make_foo() -> FooBox { FooBox(Box::new(0)) } + +#[inline] +pub fn f(a: FooBox) { a.0.foo() } +``` + +In the above code the `Foo` trait is private, so an assumption is made that its +functions can only be seen/called from the current crate and can therefore get +optimized out, if unused. However, with `make_foo` you can produce a wrapped +`dyn Foo` type outside of the current crate, which can then be used in `f`. Due +to inlining of `f`, `Foo::foo` can then be called from a foreign crate. This can +lead to miscompilations. + +[Clto]: https://doc.rust-lang.org/rustc/codegen-options/index.html#lto |
