Skip to content

Commit 7dc8f38

Browse files
authored
Merge pull request #1266 from bjorn3/parallel_comp_refactor2
Refactorings for enabling parallel compilation (part 2)
2 parents 4dac65f + 535c6dd commit 7dc8f38

File tree

10 files changed

+283
-509
lines changed

10 files changed

+283
-509
lines changed

src/base.rs

+51-71
Original file line numberDiff line numberDiff line change
@@ -7,48 +7,44 @@ use rustc_middle::ty::layout::FnAbiOf;
77
use rustc_middle::ty::print::with_no_trimmed_paths;
88
use rustc_middle::ty::SymbolName;
99

10-
use indexmap::IndexSet;
11-
1210
use crate::constant::ConstantCx;
11+
use crate::debuginfo::FunctionDebugContext;
1312
use crate::prelude::*;
1413
use crate::pretty_clif::CommentWriter;
1514

1615
struct CodegenedFunction<'tcx> {
17-
instance: Instance<'tcx>,
1816
symbol_name: SymbolName<'tcx>,
1917
func_id: FuncId,
2018
func: Function,
2119
clif_comments: CommentWriter,
22-
source_info_set: IndexSet<SourceInfo>,
23-
local_map: IndexVec<mir::Local, CPlace<'tcx>>,
20+
func_debug_cx: Option<FunctionDebugContext>,
2421
}
2522

2623
pub(crate) fn codegen_and_compile_fn<'tcx>(
27-
cx: &mut crate::CodegenCx<'tcx>,
24+
tcx: TyCtxt<'tcx>,
25+
cx: &mut crate::CodegenCx,
2826
cached_context: &mut Context,
2927
module: &mut dyn Module,
3028
instance: Instance<'tcx>,
3129
) {
32-
let tcx = cx.tcx;
3330
let _inst_guard =
3431
crate::PrintOnPanic(|| format!("{:?} {}", instance, tcx.symbol_name(instance).name));
3532

3633
let cached_func = std::mem::replace(&mut cached_context.func, Function::new());
37-
let codegened_func = codegen_fn(cx, cached_func, module, instance);
34+
let codegened_func = codegen_fn(tcx, cx, cached_func, module, instance);
3835

3936
compile_fn(cx, cached_context, module, codegened_func);
4037
}
4138

4239
fn codegen_fn<'tcx>(
43-
cx: &mut crate::CodegenCx<'tcx>,
40+
tcx: TyCtxt<'tcx>,
41+
cx: &mut crate::CodegenCx,
4442
cached_func: Function,
4543
module: &mut dyn Module,
4644
instance: Instance<'tcx>,
4745
) -> CodegenedFunction<'tcx> {
4846
debug_assert!(!instance.substs.needs_infer());
4947

