Generalized base:codegen_crate
This commit is contained in:
parent
97825a36be
commit
8d530db2c5
6 changed files with 160 additions and 66 deletions
|
@ -13,8 +13,7 @@ use back::write::{ModuleConfig, with_llvm_pmb, CodegenContext};
|
||||||
use back::write::{self, DiagnosticHandlers, pre_lto_bitcode_filename};
|
use back::write::{self, DiagnosticHandlers, pre_lto_bitcode_filename};
|
||||||
use errors::{FatalError, Handler};
|
use errors::{FatalError, Handler};
|
||||||
use llvm::archive_ro::ArchiveRO;
|
use llvm::archive_ro::ArchiveRO;
|
||||||
use llvm::{True, False};
|
use llvm::{self, True, False};
|
||||||
use llvm;
|
|
||||||
use memmap;
|
use memmap;
|
||||||
use rustc::dep_graph::WorkProduct;
|
use rustc::dep_graph::WorkProduct;
|
||||||
use rustc::dep_graph::cgu_reuse_tracker::CguReuse;
|
use rustc::dep_graph::cgu_reuse_tracker::CguReuse;
|
||||||
|
@ -49,7 +48,7 @@ pub fn crate_type_allows_lto(crate_type: config::CrateType) -> bool {
|
||||||
|
|
||||||
pub(crate) enum LtoModuleCodegen {
|
pub(crate) enum LtoModuleCodegen {
|
||||||
Fat {
|
Fat {
|
||||||
module: Option<ModuleCodegen>,
|
module: Option<ModuleCodegen<ModuleLlvm>>,
|
||||||
_serialized_bitcode: Vec<SerializedModule>,
|
_serialized_bitcode: Vec<SerializedModule>,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -73,7 +72,7 @@ impl LtoModuleCodegen {
|
||||||
pub(crate) unsafe fn optimize(&mut self,
|
pub(crate) unsafe fn optimize(&mut self,
|
||||||
cgcx: &CodegenContext,
|
cgcx: &CodegenContext,
|
||||||
timeline: &mut Timeline)
|
timeline: &mut Timeline)
|
||||||
-> Result<ModuleCodegen, FatalError>
|
-> Result<ModuleCodegen<ModuleLlvm>, FatalError>
|
||||||
{
|
{
|
||||||
match *self {
|
match *self {
|
||||||
LtoModuleCodegen::Fat { ref mut module, .. } => {
|
LtoModuleCodegen::Fat { ref mut module, .. } => {
|
||||||
|
@ -108,7 +107,7 @@ impl LtoModuleCodegen {
|
||||||
/// the need optimization and another for modules that can simply be copied over
|
/// the need optimization and another for modules that can simply be copied over
|
||||||
/// from the incr. comp. cache.
|
/// from the incr. comp. cache.
|
||||||
pub(crate) fn run(cgcx: &CodegenContext,
|
pub(crate) fn run(cgcx: &CodegenContext,
|
||||||
modules: Vec<ModuleCodegen>,
|
modules: Vec<ModuleCodegen<ModuleLlvm>>,
|
||||||
cached_modules: Vec<(SerializedModule, WorkProduct)>,
|
cached_modules: Vec<(SerializedModule, WorkProduct)>,
|
||||||
timeline: &mut Timeline)
|
timeline: &mut Timeline)
|
||||||
-> Result<(Vec<LtoModuleCodegen>, Vec<WorkProduct>), FatalError>
|
-> Result<(Vec<LtoModuleCodegen>, Vec<WorkProduct>), FatalError>
|
||||||
|
@ -232,7 +231,7 @@ pub(crate) fn run(cgcx: &CodegenContext,
|
||||||
|
|
||||||
fn fat_lto(cgcx: &CodegenContext,
|
fn fat_lto(cgcx: &CodegenContext,
|
||||||
diag_handler: &Handler,
|
diag_handler: &Handler,
|
||||||
mut modules: Vec<ModuleCodegen>,
|
mut modules: Vec<ModuleCodegen<ModuleLlvm>>,
|
||||||
mut serialized_modules: Vec<(SerializedModule, CString)>,
|
mut serialized_modules: Vec<(SerializedModule, CString)>,
|
||||||
symbol_white_list: &[*const libc::c_char],
|
symbol_white_list: &[*const libc::c_char],
|
||||||
timeline: &mut Timeline)
|
timeline: &mut Timeline)
|
||||||
|
@ -388,7 +387,7 @@ impl Drop for Linker<'a> {
|
||||||
/// they all go out of scope.
|
/// they all go out of scope.
|
||||||
fn thin_lto(cgcx: &CodegenContext,
|
fn thin_lto(cgcx: &CodegenContext,
|
||||||
diag_handler: &Handler,
|
diag_handler: &Handler,
|
||||||
modules: Vec<ModuleCodegen>,
|
modules: Vec<ModuleCodegen<ModuleLlvm>>,
|
||||||
serialized_modules: Vec<(SerializedModule, CString)>,
|
serialized_modules: Vec<(SerializedModule, CString)>,
|
||||||
cached_modules: Vec<(SerializedModule, WorkProduct)>,
|
cached_modules: Vec<(SerializedModule, WorkProduct)>,
|
||||||
symbol_white_list: &[*const libc::c_char],
|
symbol_white_list: &[*const libc::c_char],
|
||||||
|
@ -740,7 +739,7 @@ impl ThinModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn optimize(&mut self, cgcx: &CodegenContext, timeline: &mut Timeline)
|
unsafe fn optimize(&mut self, cgcx: &CodegenContext, timeline: &mut Timeline)
|
||||||
-> Result<ModuleCodegen, FatalError>
|
-> Result<ModuleCodegen<ModuleLlvm>, FatalError>
|
||||||
{
|
{
|
||||||
let diag_handler = cgcx.create_diag_handler();
|
let diag_handler = cgcx.create_diag_handler();
|
||||||
let tm = (cgcx.tm_factory)().map_err(|e| {
|
let tm = (cgcx.tm_factory)().map_err(|e| {
|
||||||
|
|
|
@ -26,7 +26,7 @@ use rustc::util::nodemap::FxHashMap;
|
||||||
use time_graph::{self, TimeGraph, Timeline};
|
use time_graph::{self, TimeGraph, Timeline};
|
||||||
use llvm::{self, DiagnosticInfo, PassManager, SMDiagnostic};
|
use llvm::{self, DiagnosticInfo, PassManager, SMDiagnostic};
|
||||||
use llvm_util;
|
use llvm_util;
|
||||||
use {CodegenResults, ModuleCodegen, CompiledModule, ModuleKind, // ModuleLlvm,
|
use {CodegenResults, ModuleCodegen, CompiledModule, ModuleKind, ModuleLlvm,
|
||||||
CachedModuleCodegen};
|
CachedModuleCodegen};
|
||||||
use CrateInfo;
|
use CrateInfo;
|
||||||
use rustc::hir::def_id::{CrateNum, LOCAL_CRATE};
|
use rustc::hir::def_id::{CrateNum, LOCAL_CRATE};
|
||||||
|
@ -408,7 +408,7 @@ impl CodegenContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn save_temp_bitcode(&self, module: &ModuleCodegen, name: &str) {
|
pub(crate) fn save_temp_bitcode(&self, module: &ModuleCodegen<ModuleLlvm>, name: &str) {
|
||||||
if !self.save_temps {
|
if !self.save_temps {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -515,7 +515,7 @@ unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void
|
||||||
// Unsafe due to LLVM calls.
|
// Unsafe due to LLVM calls.
|
||||||
unsafe fn optimize(cgcx: &CodegenContext,
|
unsafe fn optimize(cgcx: &CodegenContext,
|
||||||
diag_handler: &Handler,
|
diag_handler: &Handler,
|
||||||
module: &ModuleCodegen,
|
module: &ModuleCodegen<ModuleLlvm>,
|
||||||
config: &ModuleConfig,
|
config: &ModuleConfig,
|
||||||
timeline: &mut Timeline)
|
timeline: &mut Timeline)
|
||||||
-> Result<(), FatalError>
|
-> Result<(), FatalError>
|
||||||
|
@ -646,7 +646,7 @@ unsafe fn optimize(cgcx: &CodegenContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_lto_work(cgcx: &CodegenContext,
|
fn generate_lto_work(cgcx: &CodegenContext,
|
||||||
modules: Vec<ModuleCodegen>,
|
modules: Vec<ModuleCodegen<ModuleLlvm>>,
|
||||||
import_only_modules: Vec<(SerializedModule, WorkProduct)>)
|
import_only_modules: Vec<(SerializedModule, WorkProduct)>)
|
||||||
-> Vec<(WorkItem, u64)>
|
-> Vec<(WorkItem, u64)>
|
||||||
{
|
{
|
||||||
|
@ -675,7 +675,7 @@ fn generate_lto_work(cgcx: &CodegenContext,
|
||||||
|
|
||||||
unsafe fn codegen(cgcx: &CodegenContext,
|
unsafe fn codegen(cgcx: &CodegenContext,
|
||||||
diag_handler: &Handler,
|
diag_handler: &Handler,
|
||||||
module: ModuleCodegen,
|
module: ModuleCodegen<ModuleLlvm>,
|
||||||
config: &ModuleConfig,
|
config: &ModuleConfig,
|
||||||
timeline: &mut Timeline)
|
timeline: &mut Timeline)
|
||||||
-> Result<CompiledModule, FatalError>
|
-> Result<CompiledModule, FatalError>
|
||||||
|
@ -1284,7 +1284,7 @@ pub(crate) fn dump_incremental_data(_codegen_results: &CodegenResults) {
|
||||||
|
|
||||||
enum WorkItem {
|
enum WorkItem {
|
||||||
/// Optimize a newly codegened, totally unoptimized module.
|
/// Optimize a newly codegened, totally unoptimized module.
|
||||||
Optimize(ModuleCodegen),
|
Optimize(ModuleCodegen<ModuleLlvm>),
|
||||||
/// Copy the post-LTO artifacts from the incremental cache to the output
|
/// Copy the post-LTO artifacts from the incremental cache to the output
|
||||||
/// directory.
|
/// directory.
|
||||||
CopyPostLtoArtifacts(CachedModuleCodegen),
|
CopyPostLtoArtifacts(CachedModuleCodegen),
|
||||||
|
@ -1312,7 +1312,7 @@ impl WorkItem {
|
||||||
|
|
||||||
enum WorkItemResult {
|
enum WorkItemResult {
|
||||||
Compiled(CompiledModule),
|
Compiled(CompiledModule),
|
||||||
NeedsLTO(ModuleCodegen),
|
NeedsLTO(ModuleCodegen<ModuleLlvm>),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute_work_item(cgcx: &CodegenContext,
|
fn execute_work_item(cgcx: &CodegenContext,
|
||||||
|
@ -1336,7 +1336,7 @@ fn execute_work_item(cgcx: &CodegenContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute_optimize_work_item(cgcx: &CodegenContext,
|
fn execute_optimize_work_item(cgcx: &CodegenContext,
|
||||||
module: ModuleCodegen,
|
module: ModuleCodegen<ModuleLlvm>,
|
||||||
module_config: &ModuleConfig,
|
module_config: &ModuleConfig,
|
||||||
timeline: &mut Timeline)
|
timeline: &mut Timeline)
|
||||||
-> Result<WorkItemResult, FatalError>
|
-> Result<WorkItemResult, FatalError>
|
||||||
|
@ -1480,7 +1480,7 @@ fn execute_lto_work_item(cgcx: &CodegenContext,
|
||||||
enum Message {
|
enum Message {
|
||||||
Token(io::Result<Acquired>),
|
Token(io::Result<Acquired>),
|
||||||
NeedsLTO {
|
NeedsLTO {
|
||||||
result: ModuleCodegen,
|
result: ModuleCodegen<ModuleLlvm>,
|
||||||
worker_id: usize,
|
worker_id: usize,
|
||||||
},
|
},
|
||||||
Done {
|
Done {
|
||||||
|
@ -2445,7 +2445,7 @@ impl OngoingCodegen {
|
||||||
|
|
||||||
pub(crate) fn submit_pre_codegened_module_to_llvm(&self,
|
pub(crate) fn submit_pre_codegened_module_to_llvm(&self,
|
||||||
tcx: TyCtxt,
|
tcx: TyCtxt,
|
||||||
module: ModuleCodegen) {
|
module: ModuleCodegen<ModuleLlvm>) {
|
||||||
self.wait_for_signal_to_codegen_item();
|
self.wait_for_signal_to_codegen_item();
|
||||||
self.check_for_errors(tcx.sess);
|
self.check_for_errors(tcx.sess);
|
||||||
|
|
||||||
|
@ -2497,7 +2497,7 @@ impl OngoingCodegen {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
pub(crate) fn submit_codegened_module_to_llvm(tcx: TyCtxt,
|
pub(crate) fn submit_codegened_module_to_llvm(tcx: TyCtxt,
|
||||||
module: ModuleCodegen,
|
module: ModuleCodegen<ModuleLlvm>,
|
||||||
cost: u64) {
|
cost: u64) {
|
||||||
let llvm_work_item = WorkItem::Optimize(module);
|
let llvm_work_item = WorkItem::Optimize(module);
|
||||||
drop(tcx.tx_to_llvm_workers.lock().send(Box::new(Message::CodegenDone {
|
drop(tcx.tx_to_llvm_workers.lock().send(Box::new(Message::CodegenDone {
|
||||||
|
|
|
@ -29,7 +29,7 @@ use super::ModuleKind;
|
||||||
use super::CachedModuleCodegen;
|
use super::CachedModuleCodegen;
|
||||||
|
|
||||||
use abi;
|
use abi;
|
||||||
use back::write::{self, OngoingCodegen};
|
use back::write;
|
||||||
use llvm;
|
use llvm;
|
||||||
use metadata;
|
use metadata;
|
||||||
use rustc::dep_graph::cgu_reuse_tracker::CguReuse;
|
use rustc::dep_graph::cgu_reuse_tracker::CguReuse;
|
||||||
|
@ -48,7 +48,6 @@ use rustc::util::profiling::ProfileCategory;
|
||||||
use rustc::session::config::{self, DebugInfo, EntryFnType, Lto};
|
use rustc::session::config::{self, DebugInfo, EntryFnType, Lto};
|
||||||
use rustc::session::Session;
|
use rustc::session::Session;
|
||||||
use rustc_incremental;
|
use rustc_incremental;
|
||||||
use allocator;
|
|
||||||
use mir::place::PlaceRef;
|
use mir::place::PlaceRef;
|
||||||
use builder::{Builder, MemFlags};
|
use builder::{Builder, MemFlags};
|
||||||
use callee;
|
use callee;
|
||||||
|
@ -584,9 +583,10 @@ fn maybe_create_entry_wrapper<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_metadata<'a, 'gcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>,
|
pub(crate) fn write_metadata<'a, 'gcx>(
|
||||||
llvm_module: &ModuleLlvm)
|
tcx: TyCtxt<'a, 'gcx, 'gcx>,
|
||||||
-> EncodedMetadata {
|
llvm_module: &ModuleLlvm
|
||||||
|
) -> EncodedMetadata {
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use flate2::Compression;
|
use flate2::Compression;
|
||||||
use flate2::write::DeflateEncoder;
|
use flate2::write::DeflateEncoder;
|
||||||
|
@ -713,10 +713,12 @@ fn determine_cgu_reuse<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
pub fn codegen_crate<'a, 'tcx, B: BackendMethods>(
|
||||||
rx: mpsc::Receiver<Box<dyn Any + Send>>)
|
backend: B,
|
||||||
-> OngoingCodegen
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
{
|
rx: mpsc::Receiver<Box<dyn Any + Send>>
|
||||||
|
) -> B::OngoingCodegen {
|
||||||
|
|
||||||
check_for_rustc_errors_attr(tcx);
|
check_for_rustc_errors_attr(tcx);
|
||||||
|
|
||||||
let cgu_name_builder = &mut CodegenUnitNameBuilder::new(tcx);
|
let cgu_name_builder = &mut CodegenUnitNameBuilder::new(tcx);
|
||||||
|
@ -728,9 +730,9 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
&["crate"],
|
&["crate"],
|
||||||
Some("metadata")).as_str()
|
Some("metadata")).as_str()
|
||||||
.to_string();
|
.to_string();
|
||||||
let metadata_llvm_module = ModuleLlvm::new(tcx.sess, &metadata_cgu_name);
|
let metadata_llvm_module = backend.new_metadata(tcx.sess, &metadata_cgu_name);
|
||||||
let metadata = time(tcx.sess, "write metadata", || {
|
let metadata = time(tcx.sess, "write metadata", || {
|
||||||
write_metadata(tcx, &metadata_llvm_module)
|
backend.write_metadata(tcx, &metadata_llvm_module)
|
||||||
});
|
});
|
||||||
tcx.sess.profiler(|p| p.end_activity(ProfileCategory::Codegen));
|
tcx.sess.profiler(|p| p.end_activity(ProfileCategory::Codegen));
|
||||||
|
|
||||||
|
@ -749,19 +751,19 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
// Skip crate items and just output metadata in -Z no-codegen mode.
|
// Skip crate items and just output metadata in -Z no-codegen mode.
|
||||||
if tcx.sess.opts.debugging_opts.no_codegen ||
|
if tcx.sess.opts.debugging_opts.no_codegen ||
|
||||||
!tcx.sess.opts.output_types.should_codegen() {
|
!tcx.sess.opts.output_types.should_codegen() {
|
||||||
let ongoing_codegen = write::start_async_codegen(
|
let ongoing_codegen = backend.start_async_codegen(
|
||||||
tcx,
|
tcx,
|
||||||
time_graph,
|
time_graph,
|
||||||
metadata,
|
metadata,
|
||||||
rx,
|
rx,
|
||||||
1);
|
1);
|
||||||
|
|
||||||
ongoing_codegen.submit_pre_codegened_module_to_llvm(tcx, metadata_module);
|
backend.submit_pre_codegened_module_to_llvm(&ongoing_codegen, tcx, metadata_module);
|
||||||
ongoing_codegen.codegen_finished(tcx);
|
backend.codegen_finished(&ongoing_codegen, tcx);
|
||||||
|
|
||||||
assert_and_save_dep_graph(tcx);
|
assert_and_save_dep_graph(tcx);
|
||||||
|
|
||||||
ongoing_codegen.check_for_errors(tcx.sess);
|
backend.check_for_errors(&ongoing_codegen, tcx.sess);
|
||||||
|
|
||||||
return ongoing_codegen;
|
return ongoing_codegen;
|
||||||
}
|
}
|
||||||
|
@ -782,13 +784,13 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let ongoing_codegen = write::start_async_codegen(
|
let ongoing_codegen = backend.start_async_codegen(
|
||||||
tcx,
|
tcx,
|
||||||
time_graph.clone(),
|
time_graph.clone(),
|
||||||
metadata,
|
metadata,
|
||||||
rx,
|
rx,
|
||||||
codegen_units.len());
|
codegen_units.len());
|
||||||
let ongoing_codegen = AbortCodegenOnDrop(Some(ongoing_codegen));
|
let ongoing_codegen = AbortCodegenOnDrop::<B>(Some(ongoing_codegen));
|
||||||
|
|
||||||
// Codegen an allocator shim, if necessary.
|
// Codegen an allocator shim, if necessary.
|
||||||
//
|
//
|
||||||
|
@ -811,11 +813,9 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
&["crate"],
|
&["crate"],
|
||||||
Some("allocator")).as_str()
|
Some("allocator")).as_str()
|
||||||
.to_string();
|
.to_string();
|
||||||
let modules = ModuleLlvm::new(tcx.sess, &llmod_id);
|
let modules = backend.new_metadata(tcx.sess, &llmod_id);
|
||||||
time(tcx.sess, "write allocator module", || {
|
time(tcx.sess, "write allocator module", || {
|
||||||
unsafe {
|
backend.codegen_allocator(tcx, &modules, kind)
|
||||||
allocator::codegen(tcx, &modules, kind)
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Some(ModuleCodegen {
|
Some(ModuleCodegen {
|
||||||
|
@ -828,10 +828,10 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(allocator_module) = allocator_module {
|
if let Some(allocator_module) = allocator_module {
|
||||||
ongoing_codegen.submit_pre_codegened_module_to_llvm(tcx, allocator_module);
|
backend.submit_pre_codegened_module_to_llvm(&ongoing_codegen, tcx, allocator_module);
|
||||||
}
|
}
|
||||||
|
|
||||||
ongoing_codegen.submit_pre_codegened_module_to_llvm(tcx, metadata_module);
|
backend.submit_pre_codegened_module_to_llvm(&ongoing_codegen, tcx, metadata_module);
|
||||||
|
|
||||||
// We sort the codegen units by size. This way we can schedule work for LLVM
|
// We sort the codegen units by size. This way we can schedule work for LLVM
|
||||||
// a bit more efficiently.
|
// a bit more efficiently.
|
||||||
|
@ -845,8 +845,8 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
let mut all_stats = Stats::default();
|
let mut all_stats = Stats::default();
|
||||||
|
|
||||||
for cgu in codegen_units.into_iter() {
|
for cgu in codegen_units.into_iter() {
|
||||||
ongoing_codegen.wait_for_signal_to_codegen_item();
|
backend.wait_for_signal_to_codegen_item(&ongoing_codegen);
|
||||||
ongoing_codegen.check_for_errors(tcx.sess);
|
backend.check_for_errors(&ongoing_codegen, tcx.sess);
|
||||||
|
|
||||||
let cgu_reuse = determine_cgu_reuse(tcx, &cgu);
|
let cgu_reuse = determine_cgu_reuse(tcx, &cgu);
|
||||||
tcx.sess.cgu_reuse_tracker.set_actual_reuse(&cgu.name().as_str(), cgu_reuse);
|
tcx.sess.cgu_reuse_tracker.set_actual_reuse(&cgu.name().as_str(), cgu_reuse);
|
||||||
|
@ -881,7 +881,7 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
ongoing_codegen.codegen_finished(tcx);
|
backend.codegen_finished(&ongoing_codegen, tcx);
|
||||||
|
|
||||||
// Since the main thread is sometimes blocked during codegen, we keep track
|
// Since the main thread is sometimes blocked during codegen, we keep track
|
||||||
// -Ztime-passes output manually.
|
// -Ztime-passes output manually.
|
||||||
|
@ -915,7 +915,7 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ongoing_codegen.check_for_errors(tcx.sess);
|
backend.check_for_errors(&ongoing_codegen, tcx.sess);
|
||||||
|
|
||||||
assert_and_save_dep_graph(tcx);
|
assert_and_save_dep_graph(tcx);
|
||||||
ongoing_codegen.into_inner()
|
ongoing_codegen.into_inner()
|
||||||
|
@ -938,32 +938,32 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
/// If you see this comment in the code, then it means that this workaround
|
/// If you see this comment in the code, then it means that this workaround
|
||||||
/// worked! We may yet one day track down the mysterious cause of that
|
/// worked! We may yet one day track down the mysterious cause of that
|
||||||
/// segfault...
|
/// segfault...
|
||||||
struct AbortCodegenOnDrop(Option<OngoingCodegen>);
|
struct AbortCodegenOnDrop<B: BackendMethods>(Option<B::OngoingCodegen>);
|
||||||
|
|
||||||
impl AbortCodegenOnDrop {
|
impl<B: BackendMethods> AbortCodegenOnDrop<B> {
|
||||||
fn into_inner(mut self) -> OngoingCodegen {
|
fn into_inner(mut self) -> B::OngoingCodegen {
|
||||||
self.0.take().unwrap()
|
self.0.take().unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Deref for AbortCodegenOnDrop {
|
impl<B: BackendMethods> Deref for AbortCodegenOnDrop<B> {
|
||||||
type Target = OngoingCodegen;
|
type Target = B::OngoingCodegen;
|
||||||
|
|
||||||
fn deref(&self) -> &OngoingCodegen {
|
fn deref(&self) -> &B::OngoingCodegen {
|
||||||
self.0.as_ref().unwrap()
|
self.0.as_ref().unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DerefMut for AbortCodegenOnDrop {
|
impl<B: BackendMethods> DerefMut for AbortCodegenOnDrop<B> {
|
||||||
fn deref_mut(&mut self) -> &mut OngoingCodegen {
|
fn deref_mut(&mut self) -> &mut B::OngoingCodegen {
|
||||||
self.0.as_mut().unwrap()
|
self.0.as_mut().unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for AbortCodegenOnDrop {
|
impl<B: BackendMethods> Drop for AbortCodegenOnDrop<B> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
if let Some(codegen) = self.0.take() {
|
if let Some(codegen) = self.0.take() {
|
||||||
codegen.codegen_aborted();
|
B::codegen_aborted(codegen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1092,7 +1092,7 @@ fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
fn module_codegen<'a, 'tcx>(
|
fn module_codegen<'a, 'tcx>(
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
cgu_name: InternedString)
|
cgu_name: InternedString)
|
||||||
-> (Stats, ModuleCodegen)
|
-> (Stats, ModuleCodegen<ModuleLlvm>)
|
||||||
{
|
{
|
||||||
let cgu = tcx.codegen_unit(cgu_name);
|
let cgu = tcx.codegen_unit(cgu_name);
|
||||||
|
|
||||||
|
@ -1226,9 +1226,9 @@ pub fn visibility_to_llvm(linkage: Visibility) -> llvm::Visibility {
|
||||||
mod temp_stable_hash_impls {
|
mod temp_stable_hash_impls {
|
||||||
use rustc_data_structures::stable_hasher::{StableHasherResult, StableHasher,
|
use rustc_data_structures::stable_hasher::{StableHasherResult, StableHasher,
|
||||||
HashStable};
|
HashStable};
|
||||||
use ModuleCodegen;
|
use {ModuleCodegen, ModuleLlvm};
|
||||||
|
|
||||||
impl<HCX> HashStable<HCX> for ModuleCodegen {
|
impl<HCX> HashStable<HCX> for ModuleCodegen<ModuleLlvm> {
|
||||||
fn hash_stable<W: StableHasherResult>(&self,
|
fn hash_stable<W: StableHasherResult>(&self,
|
||||||
_: &mut HCX,
|
_: &mut HCX,
|
||||||
_: &mut StableHasher<W>) {
|
_: &mut StableHasher<W>) {
|
||||||
|
|
|
@ -12,6 +12,14 @@ use rustc::ty::layout::{HasTyCtxt, LayoutOf, TyLayout};
|
||||||
use rustc::ty::Ty;
|
use rustc::ty::Ty;
|
||||||
|
|
||||||
use super::CodegenObject;
|
use super::CodegenObject;
|
||||||
|
use rustc::middle::allocator::AllocatorKind;
|
||||||
|
use rustc::middle::cstore::EncodedMetadata;
|
||||||
|
use rustc::session::Session;
|
||||||
|
use rustc::ty::TyCtxt;
|
||||||
|
use std::any::Any;
|
||||||
|
use std::sync::mpsc::Receiver;
|
||||||
|
use time_graph::TimeGraph;
|
||||||
|
use ModuleCodegen;
|
||||||
|
|
||||||
pub trait BackendTypes {
|
pub trait BackendTypes {
|
||||||
type Value: CodegenObject;
|
type Value: CodegenObject;
|
||||||
|
@ -30,3 +38,35 @@ pub trait Backend<'tcx>:
|
||||||
impl<'tcx, T> Backend<'tcx> for T where
|
impl<'tcx, T> Backend<'tcx> for T where
|
||||||
Self: BackendTypes + HasTyCtxt<'tcx> + LayoutOf<Ty = Ty<'tcx>, TyLayout = TyLayout<'tcx>>
|
Self: BackendTypes + HasTyCtxt<'tcx> + LayoutOf<Ty = Ty<'tcx>, TyLayout = TyLayout<'tcx>>
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
pub trait BackendMethods {
|
||||||
|
type Metadata;
|
||||||
|
type OngoingCodegen;
|
||||||
|
|
||||||
|
fn new_metadata(&self, sess: &Session, mod_name: &str) -> Self::Metadata;
|
||||||
|
fn write_metadata<'a, 'gcx>(
|
||||||
|
&self,
|
||||||
|
tcx: TyCtxt<'a, 'gcx, 'gcx>,
|
||||||
|
metadata: &Self::Metadata,
|
||||||
|
) -> EncodedMetadata;
|
||||||
|
fn codegen_allocator(&self, tcx: TyCtxt, mods: &Self::Metadata, kind: AllocatorKind);
|
||||||
|
|
||||||
|
fn start_async_codegen(
|
||||||
|
&self,
|
||||||
|
tcx: TyCtxt,
|
||||||
|
time_graph: Option<TimeGraph>,
|
||||||
|
metadata: EncodedMetadata,
|
||||||
|
coordinator_receive: Receiver<Box<dyn Any + Send>>,
|
||||||
|
total_cgus: usize,
|
||||||
|
) -> Self::OngoingCodegen;
|
||||||
|
fn submit_pre_codegened_module_to_llvm(
|
||||||
|
&self,
|
||||||
|
codegen: &Self::OngoingCodegen,
|
||||||
|
tcx: TyCtxt,
|
||||||
|
module: ModuleCodegen<Self::Metadata>,
|
||||||
|
);
|
||||||
|
fn codegen_aborted(codegen: Self::OngoingCodegen);
|
||||||
|
fn codegen_finished(&self, codegen: &Self::OngoingCodegen, tcx: TyCtxt);
|
||||||
|
fn check_for_errors(&self, codegen: &Self::OngoingCodegen, sess: &Session);
|
||||||
|
fn wait_for_signal_to_codegen_item(&self, codegen: &Self::OngoingCodegen);
|
||||||
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ mod type_;
|
||||||
|
|
||||||
pub use self::abi::{AbiBuilderMethods, AbiMethods};
|
pub use self::abi::{AbiBuilderMethods, AbiMethods};
|
||||||
pub use self::asm::{AsmBuilderMethods, AsmMethods};
|
pub use self::asm::{AsmBuilderMethods, AsmMethods};
|
||||||
pub use self::backend::{Backend, BackendTypes};
|
pub use self::backend::{Backend, BackendMethods, BackendTypes};
|
||||||
pub use self::builder::BuilderMethods;
|
pub use self::builder::BuilderMethods;
|
||||||
pub use self::consts::ConstMethods;
|
pub use self::consts::ConstMethods;
|
||||||
pub use self::debuginfo::{DebugInfoBuilderMethods, DebugInfoMethods};
|
pub use self::debuginfo::{DebugInfoBuilderMethods, DebugInfoMethods};
|
||||||
|
|
|
@ -68,6 +68,10 @@ extern crate tempfile;
|
||||||
extern crate memmap;
|
extern crate memmap;
|
||||||
|
|
||||||
use back::bytecode::RLIB_BYTECODE_EXTENSION;
|
use back::bytecode::RLIB_BYTECODE_EXTENSION;
|
||||||
|
use interfaces::*;
|
||||||
|
use time_graph::TimeGraph;
|
||||||
|
use std::sync::mpsc::Receiver;
|
||||||
|
use back::write::{self, OngoingCodegen};
|
||||||
|
|
||||||
pub use llvm_util::target_features;
|
pub use llvm_util::target_features;
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
|
@ -76,7 +80,8 @@ use rustc_data_structures::sync::Lrc;
|
||||||
|
|
||||||
use rustc::dep_graph::DepGraph;
|
use rustc::dep_graph::DepGraph;
|
||||||
use rustc::hir::def_id::CrateNum;
|
use rustc::hir::def_id::CrateNum;
|
||||||
use rustc::middle::cstore::MetadataLoader;
|
use rustc::middle::allocator::AllocatorKind;
|
||||||
|
use rustc::middle::cstore::{EncodedMetadata, MetadataLoader};
|
||||||
use rustc::middle::cstore::{NativeLibrary, CrateSource, LibSource};
|
use rustc::middle::cstore::{NativeLibrary, CrateSource, LibSource};
|
||||||
use rustc::middle::lang_items::LangItem;
|
use rustc::middle::lang_items::LangItem;
|
||||||
use rustc::session::{Session, CompileIncomplete};
|
use rustc::session::{Session, CompileIncomplete};
|
||||||
|
@ -133,6 +138,56 @@ mod value;
|
||||||
|
|
||||||
pub struct LlvmCodegenBackend(());
|
pub struct LlvmCodegenBackend(());
|
||||||
|
|
||||||
|
impl BackendMethods for LlvmCodegenBackend {
|
||||||
|
type Metadata = ModuleLlvm;
|
||||||
|
type OngoingCodegen = OngoingCodegen;
|
||||||
|
|
||||||
|
fn new_metadata(&self, sess: &Session, mod_name: &str) -> ModuleLlvm {
|
||||||
|
ModuleLlvm::new(sess, mod_name)
|
||||||
|
}
|
||||||
|
fn write_metadata<'a, 'gcx>(
|
||||||
|
&self,
|
||||||
|
tcx: TyCtxt<'a, 'gcx, 'gcx>,
|
||||||
|
metadata: &ModuleLlvm
|
||||||
|
) -> EncodedMetadata {
|
||||||
|
base::write_metadata(tcx, metadata)
|
||||||
|
}
|
||||||
|
fn start_async_codegen(
|
||||||
|
&self,
|
||||||
|
tcx: TyCtxt,
|
||||||
|
time_graph: Option<TimeGraph>,
|
||||||
|
metadata: EncodedMetadata,
|
||||||
|
coordinator_receive: Receiver<Box<dyn Any + Send>>,
|
||||||
|
total_cgus: usize
|
||||||
|
) -> OngoingCodegen {
|
||||||
|
write::start_async_codegen(tcx, time_graph, metadata, coordinator_receive, total_cgus)
|
||||||
|
}
|
||||||
|
fn submit_pre_codegened_module_to_llvm(
|
||||||
|
&self,
|
||||||
|
codegen: &OngoingCodegen,
|
||||||
|
tcx: TyCtxt,
|
||||||
|
module: ModuleCodegen<ModuleLlvm>
|
||||||
|
) {
|
||||||
|
codegen.submit_pre_codegened_module_to_llvm(tcx, module)
|
||||||
|
}
|
||||||
|
fn codegen_aborted(codegen: OngoingCodegen) {
|
||||||
|
codegen.codegen_aborted();
|
||||||
|
}
|
||||||
|
fn codegen_finished(&self, codegen: &OngoingCodegen, tcx: TyCtxt) {
|
||||||
|
codegen.codegen_finished(tcx)
|
||||||
|
}
|
||||||
|
fn check_for_errors(&self, codegen: &OngoingCodegen, sess: &Session) {
|
||||||
|
codegen.check_for_errors(sess)
|
||||||
|
}
|
||||||
|
fn codegen_allocator(&self, tcx: TyCtxt, mods: &ModuleLlvm, kind: AllocatorKind) {
|
||||||
|
unsafe { allocator::codegen(tcx, mods, kind) }
|
||||||
|
}
|
||||||
|
fn wait_for_signal_to_codegen_item(&self, codegen: &OngoingCodegen) {
|
||||||
|
codegen.wait_for_signal_to_codegen_item()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
impl !Send for LlvmCodegenBackend {} // Llvm is on a per-thread basis
|
impl !Send for LlvmCodegenBackend {} // Llvm is on a per-thread basis
|
||||||
impl !Sync for LlvmCodegenBackend {}
|
impl !Sync for LlvmCodegenBackend {}
|
||||||
|
|
||||||
|
@ -212,7 +267,7 @@ impl CodegenBackend for LlvmCodegenBackend {
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
rx: mpsc::Receiver<Box<dyn Any + Send>>
|
rx: mpsc::Receiver<Box<dyn Any + Send>>
|
||||||
) -> Box<dyn Any> {
|
) -> Box<dyn Any> {
|
||||||
box base::codegen_crate(tcx, rx)
|
box base::codegen_crate(LlvmCodegenBackend(()), tcx, rx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn join_codegen_and_link(
|
fn join_codegen_and_link(
|
||||||
|
@ -265,7 +320,7 @@ pub fn __rustc_codegen_backend() -> Box<dyn CodegenBackend> {
|
||||||
LlvmCodegenBackend::new()
|
LlvmCodegenBackend::new()
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ModuleCodegen {
|
pub struct ModuleCodegen<M> {
|
||||||
/// The name of the module. When the crate may be saved between
|
/// The name of the module. When the crate may be saved between
|
||||||
/// compilations, incremental compilation requires that name be
|
/// compilations, incremental compilation requires that name be
|
||||||
/// unique amongst **all** crates. Therefore, it should contain
|
/// unique amongst **all** crates. Therefore, it should contain
|
||||||
|
@ -273,7 +328,7 @@ struct ModuleCodegen {
|
||||||
/// as the crate name and disambiguator.
|
/// as the crate name and disambiguator.
|
||||||
/// We currently generate these names via CodegenUnit::build_cgu_name().
|
/// We currently generate these names via CodegenUnit::build_cgu_name().
|
||||||
name: String,
|
name: String,
|
||||||
module_llvm: ModuleLlvm,
|
module_llvm: M,
|
||||||
kind: ModuleKind,
|
kind: ModuleKind,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,7 +337,7 @@ struct CachedModuleCodegen {
|
||||||
source: WorkProduct,
|
source: WorkProduct,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ModuleCodegen {
|
impl ModuleCodegen<ModuleLlvm> {
|
||||||
fn into_compiled_module(self,
|
fn into_compiled_module(self,
|
||||||
emit_obj: bool,
|
emit_obj: bool,
|
||||||
emit_bc: bool,
|
emit_bc: bool,
|
||||||
|
@ -315,7 +370,7 @@ impl ModuleCodegen {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ModuleLlvm {
|
pub struct ModuleLlvm {
|
||||||
llcx: &'static mut llvm::Context,
|
llcx: &'static mut llvm::Context,
|
||||||
llmod_raw: *const llvm::Module,
|
llmod_raw: *const llvm::Module,
|
||||||
tm: &'static mut llvm::TargetMachine,
|
tm: &'static mut llvm::TargetMachine,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue