1
Fork 0

Preparing the generalization of base:compile_coodegen_unit

This commit is contained in:
Denis Merigoux 2018-09-26 17:00:01 +02:00 committed by Eduard-Mihai Burtescu
parent 91a2a80692
commit 6819e6e6e1
11 changed files with 114 additions and 57 deletions

View file

@ -27,6 +27,7 @@ use super::ModuleLlvm;
use super::ModuleCodegen; use super::ModuleCodegen;
use super::ModuleKind; use super::ModuleKind;
use super::CachedModuleCodegen; use super::CachedModuleCodegen;
use super::LlvmCodegenBackend;
use abi; use abi;
use back::write; use back::write;
@ -53,8 +54,6 @@ use builder::{Builder, MemFlags};
use callee; use callee;
use rustc_mir::monomorphize::item::DefPathBasedNames; use rustc_mir::monomorphize::item::DefPathBasedNames;
use common::{self, IntPredicate, RealPredicate, TypeKind}; use common::{self, IntPredicate, RealPredicate, TypeKind};
use context::CodegenCx;
use debuginfo;
use meth; use meth;
use mir; use mir;
use monomorphize::Instance; use monomorphize::Instance;
@ -968,7 +967,7 @@ impl<B: BackendMethods> Drop for AbortCodegenOnDrop<B> {
} }
} }
fn assert_and_save_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { fn assert_and_save_dep_graph<'ll, 'tcx>(tcx: TyCtxt<'ll, 'tcx, 'tcx>) {
time(tcx.sess, time(tcx.sess,
"assert dep graph", "assert dep graph",
|| rustc_incremental::assert_dep_graph(tcx)); || rustc_incremental::assert_dep_graph(tcx));
@ -1067,7 +1066,7 @@ impl CrateInfo {
} }
} }
fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn compile_codegen_unit<'ll, 'tcx>(tcx: TyCtxt<'ll, 'tcx, 'tcx>,
cgu_name: InternedString) cgu_name: InternedString)
-> Stats { -> Stats {
let start_time = Instant::now(); let start_time = Instant::now();
@ -1089,26 +1088,26 @@ fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
cost); cost);
return stats; return stats;
fn module_codegen<'a, 'tcx>( fn module_codegen<'ll, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'ll, 'tcx, 'tcx>,
cgu_name: InternedString) cgu_name: InternedString)
-> (Stats, ModuleCodegen<ModuleLlvm>) -> (Stats, ModuleCodegen<ModuleLlvm>)
{ {
let backend = LlvmCodegenBackend(());
let cgu = tcx.codegen_unit(cgu_name); let cgu = tcx.codegen_unit(cgu_name);
// Instantiate monomorphizations without filling out definitions yet... // Instantiate monomorphizations without filling out definitions yet...
let llvm_module = ModuleLlvm::new(tcx.sess, &cgu_name.as_str()); let llvm_module = backend.new_metadata(tcx.sess, &cgu_name.as_str());
let stats = { let stats = {
let cx = CodegenCx::new(tcx, cgu, &llvm_module); let cx = backend.new_codegen_context(tcx, cgu, &llvm_module);
let mono_items = cx.codegen_unit let mono_items = cx.codegen_unit
.items_in_deterministic_order(cx.tcx); .items_in_deterministic_order(cx.tcx);
for &(mono_item, (linkage, visibility)) in &mono_items { for &(mono_item, (linkage, visibility)) in &mono_items {
mono_item.predefine(&cx, linkage, visibility); mono_item.predefine::<Builder<&Value>>(&cx, linkage, visibility);
} }
// ... and now that we have everything pre-defined, fill out those definitions. // ... and now that we have everything pre-defined, fill out those definitions.
for &(mono_item, _) in &mono_items { for &(mono_item, _) in &mono_items {
mono_item.define(&cx); mono_item.define::<Builder<&Value>>(&cx);
} }
// If this codegen unit contains the main function, also create the // If this codegen unit contains the main function, also create the
@ -1116,40 +1115,22 @@ fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
maybe_create_entry_wrapper::<Builder<&Value>>(&cx); maybe_create_entry_wrapper::<Builder<&Value>>(&cx);
// Run replace-all-uses-with for statics that need it // Run replace-all-uses-with for statics that need it
for &(old_g, new_g) in cx.statics_to_rauw.borrow().iter() { for &(old_g, new_g) in cx.statics_to_rauw().borrow().iter() {
unsafe { cx.static_replace_all_uses(old_g, new_g)
let bitcast = llvm::LLVMConstPointerCast(new_g, cx.val_ty(old_g));
llvm::LLVMReplaceAllUsesWith(old_g, bitcast);
llvm::LLVMDeleteGlobal(old_g);
}
} }
// Create the llvm.used variable // Create the llvm.used variable
// This variable has type [N x i8*] and is stored in the llvm.metadata section // This variable has type [N x i8*] and is stored in the llvm.metadata section
if !cx.used_statics.borrow().is_empty() { if !cx.used_statics().borrow().is_empty() {
let name = const_cstr!("llvm.used"); cx.create_used_variable()
let section = const_cstr!("llvm.metadata");
let array = cx.const_array(
&cx.type_ptr_to(cx.type_i8()),
&*cx.used_statics.borrow()
);
unsafe {
let g = llvm::LLVMAddGlobal(cx.llmod,
cx.val_ty(array),
name.as_ptr());
llvm::LLVMSetInitializer(g, array);
llvm::LLVMRustSetLinkage(g, llvm::Linkage::AppendingLinkage);
llvm::LLVMSetSection(g, section.as_ptr());
}
} }
// Finalize debuginfo // Finalize debuginfo
if cx.sess().opts.debuginfo != DebugInfo::None { if cx.sess().opts.debuginfo != DebugInfo::None {
debuginfo::finalize(&cx); cx.debuginfo_finalize();
} }
cx.stats.into_inner() cx.consume_stats().into_inner()
}; };
(stats, ModuleCodegen { (stats, ModuleCodegen {

View file

@ -443,4 +443,11 @@ impl StaticMethods<'tcx> for CodegenCx<'ll, 'tcx> {
} }
} }
} }
fn static_replace_all_uses(&self, old_g: &'ll Value, new_g: &'ll Value) {
unsafe {
let bitcast = llvm::LLVMConstPointerCast(new_g, self.val_ty(old_g));
llvm::LLVMReplaceAllUsesWith(old_g, bitcast);
llvm::LLVMDeleteGlobal(old_g);
}
}
} }