50-
let tcx = cx.tcx;
51-
5248
let mir = tcx.instance_mir(instance.def);
5349
let _mir_guard = crate::PrintOnPanic(|| {
5450
let mut buf = Vec::new();
@@ -84,13 +80,20 @@ fn codegen_fn<'tcx>(
8480
let pointer_type = target_config.pointer_type();
8581
let clif_comments = crate::pretty_clif::CommentWriter::new(tcx, instance);
8682

83+
let func_debug_cx = if let Some(debug_context) = &mut cx.debug_context {
84+
Some(debug_context.define_function(tcx, symbol_name.name, mir.span))
85+
} else {
86+
None
87+
};
88+
8789
let mut fx = FunctionCx {
8890
cx,
8991
module,
9092
tcx,
9193
target_config,
9294
pointer_type,
9395
constants_cx: ConstantCx::new(),
96+
func_debug_cx,
9497

9598
instance,
9699
symbol_name,
@@ -103,52 +106,42 @@ fn codegen_fn<'tcx>(
103106
caller_location: None, // set by `codegen_fn_prelude`
104107

105108
clif_comments,
106-
source_info_set: indexmap::IndexSet::new(),
109+
last_source_file: None,
107110
next_ssa_var: 0,
108111
};
109112

110113
tcx.sess.time("codegen clif ir", || codegen_fn_body(&mut fx, start_block));
111114

112115
// Recover all necessary data from fx, before accessing func will prevent future access to it.
113-
let instance = fx.instance;
114116
let clif_comments = fx.clif_comments;
115-
let source_info_set = fx.source_info_set;
116-
let local_map = fx.local_map;
117+
let func_debug_cx = fx.func_debug_cx;
117118

118119
fx.constants_cx.finalize(fx.tcx, &mut *fx.module);
119120

120-
crate::pretty_clif::write_clif_file(
121-
tcx,
122-
"unopt",
123-
module.isa(),
124-
instance,
125-
&func,
126-
&clif_comments,
127-
);
121+
if cx.should_write_ir {
122+
crate::pretty_clif::write_clif_file(
123+
tcx.output_filenames(()),
124+
symbol_name.name,
125+
"unopt",
126+
module.isa(),
127+
&func,
128+
&clif_comments,
129+
);
130+
}
128131

129132
// Verify function
130133
verify_func(tcx, &clif_comments, &func);
131134

132-
CodegenedFunction {
133-
instance,
134-
symbol_name,
135-
func_id,
136-
func,
137-
clif_comments,
138-
source_info_set,
139-
local_map,
140-
}
135+
CodegenedFunction { symbol_name, func_id, func, clif_comments, func_debug_cx }
141136
}
142137

143138
fn compile_fn<'tcx>(
144-
cx: &mut crate::CodegenCx<'tcx>,
139+
cx: &mut crate::CodegenCx,
145140
cached_context: &mut Context,
146141
module: &mut dyn Module,
147142
codegened_func: CodegenedFunction<'tcx>,
148143
) {
149-
let tcx = cx.tcx;
150-
151-
let mut clif_comments = codegened_func.clif_comments;
144+
let clif_comments = codegened_func.clif_comments;
152145

153146
// Store function in context
154147
let context = cached_context;
@@ -165,17 +158,6 @@ fn compile_fn<'tcx>(
165158
// invalidate it when it would change.
166159
context.domtree.clear();
167160

168-
// Perform rust specific optimizations
169-
tcx.sess.time("optimize clif ir", || {
170-
crate::optimize::optimize_function(
171-
tcx,
172-
module.isa(),
173-
codegened_func.instance,
174-
context,
175-
&mut clif_comments,
176-
);
177-
});
178-
179161
#[cfg(any())] // This is never true
180162
let _clif_guard = {
181163
use std::fmt::Write;
@@ -204,43 +186,41 @@ fn compile_fn<'tcx>(
204186
};
205187

206188
// Define function
207-
tcx.sess.time("define function", || {
208-
context.want_disasm = crate::pretty_clif::should_write_ir(tcx);
189+
cx.profiler.verbose_generic_activity("define function").run(|| {
190+
context.want_disasm = cx.should_write_ir;
209191
module.define_function(codegened_func.func_id, context).unwrap();
210192
});
211193

212-
// Write optimized function to file for debugging
213-
crate::pretty_clif::write_clif_file(
214-
tcx,
215-
"opt",
216-
module.isa(),
217-
codegened_func.instance,
218-
&context.func,
219-
&clif_comments,
220-
);
194+
if cx.should_write_ir {
195+
// Write optimized function to file for debugging
196+
crate::pretty_clif::write_clif_file(
197+
&cx.output_filenames,
198+
codegened_func.symbol_name.name,
199+
"opt",
200+
module.isa(),
201+
&context.func,
202+
&clif_comments,
203+
);
221204

222-
if let Some(disasm) = &context.mach_compile_result.as_ref().unwrap().disasm {
223-
crate::pretty_clif::write_ir_file(
224-
tcx,
225-
|| format!("{}.vcode", tcx.symbol_name(codegened_func.instance).name),
226-
|file| file.write_all(disasm.as_bytes()),
227-
)
205+
if let Some(disasm) = &context.mach_compile_result.as_ref().unwrap().disasm {
206+
crate::pretty_clif::write_ir_file(
207+
&cx.output_filenames,
208+
&format!("{}.vcode", codegened_func.symbol_name.name),
209+
|file| file.write_all(disasm.as_bytes()),
210+
)
211+
}
228212
}
229213

230214
// Define debuginfo for function
231215
let isa = module.isa();
232216
let debug_context = &mut cx.debug_context;
233217
let unwind_context = &mut cx.unwind_context;
234-
tcx.sess.time("generate debug info", || {
218+
cx.profiler.verbose_generic_activity("generate debug info").run(|| {
235219
if let Some(debug_context) = debug_context {
236-
debug_context.define_function(
237-
codegened_func.instance,
220+
codegened_func.func_debug_cx.unwrap().finalize(
221+
debug_context,
238222
codegened_func.func_id,
239-
codegened_func.symbol_name.name,
240-
isa,
241223
context,
242-
&codegened_func.source_info_set,
243-
codegened_func.local_map,
244224
);
245225
}
246226
unwind_context.add_function(codegened_func.func_id, &context, isa);

src/common.rs

+37-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
use cranelift_codegen::isa::TargetFrontendConfig;
2+
use gimli::write::FileId;
3+
4+
use rustc_data_structures::sync::Lrc;
25
use rustc_index::vec::IndexVec;
36
use rustc_middle::ty::layout::{
47
FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOfHelpers,
58
};
69
use rustc_middle::ty::SymbolName;
10+
use rustc_span::SourceFile;
711
use rustc_target::abi::call::FnAbi;
812
use rustc_target::abi::{Integer, Primitive};
913
use rustc_target::spec::{HasTargetSpec, Target};
1014

1115
use crate::constant::ConstantCx;
16+
use crate::debuginfo::FunctionDebugContext;
1217
use crate::prelude::*;
1318

1419
pub(crate) fn pointer_ty(tcx: TyCtxt<'_>) -> types::Type {
@@ -232,12 +237,13 @@ pub(crate) fn type_sign(ty: Ty<'_>) -> bool {
232237
}
233238

234239
pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> {
235-
pub(crate) cx: &'clif mut crate::CodegenCx<'tcx>,
240+
pub(crate) cx: &'clif mut crate::CodegenCx,
236241
pub(crate) module: &'m mut dyn Module,
237242
pub(crate) tcx: TyCtxt<'tcx>,
238243
pub(crate) target_config: TargetFrontendConfig, // Cached from module
239244
pub(crate) pointer_type: Type, // Cached from module
240245
pub(crate) constants_cx: ConstantCx,
246+
pub(crate) func_debug_cx: Option<FunctionDebugContext>,
241247

242248
pub(crate) instance: Instance<'tcx>,
243249
pub(crate) symbol_name: SymbolName<'tcx>,
@@ -252,7 +258,11 @@ pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> {
252258
pub(crate) caller_location: Option<CValue<'tcx>>,
253259

254260
pub(crate) clif_comments: crate::pretty_clif::CommentWriter,
255-
pub(crate) source_info_set: indexmap::IndexSet<SourceInfo>,
261+
262+
/// Last accessed source file and it's debuginfo file id.
263+
///
264+
/// For optimization purposes only
265+
pub(crate) last_source_file: Option<(Lrc<SourceFile>, FileId)>,
256266

257267
/// This should only be accessed by `CPlace::new_var`.
258268
pub(crate) next_ssa_var: u32,
@@ -336,8 +346,31 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
336346
}
337347

338348
pub(crate) fn set_debug_loc(&mut self, source_info: mir::SourceInfo) {
339-
let (index, _) = self.source_info_set.insert_full(source_info);
340-
self.bcx.set_srcloc(SourceLoc::new(index as u32));
349+
if let Some(debug_context) = &mut self.cx.debug_context {
350+
let (file, line, column) =
351+
DebugContext::get_span_loc(self.tcx, self.mir.span, source_info.span);
352+
353+
// add_source_file is very slow.
354+
// Optimize for the common case of the current file not being changed.
355+
let mut cached_file_id = None;
356+
if let Some((ref last_source_file, last_file_id)) = self.last_source_file {
357+
// If the allocations are not equal, the files may still be equal, but that
358+
// doesn't matter, as this is just an optimization.
359+
if rustc_data_structures::sync::Lrc::ptr_eq(last_source_file, &file) {
360+
cached_file_id = Some(last_file_id);
361+
}
362+
}
363+
364+
let file_id = if let Some(file_id) = cached_file_id {
365+
file_id
366+
} else {
367+
debug_context.add_source_file(&file)
368+
};
369+
370+
let source_loc =
371+
self.func_debug_cx.as_mut().unwrap().add_dbg_loc(file_id, line, column);
372+
self.bcx.set_srcloc(source_loc);
373+
}
341374
}
342375

343376
// Note: must be kept in sync with get_caller_location from cg_ssa

src/debuginfo/emit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use gimli::{RunTimeEndian, SectionId};
99
use super::object::WriteDebugInfo;
1010
use super::DebugContext;
1111

12-
impl DebugContext<'_> {
12+
impl DebugContext {
1313
pub(crate) fn emit(&mut self, product: &mut ObjectProduct) {
1414
let unit_range_list_id = self.dwarf.unit.ranges.add(self.unit_range_list.clone());
1515
let root = self.dwarf.unit.root();

0 commit comments

Comments
 (0)