about summary refs log tree commit diff
path: root/src/doc
diff options
context:
space:
mode:
authorflip1995 <philipp.krones@embecosm.com>2022-05-02 10:55:39 +0100
committerPhilipp Krones <hello@philkrones.com>2022-06-14 14:50:53 +0200
commita93ea7ebc83560c2c62243a9190eff09dd3a7e62 (patch)
tree95768ee8a3f29bc239b353e7717ac4c9138dd26f /src/doc
parent996c6b7964a5d587f253a9b469cb00e20dc1b5fe (diff)
downloadrust-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.md39
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