Skip to content

Commit

Permalink
Merge pull request rust-lang#1266 from bjorn3/parallel_comp_refactor2
Browse files Browse the repository at this point in the history
Refactorings for enabling parallel compilation (part 2)
  • Loading branch information
bjorn3 authored Aug 19, 2022
2 parents 4dac65f + 535c6dd commit 7dc8f38
Show file tree
Hide file tree
Showing 10 changed files with 283 additions and 509 deletions.
122 changes: 51 additions & 71 deletions src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,48 +7,44 @@ use rustc_middle::ty::layout::FnAbiOf;
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::SymbolName;

use indexmap::IndexSet;

use crate::constant::ConstantCx;
use crate::debuginfo::FunctionDebugContext;
use crate::prelude::*;
use crate::pretty_clif::CommentWriter;

struct CodegenedFunction<'tcx> {
instance: Instance<'tcx>,
symbol_name: SymbolName<'tcx>,
func_id: FuncId,
func: Function,
clif_comments: CommentWriter,
source_info_set: IndexSet<SourceInfo>,
local_map: IndexVec<mir::Local, CPlace<'tcx>>,
func_debug_cx: Option<FunctionDebugContext>,
}

pub(crate) fn codegen_and_compile_fn<'tcx>(
cx: &mut crate::CodegenCx<'tcx>,
tcx: TyCtxt<'tcx>,
cx: &mut crate::CodegenCx,
cached_context: &mut Context,
module: &mut dyn Module,
instance: Instance<'tcx>,
) {
let tcx = cx.tcx;
let _inst_guard =
crate::PrintOnPanic(|| format!("{:?} {}", instance, tcx.symbol_name(instance).name));

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

compile_fn(cx, cached_context, module, codegened_func);
}

fn codegen_fn<'tcx>(
cx: &mut crate::CodegenCx<'tcx>,
tcx: TyCtxt<'tcx>,
cx: &mut crate::CodegenCx,
cached_func: Function,
module: &mut dyn Module,
instance: Instance<'tcx>,
) -> CodegenedFunction<'tcx> {
debug_assert!(!instance.substs.needs_infer());

let tcx = cx.tcx;

