Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Run LLVM coverage instrumentation passes before optimization passes #83666

Merged
merged 2 commits into from
Mar 31, 2021

Conversation

Amanieu
Copy link
Member

@Amanieu Amanieu commented Mar 30, 2021

This matches the behavior of Clang and allows us to remove several
hacks which were needed to ensure functions weren't optimized away
before reaching the instrumentation pass.

Fixes #83429

cc @richkadel

r? @tmandry

This matches the behavior of Clang and allows us to remove several
hacks which were needed to ensure functions weren't optimized away
before reaching the instrumentation pass.
@Amanieu Amanieu added the A-code-coverage Area: Source-based code coverage (-Cinstrument-coverage) label Mar 30, 2021
@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Mar 30, 2021
Copy link
Contributor

@richkadel richkadel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! Thanks!

@@ -28,12 +28,6 @@ pub fn used_inline_function() {
}
use_this_lib_crate();
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any theories why this is no longer generating the Unexecuted instantiation? It probably doesn't have to be documented here anymore (the absence of the unexpected should be expected, so this is good), but I'm curious why it changed.

Here's a trick for keeping the diffs clean in the expected results, above. The line numbers in llvm-cov show mess things up, so I avoid changing line numbers whenever possible: Just replace these 6 deleted lines with 6 blank lines.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Unexecuted instantiation re-appears if I undo the changes in compiler/rustc_typeck/src/collect.rs. I'm not exactly sure how that causes it to re-appear though.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I assumed it's related somehow.

Thanks for inserting the blank lines. Makes the expected result diffs a lot easier to read!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want me to remove the blank lines before merging?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not necessary. Thanks.

@@ -548,6 +548,11 @@ pub(crate) unsafe fn optimize(
llvm::LLVMRustAddPass(fpm, find_pass("lint").unwrap());
continue;
}
if pass_name == "insert-gcov-profiling" || pass_name == "instrprof" {
// Instrumentation should be inserted before optimization.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we say "must" instead of "should" and reference the Issue number?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't find a suitable issue to point to so I just pointed at the Clang code.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're updated comment works for me. Thanks!

Copy link
Contributor

@richkadel richkadel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I just realized that the existing tests in the rust compiler don't confirm that your fix for the inline always actually works. See my comment about how to test this. Thanks!

} else {
InlineAttr::Always
}
InlineAttr::Always
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, before you make this change, we need to test that this doesn't break the brotli_decompressor

See #82875

I was not able to create a coverage test that failed in the way it fails in this issue, but by not forcing inline always, the issue was resolved.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just tested the example from that issue. It fails on my main rustc (2021-03-24 nightly) but succeeds on my new branch. So the fix for inline always works.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's great.

Before merging, I'd like to try your patch on some creates I had issues with.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I cherry-picked your branch commits and am testing them now.

@richkadel
Copy link
Contributor

I'm having an issue compiling the brotli_decompressor test with anything higher than -Copt-level=1. The compiler is much slower when compiling with -Copt-level=2. (Level 3 is not much slower than 2 though.)

I don't remember ever having to wait very long for the compiler to compile and link one small program like this.

Is it possible your change could significantly slow down the optimization passes?

extern crate brotli_decompressor;
use std::io;

fn main() {
    match brotli_decompressor::BrotliDecompress(&mut io::stdin(), &mut io::stdout()) {
        Ok(_) => {}
        Err(e) => println!("Error {:?}", e),
    }
}
$ time ~/rust/build/x86_64-unknown-linux-gnu/stage1/bin/rustc -Zinstrument-coverage -Copt-level=1 brotli_covtest.rs -L ~/rust-brotli-decompressor/target/debug/ -L ~/rust-brotli-decompressor/target/debug/deps --edition=2018

real    0m1.111s
user    0m3.136s
sys     0m0.179s

$ time ~/rust/build/x86_64-unknown-linux-gnu/stage1/bin/rustc -Zinstrument-coverage -Copt-level=2 brotli_covtest.rs -L ~/rust-brotli-decompressor/target/debug/ -L ~/rust-brotli-decompressor/target/debug/deps --edition=2018

real    0m23.503s
user    0m36.125s
sys     0m0.181s

$ time ~/rust/build/x86_64-unknown-linux-gnu/stage1/bin/rustc -Zinstrument-coverage -Copt-level=3 brotli_covtest.rs -L ~/rust-brotli-decompressor/target/debug/ -L ~/rust-brotli-decompressor/target/debug/deps --edition=2018

real    0m23.822s
user    0m36.961s
sys     0m0.211s

@Amanieu
Copy link
Member Author

Amanieu commented Mar 30, 2021

I can't reproduce this:

time rustc +stage1 -Zinstrument-coverage -Copt-level=3 brotli_covtest.rs -L target/debug/ -L target/debug/deps --edition=2018                                                                                                                                                                                    
________________________________________________________
Executed in    1.45 secs    fish           external
   usr time    2.26 secs  396.00 micros    2.26 secs
   sys time    0.07 secs   46.00 micros    0.07 secs

Can you try using -Ztime-passes -Ztime-llvm-passes to see what is taking up so much time?

@richkadel
Copy link
Contributor

yes. Also, Let me rebuild the compiler after a clean. I want to make sure I don't have some weird residual code influencing this somehow.

@richkadel
Copy link
Contributor

I'm not seeing an issue after a clean build. Not sure what happened, but I think it was something buggy in my build. Good to go from my perspective.

@tmandry - Thumbs up from me.

Thanks Amanieu!

@tmandry
Copy link
Member

tmandry commented Mar 31, 2021

Oh this is great, a big mystery is now solved. Thanks for this!

@bors r+

@bors
Copy link
Collaborator

bors commented Mar 31, 2021

📌 Commit cad9b6b has been approved by tmandry

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Mar 31, 2021
@bors
Copy link
Collaborator

bors commented Mar 31, 2021

⌛ Testing commit cad9b6b with merge 6ff482b...

@bors
Copy link
Collaborator

bors commented Mar 31, 2021

☀️ Test successful - checks-actions
Approved by: tmandry
Pushing 6ff482b to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Mar 31, 2021
@bors bors merged commit 6ff482b into rust-lang:master Mar 31, 2021
@rustbot rustbot added this to the 1.53.0 milestone Mar 31, 2021
@klensy
Copy link
Contributor

klensy commented Mar 31, 2021

https://perf.rust-lang.org/compare.html?start=65b44b0320e88f5a0608126c36b02be1b840700f&end=6ff482bde5d22a3a0171edb3245327f43cf9b593&stat=max-rss

Big deviations on kessak-debug and unicode_normalization-debug with incr-full, but maybe this is random thing.

@Amanieu
Copy link
Member Author

Amanieu commented Mar 31, 2021

The changes in PR only apply if -Zinstrument-coverage is used, so this is very surprising.

@klensy
Copy link
Contributor

klensy commented Mar 31, 2021

Currently rust-perf site works slow for me, maybe that affects backend performance collection process too?

@klensy
Copy link
Contributor

klensy commented Mar 31, 2021

Checked next pr, the same thing https://perf.rust-lang.org/compare.html?start=2a32abbcdea97c6bf1d0445bc657f16c50ca103b&end=a5029ac0ab372aec515db2e718da6d7787f3d122&stat=max-rss

Maybe some issues with performance collecting, or i checking wrong commits :-(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-code-coverage Area: Source-based code coverage (-Cinstrument-coverage) merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Consider moving instrument-coverage-specific behavior in rustc_typeck to backend code
7 participants