View file

@ -421,10 +421,22 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
&self.stats &self.stats
} }
fn consume_stats(self) -> RefCell<Stats> {
self.stats
}
fn codegen_unit(&self) -> &Arc<CodegenUnit<'tcx>> { fn codegen_unit(&self) -> &Arc<CodegenUnit<'tcx>> {
&self.codegen_unit &self.codegen_unit
} }
fn statics_to_rauw(&self) -> &RefCell<Vec<(&'ll Value, &'ll Value)>> {
&self.statics_to_rauw
}
fn used_statics(&self) -> &RefCell<Vec<&'ll Value>> {
&self.used_statics
}
fn set_frame_pointer_elimination(&self, llfn: &'ll Value) { fn set_frame_pointer_elimination(&self, llfn: &'ll Value) {
attributes::set_frame_pointer_elimination(self, llfn) attributes::set_frame_pointer_elimination(self, llfn)
} }
@ -432,6 +444,25 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
fn apply_target_cpu_attr(&self, llfn: &'ll Value) { fn apply_target_cpu_attr(&self, llfn: &'ll Value) {
attributes::apply_target_cpu_attr(self, llfn) attributes::apply_target_cpu_attr(self, llfn)
} }
fn create_used_variable(&self) {
let name = const_cstr!("llvm.used");
let section = const_cstr!("llvm.metadata");
let array = self.const_array(
&self.type_ptr_to(self.type_i8()),
&*self.used_statics.borrow()
);
unsafe {
let g = llvm::LLVMAddGlobal(self.llmod,
self.val_ty(array),
name.as_ptr());
llvm::LLVMSetInitializer(g, array);
llvm::LLVMRustSetLinkage(g, llvm::Linkage::AppendingLinkage);
llvm::LLVMSetSection(g, section.as_ptr());
}
}
} }
impl IntrinsicDeclarationMethods<'tcx> for CodegenCx<'b, 'tcx> { impl IntrinsicDeclarationMethods<'tcx> for CodegenCx<'b, 'tcx> {

View file

@ -585,4 +585,8 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
) -> &'ll DILexicalBlock { ) -> &'ll DILexicalBlock {
metadata::extend_scope_to_file(&self, scope_metadata, file, defining_crate) metadata::extend_scope_to_file(&self, scope_metadata, file, defining_crate)
} }
fn debuginfo_finalize(&self) {
finalize(self)
}
} }

