forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add spans to injected coverage counters
added regions with counter expressions and counters. Added codegen_llvm/coverageinfo mod for upcoming coverage map Move coverage region collection to CodegenCx finalization Moved from `query coverageinfo` (renamed from `query coverage_data`), as discussed in the PR at: rust-lang#73684 (comment) Address merge conflict in MIR instrument_coverage test The MIR test output format changed for int types. moved debug messages out of block.rs This makes the block.rs calls to add coverage mapping data to the CodegenCx much more concise and readable. move coverage intrinsic handling into llvm impl I realized that having half of the coverage intrinsic handling in `rustc_codegen_ssa` and half in `rustc_codegen_llvm` meant that any non-llvm backend would be bound to the same decisions about how the coverage-related MIR terminators should be handled. To fix this, I moved the non-codegen portion of coverage intrinsic handling into its own trait, and implemented it in `rustc_codegen_llvm` alongside `codegen_intrinsic_call`. I also added the (required?) stubs for the new intrinsics to `IntrepretCx::emulate_intrinsic()`, to ensure calls to this function do not fail if called with these new but known intrinsics. address PR Feedback on 28 June 2020 2:48pm PDT
- Loading branch information
Showing
27 changed files
with
585 additions
and
93 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
use crate::builder::Builder; | ||
use crate::common::CodegenCx; | ||
use log::debug; | ||
use rustc_codegen_ssa::coverageinfo::map::*; | ||
use rustc_codegen_ssa::traits::{CoverageInfoBuilderMethods, CoverageInfoMethods}; | ||
use rustc_data_structures::fx::FxHashMap; | ||
use rustc_middle::ty::Instance; | ||
|
||
use std::cell::RefCell; | ||
|
||
/// A context object for maintaining all state needed by the coverageinfo module. | ||
pub struct CrateCoverageContext<'tcx> { | ||
// Coverage region data for each instrumented function identified by DefId. | ||
pub(crate) coverage_regions: RefCell<FxHashMap<Instance<'tcx>, FunctionCoverageRegions>>, | ||
} | ||
|
||
impl<'tcx> CrateCoverageContext<'tcx> { | ||
pub fn new() -> Self { | ||
Self { coverage_regions: Default::default() } | ||
} | ||
} | ||
|
||
/// Generates and exports the Coverage Map. | ||
// FIXME(richkadel): Actually generate and export the coverage map to LLVM. | ||
// The current implementation is actually just debug messages to show the data is available. | ||
pub fn finalize(cx: &CodegenCx<'_, '_>) { | ||
let coverage_regions = &*cx.coverage_context().coverage_regions.borrow(); | ||
for instance in coverage_regions.keys() { | ||
let coverageinfo = cx.tcx.coverageinfo(instance.def_id()); | ||
debug_assert!(coverageinfo.num_counters > 0); | ||
debug!( | ||
"Generate coverage map for: {:?}, hash: {}, num_counters: {}", | ||
instance, coverageinfo.hash, coverageinfo.num_counters | ||
); | ||
let function_coverage_regions = &coverage_regions[instance]; | ||
for (index, region) in function_coverage_regions.indexed_regions() { | ||
match region.kind { | ||
CoverageKind::Counter => debug!( | ||
" Counter {}, for {}..{}", | ||
index, region.coverage_span.start_byte_pos, region.coverage_span.end_byte_pos | ||
), | ||
CoverageKind::CounterExpression(lhs, op, rhs) => debug!( | ||
" CounterExpression {} = {} {:?} {}, for {}..{}", | ||
index, | ||
lhs, | ||
op, | ||
rhs, | ||
region.coverage_span.start_byte_pos, | ||
region.coverage_span.end_byte_pos | ||
), | ||
} | ||
} | ||
for unreachable in function_coverage_regions.unreachable_regions() { | ||
debug!( | ||
" Unreachable code region: {}..{}", | ||
unreachable.start_byte_pos, unreachable.end_byte_pos | ||
); | ||
} | ||
} | ||
} | ||
|
||
impl CoverageInfoMethods for CodegenCx<'ll, 'tcx> { | ||
fn coverageinfo_finalize(&self) { | ||
finalize(self) | ||
} | ||
} | ||
|
||
impl CoverageInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { | ||
fn add_counter_region( | ||
&mut self, | ||
instance: Instance<'tcx>, | ||
index: u32, | ||
start_byte_pos: u32, | ||
end_byte_pos: u32, | ||
) { | ||
debug!( | ||
"adding counter to coverage map: instance={:?}, index={}, byte range {}..{}", | ||
instance, index, start_byte_pos, end_byte_pos, | ||
); | ||
let mut coverage_regions = self.coverage_context().coverage_regions.borrow_mut(); | ||
coverage_regions.entry(instance).or_default().add_counter( | ||
index, | ||
start_byte_pos, | ||
end_byte_pos, | ||
); | ||
} | ||
|
||
fn add_counter_expression_region( | ||
&mut self, | ||
instance: Instance<'tcx>, | ||
index: u32, | ||
lhs: u32, | ||
op: CounterOp, | ||
rhs: u32, | ||
start_byte_pos: u32, | ||
end_byte_pos: u32, | ||
) { | ||
debug!( | ||
"adding counter expression to coverage map: instance={:?}, index={}, {} {:?} {}, byte range {}..{}", | ||
instance, index, lhs, op, rhs, start_byte_pos, end_byte_pos, | ||
); | ||
let mut coverage_regions = self.coverage_context().coverage_regions.borrow_mut(); | ||
coverage_regions.entry(instance).or_default().add_counter_expression( | ||
index, | ||
lhs, | ||
op, | ||
rhs, | ||
start_byte_pos, | ||
end_byte_pos, | ||
); | ||
} | ||
|
||
fn add_unreachable_region( | ||
&mut self, | ||
instance: Instance<'tcx>, | ||
start_byte_pos: u32, | ||
end_byte_pos: u32, | ||
) { | ||
debug!( | ||
"adding unreachable code to coverage map: instance={:?}, byte range {}..{}", | ||
instance, start_byte_pos, end_byte_pos, | ||
); | ||
let mut coverage_regions = self.coverage_context().coverage_regions.borrow_mut(); | ||
coverage_regions.entry(instance).or_default().add_unreachable(start_byte_pos, end_byte_pos); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.