Follow-up: tooling to detect failed devirtualization?

I've made a benchmark of the Rust overhead that can be caused by vtable calls.

The reality, however, is that Rust can often do a good job of devirtualizing such calls. This benchmark shows an extreme scenario where devirtualization fails.

In terms of performance and maintainability, there are many cases where we can use dyn Trait to simplify code, while the compiler can still optimize it in such a way that the vtable is not actually used at runtime.

The main problem is that the process of deciding when the compiler will devirtualize a call and when it will not is not very transparent. Intuitively, most of us understand that the compiler is not stupid, but to rely on devirtualization we need something more solid than just our intuition.

What I am looking for is some sort of linter or other tooling that can show me when devirtualization has failed in places where I expect it to happen.


I did some research, and this is the best I have so far:

cargo rustc --release -p devirtualization-test-main -- \
    -C debuginfo=1 \
    -C remark=all 2>&1 \
    | grep -v ' inline '

And the output:

note: ~/Projects/devirtualization-test/lib-crate/src/lib.rs:0:0 asm-printer (analysis): BasicBlock:
      MOV64mr: 3
      MOV64rm: 3
      CALL64m: 1
      DEC64r: 1
      JCC_1: 1
  • CALL64m tells me that an indirect call through memory remains in the generated machine code. In this particular test, this is the vtable call I'm looking for.
  • lib.rs:0:0 is not really informative because of the 0:0 source location. However, sometimes the remark does contain the exact source line.

Do you know of any existing tooling for this?

Or, if nothing like this currently exists, do you have any suggestions for how such a tool could be implemented?


Same question asked on reddit:

https://www.reddit.com/r/learnrust/comments/1wzh4nb/followup_tooling_to_detect_failed_devirtualization/

unlisting because the original poster was silenced
(unrelated to this particular thread)