View file

@ -11,13 +11,15 @@
use rustc::ty::layout::{HasTyCtxt, LayoutOf, TyLayout}; use rustc::ty::layout::{HasTyCtxt, LayoutOf, TyLayout};
use rustc::ty::Ty; use rustc::ty::Ty;
use super::CodegenObject; use super::{CodegenMethods, CodegenObject};
use monomorphize::partitioning::CodegenUnit;
use rustc::middle::allocator::AllocatorKind; use rustc::middle::allocator::AllocatorKind;
use rustc::middle::cstore::EncodedMetadata; use rustc::middle::cstore::EncodedMetadata;
use rustc::session::Session; use rustc::session::Session;
use rustc::ty::TyCtxt; use rustc::ty::TyCtxt;
use std::any::Any; use std::any::Any;
use std::sync::mpsc::Receiver; use std::sync::mpsc::Receiver;
use std::sync::Arc;
use time_graph::TimeGraph; use time_graph::TimeGraph;
use ModuleCodegen; use ModuleCodegen;
@ -40,16 +42,16 @@ impl<'tcx, T> Backend<'tcx> for T where
{} {}
pub trait BackendMethods { pub trait BackendMethods {
type Metadata; type Module;
type OngoingCodegen; type OngoingCodegen;
fn new_metadata(&self, sess: &Session, mod_name: &str) -> Self::Metadata; fn new_metadata(&self, sess: &Session, mod_name: &str) -> Self::Module;
fn write_metadata<'a, 'gcx>( fn write_metadata<'b, 'gcx>(
&self, &self,
tcx: TyCtxt<'a, 'gcx, 'gcx>, tcx: TyCtxt<'b, 'gcx, 'gcx>,
metadata: &Self::Metadata, metadata: &Self::Module,
) -> EncodedMetadata; ) -> EncodedMetadata;
fn codegen_allocator(&self, tcx: TyCtxt, mods: &Self::Metadata, kind: AllocatorKind); fn codegen_allocator(&self, tcx: TyCtxt, mods: &Self::Module, kind: AllocatorKind);
fn start_async_codegen( fn start_async_codegen(
&self, &self,
@ -63,10 +65,21 @@ pub trait BackendMethods {
&self, &self,
codegen: &Self::OngoingCodegen, codegen: &Self::OngoingCodegen,
tcx: TyCtxt, tcx: TyCtxt,
module: ModuleCodegen<Self::Metadata>, module: ModuleCodegen<Self::Module>,
); );
fn codegen_aborted(codegen: Self::OngoingCodegen); fn codegen_aborted(codegen: Self::OngoingCodegen);
fn codegen_finished(&self, codegen: &Self::OngoingCodegen, tcx: TyCtxt); fn codegen_finished(&self, codegen: &Self::OngoingCodegen, tcx: TyCtxt);
fn check_for_errors(&self, codegen: &Self::OngoingCodegen, sess: &Session); fn check_for_errors(&self, codegen: &Self::OngoingCodegen, sess: &Session);
fn wait_for_signal_to_codegen_item(&self, codegen: &Self::OngoingCodegen); fn wait_for_signal_to_codegen_item(&self, codegen: &Self::OngoingCodegen);
} }
pub trait BackendCodegenCxMethods<'a, 'tcx: 'a>: BackendMethods {
type CodegenCx: CodegenMethods<'tcx>;
fn new_codegen_context(
&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
codegen_unit: Arc<CodegenUnit<'tcx>>,
llvm_module: &'a Self::Module,
) -> Self::CodegenCx;
}

