//! but one `llvm::Type` corresponds to many `Ty`s; for instance, `tup(int, int,
//! int)` and `rec(x=int, y=int, z=int)` will have the same `llvm::Type`.
-use super::{LlvmCodegenBackend, ModuleLlvm};
+use super::ModuleLlvm;
use crate::builder::Builder;
use crate::common;
use rustc::mir::mono::{Linkage, Visibility};
use rustc::session::config::DebugInfo;
use rustc::ty::TyCtxt;
-use rustc_codegen_ssa::back::write::submit_codegened_module_to_llvm;
use rustc_codegen_ssa::base::maybe_create_entry_wrapper;
use rustc_codegen_ssa::mono_item::MonoItemExt;
use rustc_codegen_ssa::traits::*;
pub fn compile_codegen_unit(
tcx: TyCtxt<'tcx>,
cgu_name: Symbol,
- tx_to_llvm_workers: &std::sync::mpsc::Sender<Box<dyn std::any::Any + Send>>,
-) {
+) -> (ModuleCodegen<ModuleLlvm>, u64) {
let prof_timer = tcx.prof.generic_activity("codegen_module");
let start_time = Instant::now();
// the time we needed for codegenning it.
let cost = time_to_codegen.as_secs() * 1_000_000_000 + time_to_codegen.subsec_nanos() as u64;
- submit_codegened_module_to_llvm(&LlvmCodegenBackend(()), tx_to_llvm_workers, module, cost);
-
fn module_codegen(tcx: TyCtxt<'_>, cgu_name: Symbol) -> ModuleCodegen<ModuleLlvm> {
let cgu = tcx.codegen_unit(cgu_name);
// Instantiate monomorphizations without filling out definitions yet...
kind: ModuleKind::Regular,
}
}
+
+ (module, cost)
}
pub fn set_link_section(llval: &Value, attrs: &CodegenFnAttrs) {
#![feature(link_args)]
#![feature(static_nobundle)]
#![feature(trusted_len)]
+#![recursion_limit = "256"]
use back::write::{create_informational_target_machine, create_target_machine};
use rustc_span::symbol::Symbol;
&self,
tcx: TyCtxt<'_>,
cgu_name: Symbol,
- tx: &std::sync::mpsc::Sender<Box<dyn Any + Send>>,
- ) {
- base::compile_codegen_unit(tcx, cgu_name, tx);
+ ) -> (ModuleCodegen<ModuleLlvm>, u64) {
+ base::compile_codegen_unit(tcx, cgu_name)
}
fn target_machine_factory(
&self,
//! int)` and `rec(x=int, y=int, z=int)` will have the same `llvm::Type`.
use crate::back::write::{
- start_async_codegen, submit_post_lto_module_to_llvm, submit_pre_lto_module_to_llvm,
- OngoingCodegen,
+ start_async_codegen, submit_codegened_module_to_llvm, submit_post_lto_module_to_llvm,
+ submit_pre_lto_module_to_llvm, OngoingCodegen,
};
use crate::common::{IntPredicate, RealPredicate, TypeKind};
use crate::meth;
use rustc_codegen_utils::{check_for_rustc_errors_attr, symbol_names_test};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::profiling::print_time_passes_entry;
+use rustc_data_structures::sync::{par_iter, Lock, ParallelIterator};
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_index::vec::Idx;
codegen_units
};
- let mut total_codegen_time = Duration::new(0, 0);
+ let total_codegen_time = Lock::new(Duration::new(0, 0));
- for cgu in codegen_units.into_iter() {
+ let cgu_reuse: Vec<_> = tcx.sess.time("find cgu reuse", || {
+ codegen_units.iter().map(|cgu| determine_cgu_reuse(tcx, &cgu)).collect()
+ });
+
+ let mut cgus: FxHashMap<usize, _> = if cfg!(parallel_compiler) {
+ tcx.sess.time("compile first CGUs", || {
+ // Try to find one CGU to compile per thread.
+ let cgus: Vec<_> = cgu_reuse
+ .iter()
+ .enumerate()
+ .filter(|&(_, reuse)| reuse == &CguReuse::No)
+ .take(tcx.sess.threads())
+ .collect();
+
+ // Compile the found CGUs in parallel.
+ par_iter(cgus)
+ .map(|(i, _)| {
+ let start_time = Instant::now();
+ let module = backend.compile_codegen_unit(tcx, codegen_units[i].name());
+ let mut time = total_codegen_time.lock();
+ *time += start_time.elapsed();
+ (i, module)
+ })
+ .collect()
+ })
+ } else {
+ FxHashMap::default()
+ };
+
+ let mut total_codegen_time = total_codegen_time.into_inner();
+
+ for (i, cgu) in codegen_units.into_iter().enumerate() {
ongoing_codegen.wait_for_signal_to_codegen_item();
ongoing_codegen.check_for_errors(tcx.sess);
- let cgu_reuse = determine_cgu_reuse(tcx, &cgu);
+ let cgu_reuse = cgu_reuse[i];
tcx.sess.cgu_reuse_tracker.set_actual_reuse(&cgu.name().as_str(), cgu_reuse);
match cgu_reuse {
CguReuse::No => {
- let start_time = Instant::now();
- backend.compile_codegen_unit(tcx, cgu.name(), &ongoing_codegen.coordinator_send);
- total_codegen_time += start_time.elapsed();
+ let (module, cost) = if let Some(cgu) = cgus.remove(&i) {
+ cgu
+ } else {
+ let start_time = Instant::now();
+ let module = backend.compile_codegen_unit(tcx, cgu.name());
+ total_codegen_time += start_time.elapsed();
+ module
+ };
+ submit_codegened_module_to_llvm(
+ &backend,
+ &ongoing_codegen.coordinator_send,
+ module,
+ cost,
+ );
false
}
CguReuse::PreLto => {
use super::write::WriteBackendMethods;
use super::CodegenObject;
+use crate::ModuleCodegen;
use rustc::middle::cstore::EncodedMetadata;
use rustc::session::{config, Session};
use rustc_span::symbol::Symbol;
use syntax::expand::allocator::AllocatorKind;
-use std::sync::mpsc;
use std::sync::Arc;
pub trait BackendTypes {
{
}
-pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Send {
+pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Send + Sync {
fn new_metadata(&self, sess: TyCtxt<'_>, mod_name: &str) -> Self::Module;
fn write_compressed_metadata<'tcx>(
&self,
&self,
tcx: TyCtxt<'_>,
cgu_name: Symbol,
- tx_to_llvm_workers: &mpsc::Sender<Box<dyn std::any::Any + Send>>,
- );
+ ) -> (ModuleCodegen<Self::Module>, u64);
// If find_features is true this won't access `sess.crate_types` by assuming
// that `is_pie_binary` is false. When we discover LLVM target features
// `sess.crate_types` is uninitialized so we cannot access it.