|
1 |
| -use std::iter; |
| 1 | +use std::sync::Arc; |
2 | 2 |
|
3 | 3 | use itertools::Itertools;
|
4 | 4 | use rustc_abi::Align;
|
5 | 5 | use rustc_codegen_ssa::traits::{
|
6 | 6 | BaseTypeCodegenMethods, ConstCodegenMethods, StaticCodegenMethods,
|
7 | 7 | };
|
8 |
| -use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; |
| 8 | +use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; |
9 | 9 | use rustc_hir::def_id::{DefId, LocalDefId};
|
10 | 10 | use rustc_index::IndexVec;
|
11 | 11 | use rustc_middle::mir;
|
12 | 12 | use rustc_middle::ty::{self, TyCtxt};
|
13 | 13 | use rustc_session::RemapFileNameExt;
|
14 | 14 | use rustc_session::config::RemapPathScopeComponents;
|
15 | 15 | use rustc_span::def_id::DefIdSet;
|
16 |
| -use rustc_span::{Span, Symbol}; |
| 16 | +use rustc_span::{SourceFile, StableSourceFileId}; |
17 | 17 | use tracing::debug;
|
18 | 18 |
|
19 | 19 | use crate::common::CodegenCx;
|
@@ -132,45 +132,51 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
|
132 | 132 | generate_covmap_record(cx, covmap_version, &filenames_buffer);
|
133 | 133 | }
|
134 | 134 |
|
135 |
| -/// Maps "global" (per-CGU) file ID numbers to their underlying filenames. |
| 135 | +/// Maps "global" (per-CGU) file ID numbers to their underlying source files. |
136 | 136 | struct GlobalFileTable {
|
137 |
| - /// This "raw" table doesn't include the working dir, so a filename's |
| 137 | + /// This "raw" table doesn't include the working dir, so a file's |
138 | 138 | /// global ID is its index in this set **plus one**.
|
139 |
| - raw_file_table: FxIndexSet<Symbol>, |
| 139 | + raw_file_table: FxIndexMap<StableSourceFileId, Arc<SourceFile>>, |
140 | 140 | }
|
141 | 141 |
|
142 | 142 | impl GlobalFileTable {
|
143 | 143 | fn new() -> Self {
|
144 |
| - Self { raw_file_table: FxIndexSet::default() } |
| 144 | + Self { raw_file_table: FxIndexMap::default() } |
145 | 145 | }
|
146 | 146 |
|
147 |
| - fn global_file_id_for_file_name(&mut self, file_name: Symbol) -> GlobalFileId { |
| 147 | + fn global_file_id_for_file(&mut self, file: &Arc<SourceFile>) -> GlobalFileId { |
148 | 148 | // Ensure the given file has a table entry, and get its index.
|
149 |
| - let (raw_id, _) = self.raw_file_table.insert_full(file_name); |
| 149 | + let entry = self.raw_file_table.entry(file.stable_id); |
| 150 | + let raw_id = entry.index(); |
| 151 | + entry.or_insert_with(|| Arc::clone(file)); |
| 152 | + |
150 | 153 | // The raw file table doesn't include an entry for the working dir
|
151 | 154 | // (which has ID 0), so add 1 to get the correct ID.
|
152 | 155 | GlobalFileId::from_usize(raw_id + 1)
|
153 | 156 | }
|
154 | 157 |
|
155 | 158 | fn make_filenames_buffer(&self, tcx: TyCtxt<'_>) -> Vec<u8> {
|
| 159 | + let mut table = Vec::with_capacity(self.raw_file_table.len() + 1); |
| 160 | + |
156 | 161 | // LLVM Coverage Mapping Format version 6 (zero-based encoded as 5)
|
157 | 162 | // requires setting the first filename to the compilation directory.
|
158 | 163 | // Since rustc generates coverage maps with relative paths, the
|
159 | 164 | // compilation directory can be combined with the relative paths
|
160 | 165 | // to get absolute paths, if needed.
|
161 |
| - use rustc_session::RemapFileNameExt; |
162 |
| - use rustc_session::config::RemapPathScopeComponents; |
163 |
| - let working_dir: &str = &tcx |
164 |
| - .sess |
165 |
| - .opts |
166 |
| - .working_dir |
167 |
| - .for_scope(tcx.sess, RemapPathScopeComponents::MACRO) |
168 |
| - .to_string_lossy(); |
169 |
| - |
170 |
| - // Insert the working dir at index 0, before the other filenames. |
171 |
| - let filenames = |
172 |
| - iter::once(working_dir).chain(self.raw_file_table.iter().map(Symbol::as_str)); |
173 |
| - llvm_cov::write_filenames_to_buffer(filenames) |
| 166 | + table.push( |
| 167 | + tcx.sess |
| 168 | + .opts |
| 169 | + .working_dir |
| 170 | + .for_scope(tcx.sess, RemapPathScopeComponents::MACRO) |
| 171 | + .to_string_lossy(), |
| 172 | + ); |
| 173 | + |
| 174 | + // Add the regular entries after the base directory. |
| 175 | + table.extend(self.raw_file_table.values().map(|file| { |
| 176 | + file.name.for_scope(tcx.sess, RemapPathScopeComponents::MACRO).to_string_lossy() |
| 177 | + })); |
| 178 | + |
| 179 | + llvm_cov::write_filenames_to_buffer(&table) |
174 | 180 | }
|
175 | 181 | }
|
176 | 182 |
|
@@ -209,13 +215,6 @@ impl VirtualFileMapping {
|
209 | 215 | }
|
210 | 216 | }
|
211 | 217 |
|
212 |
| -fn span_file_name(tcx: TyCtxt<'_>, span: Span) -> Symbol { |
213 |
| - let source_file = tcx.sess.source_map().lookup_source_file(span.lo()); |
214 |
| - let name = |
215 |
| - source_file.name.for_scope(tcx.sess, RemapPathScopeComponents::MACRO).to_string_lossy(); |
216 |
| - Symbol::intern(&name) |
217 |
| -} |
218 |
| - |
219 | 218 | /// Generates the contents of the covmap record for this CGU, which mostly
|
220 | 219 | /// consists of a header and a list of filenames. The record is then stored
|
221 | 220 | /// as a global variable in the `__llvm_covmap` section.
|
|
0 commit comments