From 6819e6e6e1c049b5e70ebd4fde791623e7ed2aaa Mon Sep 17 00:00:00 2001 From: Denis Merigoux Date: Wed, 26 Sep 2018 17:00:01 +0200 Subject: [PATCH] Preparing the generalization of base:compile_coodegen_unit --- src/librustc_codegen_llvm/base.rs | 51 ++++++------------- src/librustc_codegen_llvm/consts.rs | 7 +++ src/librustc_codegen_llvm/context.rs | 31 +++++++++++ src/librustc_codegen_llvm/debuginfo/mod.rs | 4 ++ .../interfaces/backend.rs | 29 ++++++++--- .../interfaces/debuginfo.rs | 1 + src/librustc_codegen_llvm/interfaces/misc.rs | 4 ++ src/librustc_codegen_llvm/interfaces/mod.rs | 2 +- .../interfaces/statics.rs | 1 + src/librustc_codegen_llvm/lib.rs | 22 ++++++-- src/librustc_codegen_llvm/mono_item.rs | 19 ++++--- 11 files changed, 114 insertions(+), 57 deletions(-) diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs index 5fd413b4c7b..74432870705 100644 --- a/src/librustc_codegen_llvm/base.rs +++ b/src/librustc_codegen_llvm/base.rs @@ -27,6 +27,7 @@ use super::ModuleCodegen; use super::ModuleKind; use super::CachedModuleCodegen; +use super::LlvmCodegenBackend; use abi; use back::write; @@ -53,8 +54,6 @@ use callee; use rustc_mir::monomorphize::item::DefPathBasedNames; use common::{self, IntPredicate, RealPredicate, TypeKind}; -use context::CodegenCx; -use debuginfo; use meth; use mir; use monomorphize::Instance; @@ -968,7 +967,7 @@ fn drop(&mut self) { } } -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, "assert dep graph", || rustc_incremental::assert_dep_graph(tcx)); @@ -1067,7 +1066,7 @@ fn load_wasm_imports(&mut self, tcx: TyCtxt, cnum: CrateNum) { } } -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) -> Stats { let start_time = Instant::now(); @@ -1089,26 +1088,26 @@ fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, cost); return stats; - fn module_codegen<'a, 'tcx>( - tcx: TyCtxt<'a, 'tcx, 'tcx>, + fn module_codegen<'ll, 'tcx>( + tcx: TyCtxt<'ll, 'tcx, 'tcx>, cgu_name: InternedString) -> (Stats, ModuleCodegen) { + let backend = LlvmCodegenBackend(()); let cgu = tcx.codegen_unit(cgu_name); - // 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 cx = CodegenCx::new(tcx, cgu, &llvm_module); + let cx = backend.new_codegen_context(tcx, cgu, &llvm_module); let mono_items = cx.codegen_unit .items_in_deterministic_order(cx.tcx); for &(mono_item, (linkage, visibility)) in &mono_items { - mono_item.predefine(&cx, linkage, visibility); + mono_item.predefine::>(&cx, linkage, visibility); } // ... and now that we have everything pre-defined, fill out those definitions. for &(mono_item, _) in &mono_items { - mono_item.define(&cx); + mono_item.define::>(&cx); } // If this codegen unit contains the main function, also create the @@ -1116,40 +1115,22 @@ fn module_codegen<'a, 'tcx>( maybe_create_entry_wrapper::>(&cx); // Run replace-all-uses-with for statics that need it - for &(old_g, new_g) in cx.statics_to_rauw.borrow().iter() { - unsafe { - let bitcast = llvm::LLVMConstPointerCast(new_g, cx.val_ty(old_g)); - llvm::LLVMReplaceAllUsesWith(old_g, bitcast); - llvm::LLVMDeleteGlobal(old_g); - } + for &(old_g, new_g) in cx.statics_to_rauw().borrow().iter() { + cx.static_replace_all_uses(old_g, new_g) } // Create the llvm.used variable // This variable has type [N x i8*] and is stored in the llvm.metadata section - if !cx.used_statics.borrow().is_empty() { - let name = const_cstr!("llvm.used"); - 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()); - } + if !cx.used_statics().borrow().is_empty() { + cx.create_used_variable() } // Finalize debuginfo if cx.sess().opts.debuginfo != DebugInfo::None { - debuginfo::finalize(&cx); + cx.debuginfo_finalize(); } - cx.stats.into_inner() + cx.consume_stats().into_inner() }; (stats, ModuleCodegen { diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs index aef13a20877..cbbda28994b 100644 --- a/src/librustc_codegen_llvm/consts.rs +++ b/src/librustc_codegen_llvm/consts.rs @@ -443,4 +443,11 @@ fn codegen_static( } } } + 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); + } + } } diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index af75c15e260..b0d153f8efc 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -421,10 +421,22 @@ fn stats(&self) -> &RefCell { &self.stats } + fn consume_stats(self) -> RefCell { + self.stats + } + fn codegen_unit(&self) -> &Arc> { &self.codegen_unit } + fn statics_to_rauw(&self) -> &RefCell> { + &self.statics_to_rauw + } + + fn used_statics(&self) -> &RefCell> { + &self.used_statics + } + fn set_frame_pointer_elimination(&self, llfn: &'ll Value) { attributes::set_frame_pointer_elimination(self, llfn) } @@ -432,6 +444,25 @@ fn set_frame_pointer_elimination(&self, llfn: &'ll Value) { fn apply_target_cpu_attr(&self, llfn: &'ll Value) { 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> { diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index eef3ddb24a7..8ef7350747d 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -585,4 +585,8 @@ fn extend_scope_to_file( ) -> &'ll DILexicalBlock { metadata::extend_scope_to_file(&self, scope_metadata, file, defining_crate) } + + fn debuginfo_finalize(&self) { + finalize(self) + } } diff --git a/src/librustc_codegen_llvm/interfaces/backend.rs b/src/librustc_codegen_llvm/interfaces/backend.rs index a5df7e5af6f..b34bb00682f 100644 --- a/src/librustc_codegen_llvm/interfaces/backend.rs +++ b/src/librustc_codegen_llvm/interfaces/backend.rs @@ -11,13 +11,15 @@ use rustc::ty::layout::{HasTyCtxt, LayoutOf, TyLayout}; use rustc::ty::Ty; -use super::CodegenObject; +use super::{CodegenMethods, CodegenObject}; +use monomorphize::partitioning::CodegenUnit; 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 std::sync::Arc; use time_graph::TimeGraph; use ModuleCodegen; @@ -40,16 +42,16 @@ impl<'tcx, T> Backend<'tcx> for T where {} pub trait BackendMethods { - type Metadata; + type Module; type OngoingCodegen; - fn new_metadata(&self, sess: &Session, mod_name: &str) -> Self::Metadata; - fn write_metadata<'a, 'gcx>( + fn new_metadata(&self, sess: &Session, mod_name: &str) -> Self::Module; + fn write_metadata<'b, 'gcx>( &self, - tcx: TyCtxt<'a, 'gcx, 'gcx>, - metadata: &Self::Metadata, + tcx: TyCtxt<'b, 'gcx, 'gcx>, + metadata: &Self::Module, ) -> 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( &self, @@ -63,10 +65,21 @@ fn submit_pre_codegened_module_to_llvm( &self, codegen: &Self::OngoingCodegen, tcx: TyCtxt, - module: ModuleCodegen, + module: ModuleCodegen, ); 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); } + +pub trait BackendCodegenCxMethods<'a, 'tcx: 'a>: BackendMethods { + type CodegenCx: CodegenMethods<'tcx>; + + fn new_codegen_context( + &self, + tcx: TyCtxt<'a, 'tcx, 'tcx>, + codegen_unit: Arc>, + llvm_module: &'a Self::Module, + ) -> Self::CodegenCx; +} diff --git a/src/librustc_codegen_llvm/interfaces/debuginfo.rs b/src/librustc_codegen_llvm/interfaces/debuginfo.rs index eca60e9c9ce..4e24e12bc68 100644 --- a/src/librustc_codegen_llvm/interfaces/debuginfo.rs +++ b/src/librustc_codegen_llvm/interfaces/debuginfo.rs @@ -47,6 +47,7 @@ fn extend_scope_to_file( file: &SourceFile, defining_crate: CrateNum, ) -> Self::DIScope; + fn debuginfo_finalize(&self); } pub trait DebugInfoBuilderMethods<'tcx>: HasCodegen<'tcx> { diff --git a/src/librustc_codegen_llvm/interfaces/misc.rs b/src/librustc_codegen_llvm/interfaces/misc.rs index 7c5108500f1..2557b51b76d 100644 --- a/src/librustc_codegen_llvm/interfaces/misc.rs +++ b/src/librustc_codegen_llvm/interfaces/misc.rs @@ -30,7 +30,11 @@ fn vtables( fn eh_unwind_resume(&self) -> Self::Value; fn sess(&self) -> &Session; fn stats(&self) -> &RefCell; + fn consume_stats(self) -> RefCell; fn codegen_unit(&self) -> &Arc>; + fn statics_to_rauw(&self) -> &RefCell>; + fn used_statics(&self) -> &RefCell>; fn set_frame_pointer_elimination(&self, llfn: Self::Value); fn apply_target_cpu_attr(&self, llfn: Self::Value); + fn create_used_variable(&self); } diff --git a/src/librustc_codegen_llvm/interfaces/mod.rs b/src/librustc_codegen_llvm/interfaces/mod.rs index e0ce05d0a84..019c4410e67 100644 --- a/src/librustc_codegen_llvm/interfaces/mod.rs +++ b/src/librustc_codegen_llvm/interfaces/mod.rs @@ -22,7 +22,7 @@ pub use self::abi::{AbiBuilderMethods, AbiMethods}; 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::consts::ConstMethods; pub use self::debuginfo::{DebugInfoBuilderMethods, DebugInfoMethods}; diff --git a/src/librustc_codegen_llvm/interfaces/statics.rs b/src/librustc_codegen_llvm/interfaces/statics.rs index a6108781231..0feb9d5255f 100644 --- a/src/librustc_codegen_llvm/interfaces/statics.rs +++ b/src/librustc_codegen_llvm/interfaces/statics.rs @@ -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 get_static(&self, def_id: DefId) -> Self::Value; fn codegen_static(&self, def_id: DefId, is_mutable: bool); + fn static_replace_all_uses(&self, old_g: Self::Value, new_g: Self::Value); } diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index d1be81f1224..8633722204d 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -72,9 +72,12 @@ use time_graph::TimeGraph; use std::sync::mpsc::Receiver; use back::write::{self, OngoingCodegen}; +use context::CodegenCx; +use monomorphize::partitioning::CodegenUnit; pub use llvm_util::target_features; use std::any::Any; +use std::sync::Arc; use std::sync::mpsc; use rustc_data_structures::sync::Lrc; @@ -139,15 +142,15 @@ mod back { pub struct LlvmCodegenBackend(()); impl BackendMethods for LlvmCodegenBackend { - type Metadata = ModuleLlvm; + type Module = ModuleLlvm; type OngoingCodegen = OngoingCodegen; fn new_metadata(&self, sess: &Session, mod_name: &str) -> ModuleLlvm { ModuleLlvm::new(sess, mod_name) } - fn write_metadata<'a, 'gcx>( + fn write_metadata<'b, 'gcx>( &self, - tcx: TyCtxt<'a, 'gcx, 'gcx>, + tcx: TyCtxt<'b, 'gcx, 'gcx>, metadata: &ModuleLlvm ) -> EncodedMetadata { base::write_metadata(tcx, metadata) @@ -187,6 +190,19 @@ fn wait_for_signal_to_codegen_item(&self, codegen: &OngoingCodegen) { } } +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>, + 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 !Sync for LlvmCodegenBackend {} diff --git a/src/librustc_codegen_llvm/mono_item.rs b/src/librustc_codegen_llvm/mono_item.rs index 041cfbf00c6..1defb2c16f8 100644 --- a/src/librustc_codegen_llvm/mono_item.rs +++ b/src/librustc_codegen_llvm/mono_item.rs @@ -27,17 +27,14 @@ use rustc::ty::TypeFoldable; use rustc::ty::layout::{LayoutOf, HasTyCtxt}; use std::fmt; -use builder::Builder; use interfaces::*; pub use rustc::mir::mono::MonoItem; pub use rustc_mir::monomorphize::item::MonoItemExt as BaseMonoItemExt; -pub trait MonoItemExt<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> : - fmt::Debug + BaseMonoItemExt<'a, 'tcx> -{ - fn define(&self, cx: &'a Bx::CodegenCx) { +pub trait MonoItemExt<'a, 'tcx: 'a>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> { + fn define>(&self, cx: &'a Bx::CodegenCx) { debug!("BEGIN IMPLEMENTING '{} ({})' in cgu {}", self.to_string(cx.tcx()), self.to_raw_string(), @@ -76,10 +73,12 @@ fn define(&self, cx: &'a Bx::CodegenCx) { cx.codegen_unit().name()); } - fn predefine(&self, - cx: &'a Bx::CodegenCx, - linkage: Linkage, - visibility: Visibility) { + fn predefine>( + &self, + cx: &'a Bx::CodegenCx, + linkage: Linkage, + visibility: Visibility + ) { debug!("BEGIN PREDEFINING '{} ({})' in cgu {}", self.to_string(cx.tcx()), self.to_raw_string(), @@ -122,7 +121,7 @@ fn to_raw_string(&self) -> String { } } -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> { fn predefine_static(&self, -- 2.44.0