1
Fork 0

Generalized base:codegen_crate

This commit is contained in:
Denis Merigoux 2018-09-25 17:52:03 +02:00 committed by Eduard-Mihai Burtescu
parent 97825a36be
commit 8d530db2c5
6 changed files with 160 additions and 66 deletions

View file

@ -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| {

View file

@ -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 {

View file

@ -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>) {

View file

@ -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);
}

View file

@ -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};

View file

@ -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,