mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-27 22:34:14 +00:00
Preparing the generalization of base:compile_coodegen_unit
This commit is contained in:
parent
91a2a80692
commit
6819e6e6e1
@ -27,6 +27,7 @@ use super::ModuleLlvm;
|
||||
use super::ModuleCodegen;
|
||||
use super::ModuleKind;
|
||||
use super::CachedModuleCodegen;
|
||||
use super::LlvmCodegenBackend;
|
||||
|
||||
use abi;
|
||||
use back::write;
|
||||
@ -53,8 +54,6 @@ use builder::{Builder, MemFlags};
|
||||
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 @@ 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,
|
||||
"assert dep graph",
|
||||
|| 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)
|
||||
-> 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<ModuleLlvm>)
|
||||
{
|
||||
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::<Builder<&Value>>(&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::<Builder<&Value>>(&cx);
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
// 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 {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -421,10 +421,22 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||
&self.stats
|
||||
}
|
||||
|
||||
fn consume_stats(self) -> RefCell<Stats> {
|
||||
self.stats
|
||||
}
|
||||
|
||||
fn codegen_unit(&self) -> &Arc<CodegenUnit<'tcx>> {
|
||||
&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) {
|
||||
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) {
|
||||
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> {
|
||||
|
@ -585,4 +585,8 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||
) -> &'ll DILexicalBlock {
|
||||
metadata::extend_scope_to_file(&self, scope_metadata, file, defining_crate)
|
||||
}
|
||||
|
||||
fn debuginfo_finalize(&self) {
|
||||
finalize(self)
|
||||
}
|
||||
}
|
||||
|
@ -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 @@ pub trait BackendMethods {
|
||||
&self,
|
||||
codegen: &Self::OngoingCodegen,
|
||||
tcx: TyCtxt,
|
||||
module: ModuleCodegen<Self::Metadata>,
|
||||
module: ModuleCodegen<Self::Module>,
|
||||
);
|
||||
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<CodegenUnit<'tcx>>,
|
||||
llvm_module: &'a Self::Module,
|
||||
) -> Self::CodegenCx;
|
||||
}
|
||||
|
@ -47,6 +47,7 @@ pub trait DebugInfoMethods<'tcx>: Backend<'tcx> {
|
||||
file: &SourceFile,
|
||||
defining_crate: CrateNum,
|
||||
) -> Self::DIScope;
|
||||
fn debuginfo_finalize(&self);
|
||||
}
|
||||
|
||||
pub trait DebugInfoBuilderMethods<'tcx>: HasCodegen<'tcx> {
|
||||
|
@ -30,7 +30,11 @@ pub trait MiscMethods<'tcx>: Backend<'tcx> {
|
||||
fn eh_unwind_resume(&self) -> Self::Value;
|
||||
fn sess(&self) -> &Session;
|
||||
fn stats(&self) -> &RefCell<Stats>;
|
||||
fn consume_stats(self) -> RefCell<Stats>;
|
||||
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 apply_target_cpu_attr(&self, llfn: Self::Value);
|
||||
fn create_used_variable(&self);
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ mod type_;
|
||||
|
||||
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};
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -72,9 +72,12 @@ use interfaces::*;
|
||||
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 value;
|
||||
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 @@ 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 !Sync for LlvmCodegenBackend {}
|
||||
|
@ -27,17 +27,14 @@ use rustc::mir::mono::{Linkage, Visibility};
|
||||
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<Bx: BuilderMethods<'a, 'tcx>>(&self, cx: &'a Bx::CodegenCx) {
|
||||
debug!("BEGIN IMPLEMENTING '{} ({})' in cgu {}",
|
||||
self.to_string(cx.tcx()),
|
||||
self.to_raw_string(),
|
||||
@ -76,10 +73,12 @@ pub trait MonoItemExt<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> :
|
||||
cx.codegen_unit().name());
|
||||
}
|
||||
|
||||
fn predefine(&self,
|
||||
cx: &'a Bx::CodegenCx,
|
||||
linkage: Linkage,
|
||||
visibility: Visibility) {
|
||||
fn predefine<Bx: BuilderMethods<'a, 'tcx>>(
|
||||
&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 @@ 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> {
|
||||
fn predefine_static(&self,
|
||||
|
Loading…
Reference in New Issue
Block a user