diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2023-10-23 08:12:39 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-10-23 08:12:39 +0200 |
| commit | dde77f7a33ab64115102ba7d4bfd6ab9bb46253e (patch) | |
| tree | 323457aaae0fe169e4eb71334558dd45ef224828 /compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs | |
| parent | e86f9b6fceda43cecd839e288f40622eadd9e639 (diff) | |
| parent | 6af9fef08590fd499370a2f6cbbae9ceacf15336 (diff) | |
| download | rust-dde77f7a33ab64115102ba7d4bfd6ab9bb46253e.tar.gz rust-dde77f7a33ab64115102ba7d4bfd6ab9bb46253e.zip | |
Rollup merge of #117042 - Zalathar:file-table, r=cjgillot
coverage: Emit the filenames section before encoding per-function mappings When embedding coverage information in LLVM IR (and ultimately in the resulting binary), there are two main things that each CGU needs to emit: - A single `__llvm_covmap` record containing a coverage header, which mostly consists of a list of filenames used by the CGU's coverage mappings. - Several `__llvm_covfun` records, one for each instrumented function, each of which contains the hash of the list of filenames in the header. There is a kind of loose cyclic dependency between the two: we need the hash of the file table before we can emit the covfun records, but we need to traverse all of the instrumented functions in order to build the file table. The existing code works by processing the individual functions first. It lazily adds filenames to the file table, and stores the mostly-complete function records in a temporary list. After this it hashes the file table, emits the header (containing the file table), and then uses the hash to emit all of the function records. This PR reverses that order: first we traverse all of the functions (without trying to prepare their function records) to build a *complete* file table, and then emit it immediately. At this point we have the file table hash, so we can then proceed to build and emit all of the function records, without needing to store them in an intermediate list. --- Along the way, this PR makes some necessary changes that are also worthwhile in their own right: - We split `FunctionCoverage` into distinct collector/finished phases, which neatly avoids some borrow-checker hassles when extracting a function's final expression/mapping data. - We avoid having to re-sort a function's mappings when preparing the list of filenames that it uses.
Diffstat (limited to 'compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs')
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs index cf7c7e6be60..7d69756181a 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs @@ -3,7 +3,7 @@ use crate::llvm; use crate::builder::Builder; use crate::common::CodegenCx; use crate::coverageinfo::ffi::{CounterExpression, CounterMappingRegion}; -use crate::coverageinfo::map_data::FunctionCoverage; +use crate::coverageinfo::map_data::FunctionCoverageCollector; use libc::c_uint; use rustc_codegen_ssa::traits::{ @@ -29,7 +29,8 @@ const VAR_ALIGN_BYTES: usize = 8; /// A context object for maintaining all state needed by the coverageinfo module. pub struct CrateCoverageContext<'ll, 'tcx> { /// Coverage data for each instrumented function identified by DefId. - pub(crate) function_coverage_map: RefCell<FxHashMap<Instance<'tcx>, FunctionCoverage<'tcx>>>, + pub(crate) function_coverage_map: + RefCell<FxHashMap<Instance<'tcx>, FunctionCoverageCollector<'tcx>>>, pub(crate) pgo_func_name_var_map: RefCell<FxHashMap<Instance<'tcx>, &'ll llvm::Value>>, } @@ -41,7 +42,9 @@ impl<'ll, 'tcx> CrateCoverageContext<'ll, 'tcx> { } } - pub fn take_function_coverage_map(&self) -> FxHashMap<Instance<'tcx>, FunctionCoverage<'tcx>> { + pub fn take_function_coverage_map( + &self, + ) -> FxHashMap<Instance<'tcx>, FunctionCoverageCollector<'tcx>> { self.function_coverage_map.replace(FxHashMap::default()) } } @@ -93,7 +96,7 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> { let mut coverage_map = coverage_context.function_coverage_map.borrow_mut(); let func_coverage = coverage_map .entry(instance) - .or_insert_with(|| FunctionCoverage::new(instance, function_coverage_info)); + .or_insert_with(|| FunctionCoverageCollector::new(instance, function_coverage_info)); let Coverage { kind } = coverage; match *kind { |
