diff options
| author | Tomasz Miąsko <tomasz.miasko@gmail.com> | 2021-03-13 00:00:00 +0000 |
|---|---|---|
| committer | Tomasz Miąsko <tomasz.miasko@gmail.com> | 2021-03-15 23:26:03 +0100 |
| commit | 1796cc0e6c43f1958d746c94608503c900b3a28e (patch) | |
| tree | fdb3668caaed6a272c90ecffc699ef6296a23aa0 /compiler/rustc_mir/src | |
| parent | 107896c32d5dda4db508968ff34997a39d286966 (diff) | |
| download | rust-1796cc0e6c43f1958d746c94608503c900b3a28e.tar.gz rust-1796cc0e6c43f1958d746c94608503c900b3a28e.zip | |
Make source-based code coverage compatible with MIR inlining
When codegenning code coverage use the instance that coverage data was originally generated for, to ensure basic level of compatibility with MIR inlining.
Diffstat (limited to 'compiler/rustc_mir/src')
| -rw-r--r-- | compiler/rustc_mir/src/transform/coverage/query.rs | 41 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/inline.rs | 9 |
2 files changed, 32 insertions, 18 deletions
diff --git a/compiler/rustc_mir/src/transform/coverage/query.rs b/compiler/rustc_mir/src/transform/coverage/query.rs index 4b455a6a1ba..de8447f1974 100644 --- a/compiler/rustc_mir/src/transform/coverage/query.rs +++ b/compiler/rustc_mir/src/transform/coverage/query.rs @@ -1,8 +1,7 @@ use super::*; use rustc_middle::mir::coverage::*; -use rustc_middle::mir::visit::Visitor; -use rustc_middle::mir::{self, Coverage, CoverageInfo, Location}; +use rustc_middle::mir::{self, Body, Coverage, CoverageInfo}; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::def_id::DefId; @@ -85,10 +84,21 @@ impl CoverageVisitor { } } } -} -impl Visitor<'_> for CoverageVisitor { - fn visit_coverage(&mut self, coverage: &Coverage, _location: Location) { + fn visit_body(&mut self, body: &Body<'_>) { + for bb_data in body.basic_blocks().iter() { + for statement in bb_data.statements.iter() { + if let StatementKind::Coverage(box ref coverage) = statement.kind { + if is_inlined(body, statement) { + continue; + } + self.visit_coverage(coverage); + } + } + } + } + + fn visit_coverage(&mut self, coverage: &Coverage) { if self.add_missing_operands { match coverage.kind { CoverageKind::Expression { lhs, rhs, .. } => { @@ -129,10 +139,14 @@ fn coverageinfo_from_mir<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> CoverageInfo } fn covered_file_name<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option<Symbol> { - for bb_data in mir_body(tcx, def_id).basic_blocks().iter() { + let body = mir_body(tcx, def_id); + for bb_data in body.basic_blocks().iter() { for statement in bb_data.statements.iter() { if let StatementKind::Coverage(box ref coverage) = statement.kind { if let Some(code_region) = coverage.code_region.as_ref() { + if is_inlined(body, statement) { + continue; + } return Some(code_region.file_name); } } @@ -151,13 +165,17 @@ fn mir_body<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx mir::Body<'tcx> { } fn covered_code_regions<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Vec<&'tcx CodeRegion> { - mir_body(tcx, def_id) - .basic_blocks() + let body = mir_body(tcx, def_id); + body.basic_blocks() .iter() .map(|data| { data.statements.iter().filter_map(|statement| match statement.kind { StatementKind::Coverage(box ref coverage) => { - coverage.code_region.as_ref() // may be None + if is_inlined(body, statement) { + None + } else { + coverage.code_region.as_ref() // may be None + } } _ => None, }) @@ -165,3 +183,8 @@ fn covered_code_regions<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Vec<&'tcx Cod .flatten() .collect() } + +fn is_inlined(body: &Body<'_>, statement: &Statement<'_>) -> bool { + let scope_data = &body.source_scopes[statement.source_info.scope]; + scope_data.inlined.is_some() || scope_data.inlined_parent_scope.is_some() +} diff --git a/compiler/rustc_mir/src/transform/inline.rs b/compiler/rustc_mir/src/transform/inline.rs index cf85503b3d5..26e7555a61d 100644 --- a/compiler/rustc_mir/src/transform/inline.rs +++ b/compiler/rustc_mir/src/transform/inline.rs @@ -39,15 +39,6 @@ struct CallSite<'tcx> { /// Returns true if MIR inlining is enabled in the current compilation session. crate fn is_enabled(tcx: TyCtxt<'_>) -> bool { - if tcx.sess.opts.debugging_opts.instrument_coverage { - // Since `Inline` happens after `InstrumentCoverage`, the function-specific coverage - // counters can be invalidated, such as by merging coverage counter statements from - // a pre-inlined function into a different function. This kind of change is invalid, - // so inlining must be skipped. Note: This check is performed here so inlining can - // be disabled without preventing other optimizations (regardless of `mir_opt_level`). - return false; - } - if let Some(enabled) = tcx.sess.opts.debugging_opts.inline_mir { return enabled; } |
