use rustc::middle::cstore::{EncodedMetadata};
use rustc::ty::TyCtxt;
use rustc::middle::exported_symbols;
-use rustc::session::config::{self, DebugInfo};
+use rustc::session::config::DebugInfo;
use rustc_codegen_ssa::mono_item::MonoItemExt;
use rustc_data_structures::small_c_str::SmallCStr;
use crate::value::Value;
-
-pub fn write_metadata<'a, 'gcx>(
+pub fn write_compressed_metadata<'a, 'gcx>(
tcx: TyCtxt<'a, 'gcx, 'gcx>,
+ metadata: &EncodedMetadata,
llvm_module: &mut ModuleLlvm
-) -> EncodedMetadata {
+) {
use std::io::Write;
use flate2::Compression;
use flate2::write::DeflateEncoder;
let (metadata_llcx, metadata_llmod) = (&*llvm_module.llcx, llvm_module.llmod());
-
- #[derive(PartialEq, Eq, PartialOrd, Ord)]
- enum MetadataKind {
- None,
- Uncompressed,
- Compressed
- }
-
- let kind = tcx.sess.crate_types.borrow().iter().map(|ty| {
- match *ty {
- config::CrateType::Executable |
- config::CrateType::Staticlib |
- config::CrateType::Cdylib => MetadataKind::None,
-
- config::CrateType::Rlib => MetadataKind::Uncompressed,
-
- config::CrateType::Dylib |
- config::CrateType::ProcMacro => MetadataKind::Compressed,
- }
- }).max().unwrap_or(MetadataKind::None);
-
- if kind == MetadataKind::None {
- return EncodedMetadata::new();
- }
-
- let metadata = tcx.encode_metadata();
- if kind == MetadataKind::Uncompressed {
- return metadata;
- }
-
- assert!(kind == MetadataKind::Compressed);
let mut compressed = tcx.metadata_encoding_version();
DeflateEncoder::new(&mut compressed, Compression::fast())
.write_all(&metadata.raw_data).unwrap();
let directive = CString::new(directive).unwrap();
llvm::LLVMSetModuleInlineAsm(metadata_llmod, directive.as_ptr())
}
- return metadata;
}
pub struct ValueIter<'ll> {
ModuleLlvm::new_metadata(tcx, mod_name)
}
- fn write_metadata<'b, 'gcx>(
+ fn write_compressed_metadata<'b, 'gcx>(
&self,
tcx: TyCtxt<'b, 'gcx, 'gcx>,
- metadata: &mut ModuleLlvm
- ) -> EncodedMetadata {
- base::write_metadata(tcx, metadata)
+ metadata: &EncodedMetadata,
+ llvm_module: &mut ModuleLlvm
+ ) {
+ base::write_compressed_metadata(tcx, metadata, llvm_module)
}
fn codegen_allocator<'b, 'gcx>(
&self,
fn codegen_crate<'b, 'tcx>(
&self,
tcx: TyCtxt<'b, 'tcx, 'tcx>,
+ metadata: EncodedMetadata,
+ need_metadata_module: bool,
rx: mpsc::Receiver<Box<dyn Any + Send>>
) -> Box<dyn Any> {
- box rustc_codegen_ssa::base::codegen_crate(LlvmCodegenBackend(()), tcx, rx)
+ box rustc_codegen_ssa::base::codegen_crate(
+ LlvmCodegenBackend(()), tcx, metadata, need_metadata_module, rx)
}
fn join_codegen_and_link(
use rustc::dep_graph::cgu_reuse_tracker::CguReuse;
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
+use rustc::middle::cstore::EncodedMetadata;
use rustc::middle::lang_items::StartFnLangItem;
use rustc::middle::weak_lang_items;
use rustc::mir::mono::{Stats, CodegenUnitNameBuilder};
use rustc::ty::query::Providers;
use rustc::middle::cstore::{self, LinkagePreference};
use rustc::util::common::{time, print_time_passes_entry};
-use rustc::session::config::{self, CrateType, EntryFnType, Lto};
+use rustc::session::config::{self, EntryFnType, Lto};
use rustc::session::Session;
use rustc_mir::monomorphize::item::DefPathBasedNames;
use rustc_mir::monomorphize::Instance;
pub fn codegen_crate<B: ExtraBackendMethods>(
backend: B,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
+ metadata: EncodedMetadata,
+ need_metadata_module: bool,
rx: mpsc::Receiver<Box<dyn Any + Send>>
) -> OngoingCodegen<B> {
check_for_rustc_errors_attr(tcx);
- let cgu_name_builder = &mut CodegenUnitNameBuilder::new(tcx);
-
- // Codegen the metadata.
- tcx.sess.profiler(|p| p.start_activity("codegen crate metadata"));
-
- let metadata_cgu_name = cgu_name_builder.build_cgu_name(LOCAL_CRATE,
- &["crate"],
- Some("metadata")).as_str()
- .to_string();
- let mut metadata_llvm_module = backend.new_metadata(tcx, &metadata_cgu_name);
- let metadata = time(tcx.sess, "write metadata", || {
- backend.write_metadata(tcx, &mut metadata_llvm_module)
- });
- tcx.sess.profiler(|p| p.end_activity("codegen crate metadata"));
-
// Skip crate items and just output metadata in -Z no-codegen mode.
if tcx.sess.opts.debugging_opts.no_codegen ||
!tcx.sess.opts.output_types.should_codegen() {
return ongoing_codegen;
}
+ let cgu_name_builder = &mut CodegenUnitNameBuilder::new(tcx);
+
// Run the monomorphization collector and partition the collected items into
// codegen units.
let codegen_units = tcx.collect_and_partition_mono_items(LOCAL_CRATE).1;
ongoing_codegen.submit_pre_codegened_module_to_llvm(tcx, allocator_module);
}
- let needs_metadata_module = tcx.sess.crate_types.borrow().iter().any(|ct| {
- match *ct {
- CrateType::Dylib |
- CrateType::ProcMacro => true,
- CrateType::Executable |
- CrateType::Rlib |
- CrateType::Staticlib |
- CrateType::Cdylib => false,
- }
- });
- if needs_metadata_module {
+ if need_metadata_module {
+ // Codegen the encoded metadata.
+ tcx.sess.profiler(|p| p.start_activity("codegen crate metadata"));
+
+ let metadata_cgu_name = cgu_name_builder.build_cgu_name(LOCAL_CRATE,
+ &["crate"],
+ Some("metadata")).as_str()
+ .to_string();
+ let mut metadata_llvm_module = backend.new_metadata(tcx, &metadata_cgu_name);
+ time(tcx.sess, "write compressed metadata", || {
+ backend.write_compressed_metadata(tcx, &ongoing_codegen.metadata,
+ &mut metadata_llvm_module);
+ });
+ tcx.sess.profiler(|p| p.end_activity("codegen crate metadata"));
+
let metadata_module = ModuleCodegen {
name: metadata_cgu_name,
module_llvm: metadata_llvm_module,
pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Send {
fn new_metadata(&self, sess: TyCtxt<'_, '_, '_>, mod_name: &str) -> Self::Module;
- fn write_metadata<'b, 'gcx>(
+ fn write_compressed_metadata<'b, 'gcx>(
&self,
tcx: TyCtxt<'b, 'gcx, 'gcx>,
- metadata: &mut Self::Module,
- ) -> EncodedMetadata;
+ metadata: &EncodedMetadata,
+ llvm_module: &mut Self::Module,
+ );
fn codegen_allocator<'b, 'gcx>(
&self,
tcx: TyCtxt<'b, 'gcx, 'gcx>,
use rustc::session::config::{OutputFilenames, PrintRequest};
use rustc::ty::TyCtxt;
use rustc::ty::query::Providers;
-use rustc::middle::cstore::MetadataLoader;
+use rustc::middle::cstore::{EncodedMetadata, MetadataLoader};
use rustc::dep_graph::DepGraph;
pub use rustc_data_structures::sync::MetadataRef;
fn codegen_crate<'a, 'tcx>(
&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
+ metadata: EncodedMetadata,
+ need_metadata_module: bool,
rx: mpsc::Receiver<Box<dyn Any + Send>>
) -> Box<dyn Any>;
use rustc::util::common::{time, ErrorReported};
use rustc::util::profiling::ProfileCategory;
use rustc::session::{CompileResult, CrateDisambiguator, Session};
-use rustc::session::config::{self, Input, OutputFilenames, OutputType};
+use rustc::session::config::{self, CrateType, Input, OutputFilenames, OutputType};
use rustc::session::search_paths::PathKind;
use rustc_allocator as allocator;
use rustc_borrowck as borrowck;
Ok(())
}
+fn encode_metadata<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) -> (middle::cstore::EncodedMetadata, bool) {
+ #[derive(PartialEq, Eq, PartialOrd, Ord)]
+ enum MetadataKind {
+ None,
+ Uncompressed,
+ Compressed
+ }
+
+ let metadata_kind = tcx.sess.crate_types.borrow().iter().map(|ty| {
+ match *ty {
+ CrateType::Executable |
+ CrateType::Staticlib |
+ CrateType::Cdylib => MetadataKind::None,
+
+ CrateType::Rlib => MetadataKind::Uncompressed,
+
+ CrateType::Dylib |
+ CrateType::ProcMacro => MetadataKind::Compressed,
+ }
+ }).max().unwrap_or(MetadataKind::None);
+
+ let need_metadata_module = metadata_kind == MetadataKind::Compressed;
+
+ let metadata = match metadata_kind {
+ MetadataKind::None => middle::cstore::EncodedMetadata::new(),
+ MetadataKind::Uncompressed |
+ MetadataKind::Compressed => tcx.encode_metadata(),
+ };
+
+ (metadata, need_metadata_module)
+}
+
/// Runs the codegen backend, after which the AST and analysis can
/// be discarded.
pub fn start_codegen<'tcx>(
}
time(tcx.sess, "resolving dependency formats", || {
- ::rustc::middle::dependency_format::calculate(tcx)
+ middle::dependency_format::calculate(tcx)
+ });
+
+ let (metadata, need_metadata_module) = time(tcx.sess, "metadata encoding", || {
+ encode_metadata(tcx)
});
tcx.sess.profiler(|p| p.start_activity("codegen crate"));
- let codegen = time(tcx.sess, "codegen", move || codegen_backend.codegen_crate(tcx, rx));
+ let codegen = time(tcx.sess, "codegen", move || {
+ codegen_backend.codegen_crate(tcx, metadata, need_metadata_module, rx)
+ });
tcx.sess.profiler(|p| p.end_activity("codegen crate"));
if log_enabled!(::log::Level::Info) {
use rustc::session::config::OutputFilenames;
use rustc::ty::TyCtxt;
use rustc::ty::query::Providers;
-use rustc::middle::cstore::MetadataLoader;
+use rustc::middle::cstore::{EncodedMetadata, MetadataLoader};
use rustc::dep_graph::DepGraph;
use rustc::util::common::ErrorReported;
use rustc_codegen_utils::codegen_backend::CodegenBackend;
fn codegen_crate<'a, 'tcx>(
&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
+ _metadata: EncodedMetadata,
+ _need_metadata_module: bool,
_rx: mpsc::Receiver<Box<Any + Send>>
) -> Box<Any> {
use rustc::hir::def_id::LOCAL_CRATE;