From 26d260bfa4a31df541ff1d4c24965730660b4114 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Sat, 27 Mar 2021 05:04:32 +0000 Subject: Run LLVM coverage instrumentation passes before optimization passes 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. --- compiler/rustc_codegen_llvm/src/back/write.rs | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'compiler/rustc_codegen_llvm/src') diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 388dd7ce81b..c45d637177e 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -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. + llvm::LLVMRustAddPass(mpm, find_pass(pass_name).unwrap()); + continue; + } if let Some(pass) = find_pass(pass_name) { extra_passes.push(pass); -- cgit 1.4.1-3-g733a5 From cad9b6b695e86c7c23482876d2f6fefd64451ab3 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Tue, 30 Mar 2021 07:03:41 +0100 Subject: Apply review feedback --- compiler/rustc_codegen_llvm/src/back/write.rs | 6 +- .../expected_show_coverage.uses_inline_crate.txt | 160 +++++++++++---------- .../coverage/lib/used_inline_crate.rs | 6 + 3 files changed, 94 insertions(+), 78 deletions(-) (limited to 'compiler/rustc_codegen_llvm/src') diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index c45d637177e..085935b94df 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -549,7 +549,11 @@ pub(crate) unsafe fn optimize( continue; } if pass_name == "insert-gcov-profiling" || pass_name == "instrprof" { - // Instrumentation should be inserted before optimization. + // Instrumentation must be inserted before optimization, + // otherwise LLVM may optimize some functions away which + // breaks llvm-cov. + // + // This mirrors what Clang does in lib/CodeGen/BackendUtil.cpp. llvm::LLVMRustAddPass(mpm, find_pass(pass_name).unwrap()); continue; } diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_inline_crate.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_inline_crate.txt index c38d2f87ace..cc98956e307 100644 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_inline_crate.txt +++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_inline_crate.txt @@ -31,103 +31,109 @@ 29| 1| use_this_lib_crate(); 30| 1|} 31| | - 32| |#[inline(always)] - 33| 2|pub fn used_only_from_bin_crate_generic_function(arg: T) { - 34| 2| println!("used_only_from_bin_crate_generic_function with {:?}", arg); - 35| 2|} + 32| | + 33| | + 34| | + 35| | + 36| | + 37| | + 38| |#[inline(always)] + 39| 2|pub fn used_only_from_bin_crate_generic_function(arg: T) { + 40| 2| println!("used_only_from_bin_crate_generic_function with {:?}", arg); + 41| 2|} ------------------ | used_inline_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec>: - | 33| 1|pub fn used_only_from_bin_crate_generic_function(arg: T) { - | 34| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg); - | 35| 1|} + | 39| 1|pub fn used_only_from_bin_crate_generic_function(arg: T) { + | 40| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg); + | 41| 1|} ------------------ | used_inline_crate::used_only_from_bin_crate_generic_function::<&str>: - | 33| 1|pub fn used_only_from_bin_crate_generic_function(arg: T) { - | 34| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg); - | 35| 1|} + | 39| 1|pub fn used_only_from_bin_crate_generic_function(arg: T) { + | 40| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg); + | 41| 1|} ------------------ | Unexecuted instantiation: used_inline_crate::used_only_from_bin_crate_generic_function::<_> ------------------ - 36| |// Expect for above function: `Unexecuted instantiation` (see notes in `used_crate.rs`) - 37| | - 38| |#[inline(always)] - 39| 4|pub fn used_only_from_this_lib_crate_generic_function(arg: T) { - 40| 4| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg); - 41| 4|} + 42| |// Expect for above function: `Unexecuted instantiation` (see notes in `used_crate.rs`) + 43| | + 44| |#[inline(always)] + 45| 4|pub fn used_only_from_this_lib_crate_generic_function(arg: T) { + 46| 4| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg); + 47| 4|} ------------------ | used_inline_crate::used_only_from_this_lib_crate_generic_function::>: - | 39| 2|pub fn used_only_from_this_lib_crate_generic_function(arg: T) { - | 40| 2| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg); - | 41| 2|} + | 45| 2|pub fn used_only_from_this_lib_crate_generic_function(arg: T) { + | 46| 2| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg); + | 47| 2|} ------------------ | used_inline_crate::used_only_from_this_lib_crate_generic_function::<&str>: - | 39| 2|pub fn used_only_from_this_lib_crate_generic_function(arg: T) { - | 40| 2| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg); - | 41| 2|} + | 45| 2|pub fn used_only_from_this_lib_crate_generic_function(arg: T) { + | 46| 2| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg); + | 47| 2|} ------------------ - 42| | - 43| |#[inline(always)] - 44| 3|pub fn used_from_bin_crate_and_lib_crate_generic_function(arg: T) { - 45| 3| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); - 46| 3|} + 48| | + 49| |#[inline(always)] + 50| 3|pub fn used_from_bin_crate_and_lib_crate_generic_function(arg: T) { + 51| 3| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); + 52| 3|} ------------------ | used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::>: - | 44| 1|pub fn used_from_bin_crate_and_lib_crate_generic_function(arg: T) { - | 45| 1| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); - | 46| 1|} + | 50| 1|pub fn used_from_bin_crate_and_lib_crate_generic_function(arg: T) { + | 51| 1| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); + | 52| 1|} ------------------ | used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::<&str>: - | 44| 2|pub fn used_from_bin_crate_and_lib_crate_generic_function(arg: T) { - | 45| 2| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); - | 46| 2|} + | 50| 2|pub fn used_from_bin_crate_and_lib_crate_generic_function(arg: T) { + | 51| 2| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); + | 52| 2|} ------------------ - 47| | - 48| |#[inline(always)] - 49| 3|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function(arg: T) { - 50| 3| println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); - 51| 3|} + 53| | + 54| |#[inline(always)] + 55| 3|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function(arg: T) { + 56| 3| println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); + 57| 3|} ------------------ | used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>: - | 49| 1|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function(arg: T) { - | 50| 1| println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); - | 51| 1|} + | 55| 1|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function(arg: T) { + | 56| 1| println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); + | 57| 1|} ------------------ | used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>: - | 49| 2|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function(arg: T) { - | 50| 2| println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); - | 51| 2|} + | 55| 2|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function(arg: T) { + | 56| 2| println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); + | 57| 2|} ------------------ - 52| | - 53| |#[inline(always)] - 54| 0|pub fn unused_generic_function(arg: T) { - 55| 0| println!("unused_generic_function with {:?}", arg); - 56| 0|} - 57| | - 58| |#[inline(always)] - 59| 0|pub fn unused_function() { - 60| 0| let is_true = std::env::args().len() == 1; - 61| 0| let mut countdown = 2; - 62| 0| if !is_true { - 63| 0| countdown = 20; - 64| 0| } - 65| 0|} - 66| | - 67| |#[inline(always)] - 68| 0|fn unused_private_function() { - 69| 0| let is_true = std::env::args().len() == 1; - 70| 0| let mut countdown = 2; - 71| 0| if !is_true { - 72| 0| countdown = 20; - 73| 0| } - 74| 0|} - 75| | - 76| 2|fn use_this_lib_crate() { - 77| 2| used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs"); - 78| 2| used_with_same_type_from_bin_crate_and_lib_crate_generic_function( - 79| 2| "used from library used_crate.rs", - 80| 2| ); - 81| 2| let some_vec = vec![5, 6, 7, 8]; - 82| 2| used_only_from_this_lib_crate_generic_function(some_vec); - 83| 2| used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs"); - 84| 2|} + 58| | + 59| |#[inline(always)] + 60| 0|pub fn unused_generic_function(arg: T) { + 61| 0| println!("unused_generic_function with {:?}", arg); + 62| 0|} + 63| | + 64| |#[inline(always)] + 65| 0|pub fn unused_function() { + 66| 0| let is_true = std::env::args().len() == 1; + 67| 0| let mut countdown = 2; + 68| 0| if !is_true { + 69| 0| countdown = 20; + 70| 0| } + 71| 0|} + 72| | + 73| |#[inline(always)] + 74| 0|fn unused_private_function() { + 75| 0| let is_true = std::env::args().len() == 1; + 76| 0| let mut countdown = 2; + 77| 0| if !is_true { + 78| 0| countdown = 20; + 79| 0| } + 80| 0|} + 81| | + 82| 2|fn use_this_lib_crate() { + 83| 2| used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs"); + 84| 2| used_with_same_type_from_bin_crate_and_lib_crate_generic_function( + 85| 2| "used from library used_crate.rs", + 86| 2| ); + 87| 2| let some_vec = vec![5, 6, 7, 8]; + 88| 2| used_only_from_this_lib_crate_generic_function(some_vec); + 89| 2| used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs"); + 90| 2|} diff --git a/src/test/run-make-fulldeps/coverage/lib/used_inline_crate.rs b/src/test/run-make-fulldeps/coverage/lib/used_inline_crate.rs index 249e99fccb8..4a052756d4e 100644 --- a/src/test/run-make-fulldeps/coverage/lib/used_inline_crate.rs +++ b/src/test/run-make-fulldeps/coverage/lib/used_inline_crate.rs @@ -29,6 +29,12 @@ pub fn used_inline_function() { use_this_lib_crate(); } + + + + + + #[inline(always)] pub fn used_only_from_bin_crate_generic_function(arg: T) { println!("used_only_from_bin_crate_generic_function with {:?}", arg); -- cgit 1.4.1-3-g733a5