View file

@ -47,6 +47,7 @@ pub trait DebugInfoMethods<'tcx>: Backend<'tcx> {
file: &SourceFile, file: &SourceFile,
defining_crate: CrateNum, defining_crate: CrateNum,
) -> Self::DIScope; ) -> Self::DIScope;
fn debuginfo_finalize(&self);
} }
pub trait DebugInfoBuilderMethods<'tcx>: HasCodegen<'tcx> { pub trait DebugInfoBuilderMethods<'tcx>: HasCodegen<'tcx> {

View file

@ -30,7 +30,11 @@ pub trait MiscMethods<'tcx>: Backend<'tcx> {
fn eh_unwind_resume(&self) -> Self::Value; fn eh_unwind_resume(&self) -> Self::Value;
fn sess(&self) -> &Session; fn sess(&self) -> &Session;
fn stats(&self) -> &RefCell<Stats>; fn stats(&self) -> &RefCell<Stats>;
fn consume_stats(self) -> RefCell<Stats>;
fn codegen_unit(&self) -> &Arc<CodegenUnit<'tcx>>; fn codegen_unit(&self) -> &Arc<CodegenUnit<'tcx>>;
fn statics_to_rauw(&self) -> &RefCell<Vec<(Self::Value, Self::Value)>>;
fn used_statics(&self) -> &RefCell<Vec<Self::Value>>;
fn set_frame_pointer_elimination(&self, llfn: Self::Value); fn set_frame_pointer_elimination(&self, llfn: Self::Value);
fn apply_target_cpu_attr(&self, llfn: Self::Value); fn apply_target_cpu_attr(&self, llfn: Self::Value);
fn create_used_variable(&self);
} }

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, BackendMethods, BackendTypes}; pub use self::backend::{Backend, BackendCodegenCxMethods, 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

@ -19,4 +19,5 @@ pub trait StaticMethods<'tcx>: Backend<'tcx> {
fn static_addr_of(&self, cv: Self::Value, align: Align, kind: Option<&str>) -> Self::Value; fn static_addr_of(&self, cv: Self::Value, align: Align, kind: Option<&str>) -> Self::Value;
fn get_static(&self, def_id: DefId) -> Self::Value; fn get_static(&self, def_id: DefId) -> Self::Value;
fn codegen_static(&self, def_id: DefId, is_mutable: bool); fn codegen_static(&self, def_id: DefId, is_mutable: bool);
fn static_replace_all_uses(&self, old_g: Self::Value, new_g: Self::Value);
} }

View file