let mir = tcx.instance_mir(instance.def);
let _mir_guard = crate::PrintOnPanic(|| {
let mut buf = Vec::new();
Expand Down Expand Up @@ -84,13 +80,20 @@ fn codegen_fn<'tcx>(
let pointer_type = target_config.pointer_type();
let clif_comments = crate::pretty_clif::CommentWriter::new(tcx, instance);

let func_debug_cx = if let Some(debug_context) = &mut cx.debug_context {
Some(debug_context.define_function(tcx, symbol_name.name, mir.span))
} else {
None
};

let mut fx = FunctionCx {
cx,
module,
tcx,
target_config,
pointer_type,
constants_cx: ConstantCx::new(),
func_debug_cx,

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

clif_comments,
source_info_set: indexmap::IndexSet::new(),
last_source_file: None,
next_ssa_var: 0,
};

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

// Recover all necessary data from fx, before accessing func will prevent future access to it.
let instance = fx.instance;
let clif_comments = fx.clif_comments;
let source_info_set = fx.source_info_set;
let local_map = fx.local_map;
let func_debug_cx = fx.func_debug_cx;

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

crate::pretty_clif::write_clif_file(
tcx,
"unopt",
module.isa(),
instance,
&func,
&clif_comments,
);
if cx.should_write_ir {
crate::pretty_clif::write_clif_file(
tcx.output_filenames(()),
symbol_name.name,
"unopt",
module.isa(),
&func,
&clif_comments,
);
}

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

CodegenedFunction {
instance,
symbol_name,
func_id,
func,
clif_comments,
source_info_set,
local_map,
}
CodegenedFunction { symbol_name, func_id, func, clif_comments, func_debug_cx }
}

fn compile_fn<'tcx>(
cx: &mut crate::CodegenCx<'tcx>,
cx: &mut crate::CodegenCx,
cached_context: &mut Context,
module: &mut dyn Module,
codegened_func: CodegenedFunction<'tcx>,
) {
let tcx = cx.tcx;

let mut clif_comments = codegened_func.clif_comments;
let clif_comments = codegened_func.clif_comments;

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

// Perform rust specific optimizations
tcx.sess.time("optimize clif ir", || {
crate::optimize::optimize_function(
tcx,
module.isa(),
codegened_func.instance,
context,
&mut clif_comments,
);
});

#[cfg(any())] // This is never true
let _clif_guard = {
use std::fmt::Write;
Expand Down Expand Up @@ -204,43 +186,41 @@ fn compile_fn<'tcx>(
};

// Define function
tcx.sess.time("define function", || {
context.want_disasm = crate::pretty_clif::should_write_ir(tcx);
cx.profiler.verbose_generic_activity("define function").run(|| {
context.want_disasm = cx.should_write_ir;
module.define_function(codegened_func.func_id, context).unwrap();
});

// Write optimized function to file for debugging
crate::pretty_clif::write_clif_file(
tcx,
"opt",
module.isa(),
codegened_func.instance,
&context.func,
&clif_comments,
);
if cx.should_write_ir {
// Write optimized function to file for debugging
crate::pretty_clif::write_clif_file(
&cx.output_filenames,
codegened_func.symbol_name.name,
"opt",
module.isa(),
&context.func,
&clif_comments,
);

if let Some(disasm) = &context.mach_compile_result.as_ref().unwrap().disasm {
crate::pretty_clif::write_ir_file(
tcx,
|| format!("{}.vcode", tcx.symbol_name(codegened_func.instance).name),
|file| file.write_all(disasm.as_bytes()),
)
if let Some(disasm) = &context.mach_compile_result.as_ref().unwrap().disasm {
crate::pretty_clif::write_ir_file(
&cx.output_filenames,
&format!("{}.vcode", codegened_func.symbol_name.name),
|file| file.write_all(disasm.as_bytes()),
)
}
}

// Define debuginfo for function
let isa = module.isa();
let debug_context = &mut cx.debug_context;
let unwind_context = &mut cx.unwind_context;
tcx.sess.time("generate debug info", || {
cx.profiler.verbose_generic_activity("generate debug info").run(|| {
if let Some(debug_context) = debug_context {
debug_context.define_function(
codegened_func.instance,
codegened_func.func_debug_cx.unwrap().finalize(
debug_context,
codegened_func.func_id,
codegened_func.symbol_name.name,
isa,
context,
&codegened_func.source_info_set,
codegened_func.local_map,
);
}
unwind_context.add_function(codegened_func.func_id, &context, isa);
Expand Down
41 changes: 37 additions & 4 deletions src/common.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
use cranelift_codegen::isa::TargetFrontendConfig;
use gimli::write::FileId;

use rustc_data_structures::sync::Lrc;
use rustc_index::vec::IndexVec;
use rustc_middle::ty::layout::{
FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOfHelpers,
};
use rustc_middle::ty::SymbolName;
use rustc_span::SourceFile;
use rustc_target::abi::call::FnAbi;
use rustc_target::abi::{Integer, Primitive};
use rustc_target::spec::{HasTargetSpec, Target};

use crate::constant::ConstantCx;
use crate::debuginfo::FunctionDebugContext;
use crate::prelude::*;

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

pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> {
pub(crate) cx: &'clif mut crate::CodegenCx<'tcx>,
pub(crate) cx: &'clif mut crate::CodegenCx,
pub(crate) module: &'m mut dyn Module,
pub(crate) tcx: TyCtxt<'tcx>,
pub(crate) target_config: TargetFrontendConfig, // Cached from module
pub(crate) pointer_type: Type, // Cached from module
pub(crate) constants_cx: ConstantCx,
pub(crate) func_debug_cx: Option<FunctionDebugContext>,

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

pub(crate) clif_comments: crate::pretty_clif::CommentWriter,
pub(crate) source_info_set: indexmap::IndexSet<SourceInfo>,

/// Last accessed source file and it's debuginfo file id.
///
/// For optimization purposes only
pub(crate) last_source_file: Option<(Lrc<SourceFile>, FileId)>,

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

pub(crate) fn set_debug_loc(&mut self, source_info: mir::SourceInfo) {
let (index, _) = self.source_info_set.insert_full(source_info);
self.bcx.set_srcloc(SourceLoc::new(index as u32));
if let Some(debug_context) = &mut self.cx.debug_context {
let (file, line, column) =
DebugContext::get_span_loc(self.tcx, self.mir.span, source_info.span);

// add_source_file is very slow.
// Optimize for the common case of the current file not being changed.
let mut cached_file_id = None;
if let Some((ref last_source_file, last_file_id)) = self.last_source_file {
// If the allocations are not equal, the files may still be equal, but that
// doesn't matter, as this is just an optimization.
if rustc_data_structures::sync::Lrc::ptr_eq(last_source_file, &file) {
cached_file_id = Some(last_file_id);
}
}

let file_id = if let Some(file_id) = cached_file_id {
file_id
} else {
debug_context.add_source_file(&file)
};

let source_loc =
self.func_debug_cx.as_mut().unwrap().add_dbg_loc(file_id, line, column);
self.bcx.set_srcloc(source_loc);
}
}

// Note: must be kept in sync with get_caller_location from cg_ssa
Expand Down
2 changes: 1 addition & 1 deletion src/debuginfo/emit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use gimli::{RunTimeEndian, SectionId};
use super::object::WriteDebugInfo;
use super::DebugContext;

impl DebugContext<'_> {
impl DebugContext {
pub(crate) fn emit(&mut self, product: &mut ObjectProduct) {
let unit_range_list_id = self.dwarf.unit.ranges.add(self.unit_range_list.clone());
let root = self.dwarf.unit.root();
Expand Down
Loading

0 comments on commit 7dc8f38

Please sign in to comment.