Skip to content

Commit a93ea7e

Browse files
committed
Add user documentation for -Zvirtual-function-elimination
1 parent 996c6b7 commit a93ea7e

File tree

1 file changed

+39
-0
lines changed

1 file changed

+39
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# `virtual-function-elimination`
2+
3+
This option controls whether LLVM runs the Virtual Function Elimination (VFE)
4+
optimization. This optimization in only available with LTO, so this flag can
5+
only be passed if [`-Clto`][Clto] is also passed.
6+
7+
VFE makes it possible to remove functions from vtables that are never
8+
dynamically called by the rest of the code. Without this flag, LLVM makes the
9+
really conservative assumption, that if any function in a vtable is called, no
10+
function that is referenced by this vtable can be removed. With this flag
11+
additional information are given to LLVM, so that it can determine which
12+
functions are actually called and remove the unused functions.
13+
14+
## Limitations
15+
16+
At the time of writing this flag may remove vtable functions too eagerly. One
17+
such example is in this code:
18+
19+
```rust
20+
trait Foo { fn foo(&self) { println!("foo") } }
21+
22+
impl Foo for usize {}
23+
24+
pub struct FooBox(Box<dyn Foo>);
25+
26+
pub fn make_foo() -> FooBox { FooBox(Box::new(0)) }
27+
28+
#[inline]
29+
pub fn f(a: FooBox) { a.0.foo() }
30+
```
31+
32+
In the above code the `Foo` trait is private, so an assumption is made that its
33+
functions can only be seen/called from the current crate and can therefore get
34+
optimized out, if unused. However, with `make_foo` you can produce a wrapped
35+
`dyn Foo` type outside of the current crate, which can then be used in `f`. Due
36+
to inlining of `f`, `Foo::foo` can then be called from a foreign crate. This can
37+
lead to miscompilations.
38+
39+
[Clto]: https://doc.rust-lang.org/rustc/codegen-options/index.html#lto

0 commit comments

Comments
 (0)