@ -72,9 +72,12 @@ use interfaces::*;
use time_graph::TimeGraph; use time_graph::TimeGraph;
use std::sync::mpsc::Receiver; use std::sync::mpsc::Receiver;
use back::write::{self, OngoingCodegen}; use back::write::{self, OngoingCodegen};
use context::CodegenCx;
use monomorphize::partitioning::CodegenUnit;
pub use llvm_util::target_features; pub use llvm_util::target_features;
use std::any::Any; use std::any::Any;
use std::sync::Arc;
use std::sync::mpsc; use std::sync::mpsc;
use rustc_data_structures::sync::Lrc; use rustc_data_structures::sync::Lrc;
@ -139,15 +142,15 @@ mod value;
pub struct LlvmCodegenBackend(()); pub struct LlvmCodegenBackend(());
impl BackendMethods for LlvmCodegenBackend { impl BackendMethods for LlvmCodegenBackend {
type Metadata = ModuleLlvm; type Module = ModuleLlvm;
type OngoingCodegen = OngoingCodegen; type OngoingCodegen = OngoingCodegen;
fn new_metadata(&self, sess: &Session, mod_name: &str) -> ModuleLlvm { fn new_metadata(&self, sess: &Session, mod_name: &str) -> ModuleLlvm {
ModuleLlvm::new(sess, mod_name) ModuleLlvm::new(sess, mod_name)
} }
fn write_metadata<'a, 'gcx>( fn write_metadata<'b, 'gcx>(
&self, &self,
tcx: TyCtxt<'a, 'gcx, 'gcx>, tcx: TyCtxt<'b, 'gcx, 'gcx>,
metadata: &ModuleLlvm metadata: &ModuleLlvm
) -> EncodedMetadata { ) -> EncodedMetadata {
base::write_metadata(tcx, metadata) base::write_metadata(tcx, metadata)
@ -187,6 +190,19 @@ impl BackendMethods for LlvmCodegenBackend {
} }
} }
impl<'a, 'tcx: 'a> BackendCodegenCxMethods<'a, 'tcx> for LlvmCodegenBackend {
type CodegenCx = CodegenCx<'a, 'tcx>;
fn new_codegen_context(
&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
codegen_unit: Arc<CodegenUnit<'tcx>>,
llvm_module: &'a ModuleLlvm
) -> CodegenCx<'a, 'tcx> {
CodegenCx::new(tcx, codegen_unit, llvm_module)
}
}
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 {}

View file

@ -27,17 +27,14 @@ use rustc::mir::mono::{Linkage, Visibility};
use rustc::ty::TypeFoldable; use rustc::ty::TypeFoldable;
use rustc::ty::layout::{LayoutOf, HasTyCtxt}; use rustc::ty::layout::{LayoutOf, HasTyCtxt};
use std::fmt; use std::fmt;
use builder::Builder;
use interfaces::*; use interfaces::*;
pub use rustc::mir::mono::MonoItem; pub use rustc::mir::mono::MonoItem;
pub use rustc_mir::monomorphize::item::MonoItemExt as BaseMonoItemExt; pub use rustc_mir::monomorphize::item::MonoItemExt as BaseMonoItemExt;
pub trait MonoItemExt<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> : pub trait MonoItemExt<'a, 'tcx: 'a>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> {
fmt::Debug + BaseMonoItemExt<'a, 'tcx> fn define<Bx: BuilderMethods<'a, 'tcx>>(&self, cx: &'a Bx::CodegenCx) {
{
fn define(&self, cx: &'a Bx::CodegenCx) {
debug!("BEGIN IMPLEMENTING '{} ({})' in cgu {}", debug!("BEGIN IMPLEMENTING '{} ({})' in cgu {}",
self.to_string(cx.tcx()), self.to_string(cx.tcx()),
self.to_raw_string(), self.to_raw_string(),
@ -76,10 +73,12 @@ pub trait MonoItemExt<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> :
cx.codegen_unit().name()); cx.codegen_unit().name());
} }
fn predefine(&self, fn predefine<Bx: BuilderMethods<'a, 'tcx>>(
cx: &'a Bx::CodegenCx, &self,
linkage: Linkage, cx: &'a Bx::CodegenCx,
visibility: Visibility) { linkage: Linkage,
visibility: Visibility
) {
debug!("BEGIN PREDEFINING '{} ({})' in cgu {}", debug!("BEGIN PREDEFINING '{} ({})' in cgu {}",
self.to_string(cx.tcx()), self.to_string(cx.tcx()),
self.to_raw_string(), self.to_raw_string(),
@ -122,7 +121,7 @@ pub trait MonoItemExt<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> :
} }
} }
impl MonoItemExt<'a, 'tcx, Builder<'a, 'll, 'tcx>> for MonoItem<'tcx> {} impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {}
impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> { impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> {
fn predefine_static(&self, fn predefine_static(&self,