rust-lang / rustc_codegen_cranelift

Cranelift based backend for rustc
Apache License 2.0
1.59k stars 100 forks source link

-Zcoverage is unimplemented #1494

Open weiznich opened 3 months ago

weiznich commented 3 months ago

I've tried to use the cranlift rust backend for a project that records code coverage for tests. For this I run the following command:

RUSTFLAGS="-Zcodegen-backend=cranelift" cargo +nightly llvm-cov test -j 1

which resulted in the following error:

   Compiling proc-macro2 v1.0.78
error: -Zcoverage is unimplemented

stmt Coverage::CounterIncrement(0)
fn main() -> () {
    let mut _0: ();
// … more MIR 

I expected that this would likely not work. I was just surprised that there is no issue for this yet, so I filled that one.

bjorn3 commented 3 months ago

LLVM's coverage infrastructure is LLVM specific and the exact data format even changes between LLVM versions.

https://clang.llvm.org/docs/SourceBasedCodeCoverage.html#format-compatibility-guarantees

There are no backwards or forwards compatibility guarantees for the raw profile format. Raw profiles may be dependent on the specific compiler revision used to generate them. It’s inadvisable to store raw profiles for long periods of time.

Implementing coverage support in cg_clif would be possible, but it will not be compatible with llvm-cov. And it will require writing a replacement for the LLVM profiler runtime and getting rustc to use this replacement.

weiznich commented 3 months ago

Thanks for your response. As already written before I did not expect this to work.

I think the problematic part here is that -Ccoverage is a option that's supported by a stable compiler, which somewhat makes this format/option more official from my point of view.

Maybe a short term solution would be to just change the message so that it does not say anymore that it's unimplemented but not supported or something like that? Maybe even with a bit more context outlining that this is a llvm specific feature?

bjorn3 commented 3 months ago

-Cllvm-args is also supported on stable, yet we don't guarantee anything about it either. We can't anyway as LLVM doesn't make any stability promises about which flags it supports. (Clang flags don't always directly map to LLVM flags and some LLVM flags are not exposed by clang at all.)

Maybe a short term solution would be to just change the message so that it does not say anymore that it's unimplemented but not supported or something like that? Maybe even with a bit more context outlining that this is a llvm specific feature?

Done

weiznich commented 1 month ago

I just stumbled on https://crates.io/crates/minicov which seem to implement most of the necessary format. It seems like that crate could be used to generate the relevant glue code to support this flag?

bjorn3 commented 1 month ago

Profiling support is split into two parts: an instrumentation pass in the compiler and a profiler runtime. Cg_clif misses the instrumentation pass, while minicov implements the profiler runtime. I am pretty sure cg_clif can reuse the LLVM profiler runtime in the profiler-builtins crate already, so using minicov doesn't really help here. Once the instrumentation pass is written for cg_clif, profiler-builtins and minicov could be used interchangably.

weiznich commented 1 month ago

Thanks for the clarification. To be honest it sounded already a bit too easy in the beginning.