From cba53f0be575196083fe52ecd2ec8f1c015664ce Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 13 Aug 2017 18:53:50 +0200 Subject: [PATCH 01/17] Allow writing metadata without llvm --- .gitignore | 3 ++ src/Cargo.lock | 2 + src/bootstrap/compile.rs | 7 +++- src/librustc_driver/driver.rs | 3 +- src/librustc_driver/lib.rs | 5 ++- src/librustc_trans/back/link.rs | 11 +----- src/librustc_trans/base.rs | 2 + src/librustc_trans_utils/Cargo.toml | 2 + src/librustc_trans_utils/lib.rs | 60 +++++++++++++++++++++++++++++ src/librustc_trans_utils/link.rs | 14 ++++++- 10 files changed, 95 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index b54bab177d0ae..309fbd95345a4 100644 --- a/.gitignore +++ b/.gitignore @@ -103,3 +103,6 @@ version.texi .cargo !src/vendor/** /src/target/ + +no_llvm_build + diff --git a/src/Cargo.lock b/src/Cargo.lock index 807375e00afdb..9481032985477 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -1778,7 +1778,9 @@ dependencies = [ name = "rustc_trans_utils" version = "0.0.0" dependencies = [ + "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", + "rustc_incremental 0.0.0", "syntax 0.0.0", "syntax_pos 0.0.0", ] diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 335e1690a2ea0..2e368ddf43f38 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -104,7 +104,11 @@ impl Step for Std { let out_dir = build.cargo_out(compiler, Mode::Libstd, target); build.clear_if_dirty(&out_dir, &builder.rustc(compiler)); - let mut cargo = builder.cargo(compiler, Mode::Libstd, target, "build"); + let mut cargo = if compiler.stage == 0 { + builder.cargo(compiler, Mode::Libstd, target, "build") + }else{ + builder.cargo(compiler, Mode::Libstd, target, "check") + }; std_cargo(build, &compiler, target, &mut cargo); run_cargo(build, &mut cargo, @@ -161,6 +165,7 @@ pub fn std_cargo(build: &Build, // missing // We also only build the runtimes when --enable-sanitizers (or its // config.toml equivalent) is used + //cargo.env("RUST_FLAGS", "-Zno-trans"); cargo.env("LLVM_CONFIG", build.llvm_config(target)); } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index ce4ab2c8a1de9..1520fc7def839 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -77,6 +77,8 @@ pub fn compile_input(sess: &Session, addl_plugins: Option>, control: &CompileController) -> CompileResult { use rustc_trans::back::write::OngoingCrateTranslation; + use rustc::session::config::CrateType; + macro_rules! controller_entry_point { ($point: ident, $tsess: expr, $make_state: expr, $phase_result: expr) => {{ let state = &mut $make_state; @@ -94,7 +96,6 @@ pub fn compile_input(sess: &Session, } if cfg!(not(feature="llvm")) { - use rustc::session::config::CrateType; if !sess.opts.debugging_opts.no_trans && sess.opts.output_types.should_trans() { sess.err("LLVM is not supported by this rustc. Please use -Z no-trans to compile") } diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 044f4a5eaf512..2e0193fc8a1ea 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -25,6 +25,8 @@ #![feature(rustc_diagnostic_macros)] #![feature(set_stdio)] +#[cfg(not(feature="llvm"))] +extern crate ar; extern crate arena; extern crate getopts; extern crate graphviz; @@ -157,7 +159,6 @@ pub use rustc_trans::LlvmMetadataLoader as MetadataLoader; #[cfg(not(feature="llvm"))] mod no_llvm_metadata_loader { - extern crate ar; extern crate owning_ref; use rustc::middle::cstore::MetadataLoader as MetadataLoaderTrait; @@ -166,7 +167,7 @@ mod no_llvm_metadata_loader { use std::fs::File; use std::path::Path; - use self::ar::Archive; + use ar::Archive; use self::owning_ref::{OwningRef, ErasedBoxRef}; pub struct NoLLvmMetadataLoader; diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 9d13d4ce15b79..e6ab46fa93114 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -89,15 +89,8 @@ pub const RLIB_BYTECODE_OBJECT_V1_DATA_OFFSET: usize = RLIB_BYTECODE_OBJECT_V1_DATASIZE_OFFSET + 8; pub use self::rustc_trans_utils::link::{find_crate_name, filename_for_input, - default_output_for_target, invalid_output_for_target}; - -pub fn build_link_meta(crate_hash: Fingerprint) -> LinkMeta { - let r = LinkMeta { - crate_hash: Svh::new(crate_hash.to_smaller_hash()), - }; - info!("{:?}", r); - return r; -} + default_output_for_target, invalid_output_for_target, + build_link_meta}; // The third parameter is for env vars, used on windows to set up the // path for MSVC to find its DLLs, and gcc to find its bundled diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index bfa18d84d2705..91852630fa47a 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -938,6 +938,8 @@ pub fn find_exported_symbols(tcx: TyCtxt) -> NodeSet { pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, rx: mpsc::Receiver>) -> OngoingCrateTranslation { + use back::link::rustc_trans_utils::find_exported_symbols; + check_for_rustc_errors_attr(tcx); diff --git a/src/librustc_trans_utils/Cargo.toml b/src/librustc_trans_utils/Cargo.toml index f026d4fcbc280..b91a397711140 100644 --- a/src/librustc_trans_utils/Cargo.toml +++ b/src/librustc_trans_utils/Cargo.toml @@ -10,6 +10,8 @@ crate-type = ["dylib"] test = false [dependencies] +log = "0.3" rustc = { path = "../librustc" } +rustc_incremental = { path = "../librustc_incremental" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } diff --git a/src/librustc_trans_utils/lib.rs b/src/librustc_trans_utils/lib.rs index 5e8abe59ad9a4..44f0f62d7082f 100644 --- a/src/librustc_trans_utils/lib.rs +++ b/src/librustc_trans_utils/lib.rs @@ -29,8 +29,68 @@ #![cfg_attr(stage0, feature(const_fn))] +#[macro_use] +extern crate log; extern crate rustc; +extern crate rustc_incremental; extern crate syntax; extern crate syntax_pos; +use rustc::ty::TyCtxt; +use rustc::hir; +use rustc::hir::map as hir_map; +use rustc::util::nodemap::NodeSet; + +use syntax::attr; + pub mod link; + +/// The context provided lists a set of reachable ids as calculated by +/// middle::reachable, but this contains far more ids and symbols than we're +/// actually exposing from the object file. This function will filter the set in +/// the context to the set of ids which correspond to symbols that are exposed +/// from the object file being generated. +/// +/// This list is later used by linkers to determine the set of symbols needed to +/// be exposed from a dynamic library and it's also encoded into the metadata. +pub fn find_exported_symbols(tcx: TyCtxt, reachable: &NodeSet) -> NodeSet { + reachable.iter().cloned().filter(|&id| { + // Next, we want to ignore some FFI functions that are not exposed from + // this crate. Reachable FFI functions can be lumped into two + // categories: + // + // 1. Those that are included statically via a static library + // 2. Those included otherwise (e.g. dynamically or via a framework) + // + // Although our LLVM module is not literally emitting code for the + // statically included symbols, it's an export of our library which + // needs to be passed on to the linker and encoded in the metadata. + // + // As a result, if this id is an FFI item (foreign item) then we only + // let it through if it's included statically. + match tcx.hir.get(id) { + hir_map::NodeForeignItem(..) => { + let def_id = tcx.hir.local_def_id(id); + tcx.sess.cstore.is_statically_included_foreign_item(def_id) + } + + // Only consider nodes that actually have exported symbols. + hir_map::NodeItem(&hir::Item { + node: hir::ItemStatic(..), .. }) | + hir_map::NodeItem(&hir::Item { + node: hir::ItemFn(..), .. }) | + hir_map::NodeImplItem(&hir::ImplItem { + node: hir::ImplItemKind::Method(..), .. }) => { + let def_id = tcx.hir.local_def_id(id); + let generics = tcx.generics_of(def_id); + let attributes = tcx.get_attrs(def_id); + (generics.parent_types == 0 && generics.types.is_empty()) && + // Functions marked with #[inline] are only ever translated + // with "internal" linkage and are never exported. + !attr::requests_inline(&attributes) + } + + _ => false + } + }).collect() +} diff --git a/src/librustc_trans_utils/link.rs b/src/librustc_trans_utils/link.rs index aa8637fabe85f..36c3ddc178beb 100644 --- a/src/librustc_trans_utils/link.rs +++ b/src/librustc_trans_utils/link.rs @@ -10,11 +10,23 @@ use rustc::session::config::{self, OutputFilenames, Input, OutputType}; use rustc::session::Session; -use rustc::middle::cstore; +use rustc::middle::cstore::{self, LinkMeta}; +use rustc::dep_graph::{DepKind, DepNode}; +use rustc::hir::svh::Svh; +use rustc_incremental::IncrementalHashesMap; use std::path::PathBuf; use syntax::ast; use syntax_pos::Span; +pub fn build_link_meta(incremental_hashes_map: &IncrementalHashesMap) -> LinkMeta { + let krate_dep_node = &DepNode::new_no_params(DepKind::Krate); + let r = LinkMeta { + crate_hash: Svh::new(incremental_hashes_map[krate_dep_node].to_smaller_hash()), + }; + info!("{:?}", r); + return r; +} + pub fn find_crate_name(sess: Option<&Session>, attrs: &[ast::Attribute], input: &Input) -> String { From d44a256157f1773f146465107de1f211401ebf93 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 26 Aug 2017 17:31:32 +0200 Subject: [PATCH 02/17] Allow building stage 2 compiler libraries --- src/bootstrap/bin/rustc.rs | 4 +++ src/bootstrap/builder.rs | 2 +- src/bootstrap/compile.rs | 7 +----- src/librustc_driver/driver.rs | 37 +++++++++++++++++++++------- src/librustc_metadata/locator.rs | 18 +++++++++++++- src/librustc_trans/back/link.rs | 42 +++----------------------------- src/librustc_trans/base.rs | 2 +- src/librustc_trans/lib.rs | 1 + src/librustc_trans_utils/link.rs | 35 +++++++++++++++++++++++++- 9 files changed, 90 insertions(+), 58 deletions(-) diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index 848b10d312cea..df9c55ce0be36 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -159,6 +159,10 @@ fn main() { cmd.arg("-C").arg("panic=abort"); } + if cfg!(not(feature="llvm")) && stage != "0" { + cmd.arg("-Zno-trans"); + } + // Set various options from config.toml to configure how we're building // code. if env::var("RUSTC_DEBUGINFO") == Ok("true".to_string()) { diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 8a6c998c932c2..de6dd10938e6d 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -531,7 +531,7 @@ impl<'a> Builder<'a> { // For other crates, however, we know that we've already got a standard // library up and running, so we can use the normal compiler to compile // build scripts in that situation. - if mode == Mode::Libstd { + if mode == Mode::Libstd || !self.build.config.llvm_enabled { cargo.env("RUSTC_SNAPSHOT", &self.initial_rustc) .env("RUSTC_SNAPSHOT_LIBDIR", self.rustc_snapshot_libdir()); } else { diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 2e368ddf43f38..335e1690a2ea0 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -104,11 +104,7 @@ impl Step for Std { let out_dir = build.cargo_out(compiler, Mode::Libstd, target); build.clear_if_dirty(&out_dir, &builder.rustc(compiler)); - let mut cargo = if compiler.stage == 0 { - builder.cargo(compiler, Mode::Libstd, target, "build") - }else{ - builder.cargo(compiler, Mode::Libstd, target, "check") - }; + let mut cargo = builder.cargo(compiler, Mode::Libstd, target, "build"); std_cargo(build, &compiler, target, &mut cargo); run_cargo(build, &mut cargo, @@ -165,7 +161,6 @@ pub fn std_cargo(build: &Build, // missing // We also only build the runtimes when --enable-sanitizers (or its // config.toml equivalent) is used - //cargo.env("RUST_FLAGS", "-Zno-trans"); cargo.env("LLVM_CONFIG", build.llvm_config(target)); } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 1520fc7def839..1b1282eacc0e6 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -69,7 +69,7 @@ use derive_registrar; use profile; -pub fn compile_input(sess: &Session, +pub fn compile_input(sess: &mut Session, cstore: &CStore, input: &Input, outdir: &Option, @@ -100,17 +100,32 @@ pub fn compile_input(sess: &Session, sess.err("LLVM is not supported by this rustc. Please use -Z no-trans to compile") } - if sess.opts.crate_types.iter().all(|&t|{ - t != CrateType::CrateTypeRlib && t != CrateType::CrateTypeExecutable - }) && !sess.opts.crate_types.is_empty() { - sess.err( - "LLVM is not supported by this rustc, so non rlib libraries are not supported" - ); + for cty in sess.opts.crate_types.iter_mut() { + match *cty { + CrateType::CrateTypeRlib | CrateType::CrateTypeExecutable => {}, + CrateType::CrateTypeDylib | CrateType::CrateTypeCdylib | + CrateType::CrateTypeStaticlib => { + sess.parse_sess.span_diagnostic.warn( + &format!("LLVM unsupported, so non rlib output type {} \ + will be treated like rlib lib", cty) + ); + *cty = CrateType::CrateTypeRlib; + }, + CrateType::CrateTypeProcMacro => { + sess.parse_sess.span_diagnostic.err( + "No LLVM support, so cant compile proc macros" + ); + } + } } sess.abort_if_errors(); } + // Make sure nobody changes sess after crate types + // have optionally been adjusted for no llvm builds + let sess = &*sess; + if sess.profile_queries() { profile::begin(); } @@ -267,6 +282,10 @@ pub fn compile_input(sess: &Session, if cfg!(not(feature="llvm")) { let (_, _) = (outputs, trans); + + if sess.opts.crate_types.contains(&CrateType::CrateTypeRlib) { + return Ok(()) + } sess.fatal("LLVM is not supported by this rustc"); } @@ -300,9 +319,9 @@ pub fn compile_input(sess: &Session, CompileState::state_when_compilation_done(input, sess, outdir, output), Ok(()) ); - - Ok(()) } + + Ok(()) } fn keep_hygiene_data(sess: &Session) -> bool { diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs index 19f7cb0ee238a..c762844ab3515 100644 --- a/src/librustc_metadata/locator.rs +++ b/src/librustc_metadata/locator.rs @@ -457,6 +457,14 @@ impl<'a> Context<'a> { // // The goal of this step is to look at as little metadata as possible. self.filesearch.search(|path, kind| { + let mut path = path.to_owned(); + if cfg!(not(feature="llvm")) { + // This is a hack to make crates both defined as dylib + // and rlib to be findable without LLVM + path.set_extension("rlib"); + } + let path = &path; + let file = match path.file_name().and_then(|s| s.to_str()) { None => return FileDoesntMatch, Some(file) => file, @@ -745,7 +753,15 @@ impl<'a> Context<'a> { let mut rmetas = FxHashMap(); let mut dylibs = FxHashMap(); { - let locs = locs.map(|l| PathBuf::from(l)).filter(|loc| { + let locs = locs.map(|l| PathBuf::from(l)) + .map(|mut l| { + if cfg!(not(feature="llvm")) { + // This is a hack to make crates both defined as dylib + // and rlib to be findable without LLVM + l.set_extension("rlib"); + } + l + }).filter(|loc| { if !loc.exists() { sess.err(&format!("extern location for {} does not exist: {}", self.crate_name, diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index e6ab46fa93114..796e203bd0431 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -extern crate rustc_trans_utils; - use super::archive::{ArchiveBuilder, ArchiveConfig}; use super::linker::Linker; use super::command::Command; @@ -27,7 +25,6 @@ use {CrateTranslation, CrateInfo}; use rustc::util::common::time; use rustc::util::fs::fix_windows_verbatim_for_gcc; use rustc::hir::def_id::CrateNum; -use rustc::hir::svh::Svh; use rustc_back::tempdir::TempDir; use rustc_back::{PanicStrategy, RelroLevel}; use context::get_reloc_model; @@ -88,9 +85,9 @@ pub const RLIB_BYTECODE_OBJECT_V1_DATASIZE_OFFSET: usize = pub const RLIB_BYTECODE_OBJECT_V1_DATA_OFFSET: usize = RLIB_BYTECODE_OBJECT_V1_DATASIZE_OFFSET + 8; -pub use self::rustc_trans_utils::link::{find_crate_name, filename_for_input, - default_output_for_target, invalid_output_for_target, - build_link_meta}; +pub use rustc_trans_utils::link::{find_crate_name, filename_for_input, default_output_for_target, + invalid_output_for_target, build_link_meta, out_filename, + check_file_is_writeable}; // The third parameter is for env vars, used on windows to set up the // path for MSVC to find its DLLs, and gcc to find its bundled @@ -218,13 +215,6 @@ pub fn link_binary(sess: &Session, out_filenames } -fn is_writeable(p: &Path) -> bool { - match p.metadata() { - Err(..) => true, - Ok(m) => !m.permissions().readonly() - } -} - fn filename_for_metadata(sess: &Session, crate_name: &str, outputs: &OutputFilenames) -> PathBuf { let out_filename = outputs.single_output_file.clone() .unwrap_or(outputs @@ -288,32 +278,6 @@ pub fn ignored_for_lto(info: &CrateInfo, cnum: CrateNum) -> bool { info.is_no_builtins.contains(&cnum) || info.compiler_builtins == Some(cnum) } -fn out_filename(sess: &Session, - crate_type: config::CrateType, - outputs: &OutputFilenames, - crate_name: &str) - -> PathBuf { - let default_filename = filename_for_input(sess, crate_type, crate_name, outputs); - let out_filename = outputs.outputs.get(&OutputType::Exe) - .and_then(|s| s.to_owned()) - .or_else(|| outputs.single_output_file.clone()) - .unwrap_or(default_filename); - - check_file_is_writeable(&out_filename, sess); - - out_filename -} - -// Make sure files are writeable. Mac, FreeBSD, and Windows system linkers -// check this already -- however, the Linux linker will happily overwrite a -// read-only file. We should be consistent. -fn check_file_is_writeable(file: &Path, sess: &Session) { - if !is_writeable(file) { - sess.fatal(&format!("output file {} is not writeable -- check its \ - permissions", file.display())); - } -} - fn link_binary_output(sess: &Session, trans: &CrateTranslation, crate_type: config::CrateType, diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 91852630fa47a..7d69db12bd0ca 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -938,7 +938,7 @@ pub fn find_exported_symbols(tcx: TyCtxt) -> NodeSet { pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, rx: mpsc::Receiver>) -> OngoingCrateTranslation { - use back::link::rustc_trans_utils::find_exported_symbols; + use rustc_trans_utils::find_exported_symbols; check_for_rustc_errors_attr(tcx); diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 57e9f1d091b21..f45a011e94d8d 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -50,6 +50,7 @@ extern crate rustc_incremental; extern crate rustc_llvm as llvm; extern crate rustc_platform_intrinsics as intrinsics; extern crate rustc_const_math; +extern crate rustc_trans_utils; extern crate rustc_demangle; extern crate jobserver; extern crate num_cpus; diff --git a/src/librustc_trans_utils/link.rs b/src/librustc_trans_utils/link.rs index 36c3ddc178beb..ccd5739efe021 100644 --- a/src/librustc_trans_utils/link.rs +++ b/src/librustc_trans_utils/link.rs @@ -14,10 +14,43 @@ use rustc::middle::cstore::{self, LinkMeta}; use rustc::dep_graph::{DepKind, DepNode}; use rustc::hir::svh::Svh; use rustc_incremental::IncrementalHashesMap; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use syntax::ast; use syntax_pos::Span; +pub fn out_filename(sess: &Session, + crate_type: config::CrateType, + outputs: &OutputFilenames, + crate_name: &str) + -> PathBuf { + let default_filename = filename_for_input(sess, crate_type, crate_name, outputs); + let out_filename = outputs.outputs.get(&OutputType::Exe) + .and_then(|s| s.to_owned()) + .or_else(|| outputs.single_output_file.clone()) + .unwrap_or(default_filename); + + check_file_is_writeable(&out_filename, sess); + + out_filename +} + +// Make sure files are writeable. Mac, FreeBSD, and Windows system linkers +// check this already -- however, the Linux linker will happily overwrite a +// read-only file. We should be consistent. +pub fn check_file_is_writeable(file: &Path, sess: &Session) { + if !is_writeable(file) { + sess.fatal(&format!("output file {} is not writeable -- check its \ + permissions", file.display())); + } +} + +fn is_writeable(p: &Path) -> bool { + match p.metadata() { + Err(..) => true, + Ok(m) => !m.permissions().readonly() + } +} + pub fn build_link_meta(incremental_hashes_map: &IncrementalHashesMap) -> LinkMeta { let krate_dep_node = &DepNode::new_no_params(DepKind::Krate); let r = LinkMeta { From 2c03c57bf5ac9e106440ea474827be16092f1807 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 2 Sep 2017 12:27:28 +0200 Subject: [PATCH 03/17] Dont do no-trans for llvm enabled builds --- src/bootstrap/bin/rustc.rs | 2 +- src/bootstrap/builder.rs | 6 ++++++ src/librustc_driver/Cargo.toml | 2 +- src/librustc_metadata/Cargo.toml | 3 +++ 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index df9c55ce0be36..2768d9c7f04f1 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -159,7 +159,7 @@ fn main() { cmd.arg("-C").arg("panic=abort"); } - if cfg!(not(feature="llvm")) && stage != "0" { + if env::var("RUSTC_LLVM_ENABLED") == Ok("0".to_string()) && stage != "0" { cmd.arg("-Zno-trans"); } diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index de6dd10938e6d..99712d9fcab7f 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -539,6 +539,12 @@ impl<'a> Builder<'a> { .env("RUSTC_SNAPSHOT_LIBDIR", self.rustc_libdir(compiler)); } + if self.build.config.llvm_enabled { + cargo.env("RUSTC_LLVM_ENABLED", "1"); + } else { + cargo.env("RUSTC_LLVM_ENABLED", "0"); + } + // Ignore incremental modes except for stage0, since we're // not guaranteeing correctness across builds if the compiler // is changing under your feet.` diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml index d6155f53485e3..dabe15b6a6e64 100644 --- a/src/librustc_driver/Cargo.toml +++ b/src/librustc_driver/Cargo.toml @@ -41,4 +41,4 @@ syntax_pos = { path = "../libsyntax_pos" } ar = "0.3.0" [features] -llvm = ["rustc_trans"] +llvm = ["rustc_trans", "rustc_metadata/llvm"] diff --git a/src/librustc_metadata/Cargo.toml b/src/librustc_metadata/Cargo.toml index 40b75be36fefb..2c17797ed5dd8 100644 --- a/src/librustc_metadata/Cargo.toml +++ b/src/librustc_metadata/Cargo.toml @@ -21,3 +21,6 @@ serialize = { path = "../libserialize" } syntax = { path = "../libsyntax" } syntax_ext = { path = "../libsyntax_ext" } syntax_pos = { path = "../libsyntax_pos" } + +[features] +llvm = [] From d935a8d6af6201546c0e699b9374dff31cb5af3e Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 10 Sep 2017 14:17:54 +0200 Subject: [PATCH 04/17] Fix rustc_trans_utils::find_exported_symbols Fix denied warnings --- src/librustc_trans/back/link.rs | 3 +- src/librustc_trans/base.rs | 51 --------------------------------- src/librustc_trans_utils/lib.rs | 2 +- 3 files changed, 2 insertions(+), 54 deletions(-) diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 796e203bd0431..1630e7759919c 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -18,8 +18,7 @@ use rustc::session::config::{self, NoDebugInfo, OutputFilenames, OutputType, Pri use rustc::session::filesearch; use rustc::session::search_paths::PathKind; use rustc::session::Session; -use rustc::ich::Fingerprint; -use rustc::middle::cstore::{LinkMeta, NativeLibrary, LibSource, NativeLibraryKind}; +use rustc::middle::cstore::{NativeLibrary, LibSource, NativeLibraryKind}; use rustc::middle::dependency_format::Linkage; use {CrateTranslation, CrateInfo}; use rustc::util::common::time; diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 7d69db12bd0ca..154e54f92a83f 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -43,7 +43,6 @@ use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::maps::Providers; use rustc::dep_graph::{DepNode, DepKind}; use rustc::middle::cstore::{self, LinkMeta, LinkagePreference}; -use rustc::hir::map as hir_map; use rustc::util::common::{time, print_time_passes_entry}; use rustc::session::config::{self, NoDebugInfo}; use rustc::session::Session; @@ -885,56 +884,6 @@ fn iter_globals(llmod: llvm::ModuleRef) -> ValueIter { } } -/// The context provided lists a set of reachable ids as calculated by -/// middle::reachable, but this contains far more ids and symbols than we're -/// actually exposing from the object file. This function will filter the set in -/// the context to the set of ids which correspond to symbols that are exposed -/// from the object file being generated. -/// -/// This list is later used by linkers to determine the set of symbols needed to -/// be exposed from a dynamic library and it's also encoded into the metadata. -pub fn find_exported_symbols(tcx: TyCtxt) -> NodeSet { - tcx.reachable_set(LOCAL_CRATE).0.iter().cloned().filter(|&id| { - // Next, we want to ignore some FFI functions that are not exposed from - // this crate. Reachable FFI functions can be lumped into two - // categories: - // - // 1. Those that are included statically via a static library - // 2. Those included otherwise (e.g. dynamically or via a framework) - // - // Although our LLVM module is not literally emitting code for the - // statically included symbols, it's an export of our library which - // needs to be passed on to the linker and encoded in the metadata. - // - // As a result, if this id is an FFI item (foreign item) then we only - // let it through if it's included statically. - match tcx.hir.get(id) { - hir_map::NodeForeignItem(..) => { - let def_id = tcx.hir.local_def_id(id); - tcx.is_statically_included_foreign_item(def_id) - } - - // Only consider nodes that actually have exported symbols. - hir_map::NodeItem(&hir::Item { - node: hir::ItemStatic(..), .. }) | - hir_map::NodeItem(&hir::Item { - node: hir::ItemFn(..), .. }) | - hir_map::NodeImplItem(&hir::ImplItem { - node: hir::ImplItemKind::Method(..), .. }) => { - let def_id = tcx.hir.local_def_id(id); - let generics = tcx.generics_of(def_id); - let attributes = tcx.get_attrs(def_id); - (generics.parent_types == 0 && generics.types.is_empty()) && - // Functions marked with #[inline] are only ever translated - // with "internal" linkage and are never exported. - !attr::requests_inline(&attributes) - } - - _ => false - } - }).collect() -} - pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, rx: mpsc::Receiver>) -> OngoingCrateTranslation { diff --git a/src/librustc_trans_utils/lib.rs b/src/librustc_trans_utils/lib.rs index 44f0f62d7082f..49251a9ecf543 100644 --- a/src/librustc_trans_utils/lib.rs +++ b/src/librustc_trans_utils/lib.rs @@ -71,7 +71,7 @@ pub fn find_exported_symbols(tcx: TyCtxt, reachable: &NodeSet) -> NodeSet { match tcx.hir.get(id) { hir_map::NodeForeignItem(..) => { let def_id = tcx.hir.local_def_id(id); - tcx.sess.cstore.is_statically_included_foreign_item(def_id) + tcx.is_statically_included_foreign_item(def_id) } // Only consider nodes that actually have exported symbols. From 89af6d5c8bafeb30971a2525d3973ef4f6124099 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 10 Sep 2017 17:56:48 +0200 Subject: [PATCH 05/17] [WIP] Less hacky way of supporting dylibs --- src/Cargo.lock | 1 + src/librustc_driver/Cargo.toml | 3 ++- src/librustc_driver/driver.rs | 26 ++++++++------------------ src/librustc_driver/lib.rs | 5 ++++- src/librustc_metadata/Cargo.toml | 3 --- src/librustc_metadata/locator.rs | 18 +----------------- 6 files changed, 16 insertions(+), 40 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index 9481032985477..a5ad7d6ff697e 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -1554,6 +1554,7 @@ dependencies = [ "ar 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "arena 0.0.0", "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "flate2 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", "graphviz 0.0.0", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml index dabe15b6a6e64..2aac1b085e95a 100644 --- a/src/librustc_driver/Cargo.toml +++ b/src/librustc_driver/Cargo.toml @@ -10,6 +10,7 @@ crate-type = ["dylib"] [dependencies] arena = { path = "../libarena" } +flate2 = "0.2" graphviz = { path = "../libgraphviz" } log = { version = "0.3", features = ["release_max_level_info"] } owning_ref = "0.3.3" @@ -41,4 +42,4 @@ syntax_pos = { path = "../libsyntax_pos" } ar = "0.3.0" [features] -llvm = ["rustc_trans", "rustc_metadata/llvm"] +llvm = ["rustc_trans"] diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 1b1282eacc0e6..457c9357336b3 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -69,7 +69,7 @@ use derive_registrar; use profile; -pub fn compile_input(sess: &mut Session, +pub fn compile_input(sess: &Session, cstore: &CStore, input: &Input, outdir: &Option, @@ -100,32 +100,21 @@ pub fn compile_input(sess: &mut Session, sess.err("LLVM is not supported by this rustc. Please use -Z no-trans to compile") } - for cty in sess.opts.crate_types.iter_mut() { + for cty in sess.opts.crate_types.iter() { match *cty { - CrateType::CrateTypeRlib | CrateType::CrateTypeExecutable => {}, - CrateType::CrateTypeDylib | CrateType::CrateTypeCdylib | - CrateType::CrateTypeStaticlib => { + CrateType::CrateTypeRlib | CrateType::CrateTypeDylib | + CrateType::CrateTypeExecutable => {}, + _ => { sess.parse_sess.span_diagnostic.warn( - &format!("LLVM unsupported, so non rlib output type {} \ - will be treated like rlib lib", cty) + &format!("LLVM unsupported, so output type {} is not supported", cty) ); - *cty = CrateType::CrateTypeRlib; }, - CrateType::CrateTypeProcMacro => { - sess.parse_sess.span_diagnostic.err( - "No LLVM support, so cant compile proc macros" - ); - } } } sess.abort_if_errors(); } - // Make sure nobody changes sess after crate types - // have optionally been adjusted for no llvm builds - let sess = &*sess; - if sess.profile_queries() { profile::begin(); } @@ -283,7 +272,8 @@ pub fn compile_input(sess: &mut Session, if cfg!(not(feature="llvm")) { let (_, _) = (outputs, trans); - if sess.opts.crate_types.contains(&CrateType::CrateTypeRlib) { + if sess.opts.crate_types.contains(&CrateType::CrateTypeRlib) + || sess.opts.crate_types.contains(&CrateType::CrateTypeDylib) { return Ok(()) } sess.fatal("LLVM is not supported by this rustc"); diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 2e0193fc8a1ea..7af5ad3410fce 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -27,6 +27,8 @@ #[cfg(not(feature="llvm"))] extern crate ar; +#[cfg(not(feature="llvm"))] +extern crate flate2; extern crate arena; extern crate getopts; extern crate graphviz; @@ -202,7 +204,8 @@ mod no_llvm_metadata_loader { _target: &Target, _filename: &Path) -> Result, String> { - panic!("Dylib metadata loading not supported without LLVM") + // FIXME: Support reading dylibs from llvm enabled rustc + self.get_rlib_metadata(_target, _filename) } } } diff --git a/src/librustc_metadata/Cargo.toml b/src/librustc_metadata/Cargo.toml index 2c17797ed5dd8..40b75be36fefb 100644 --- a/src/librustc_metadata/Cargo.toml +++ b/src/librustc_metadata/Cargo.toml @@ -21,6 +21,3 @@ serialize = { path = "../libserialize" } syntax = { path = "../libsyntax" } syntax_ext = { path = "../libsyntax_ext" } syntax_pos = { path = "../libsyntax_pos" } - -[features] -llvm = [] diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs index c762844ab3515..19f7cb0ee238a 100644 --- a/src/librustc_metadata/locator.rs +++ b/src/librustc_metadata/locator.rs @@ -457,14 +457,6 @@ impl<'a> Context<'a> { // // The goal of this step is to look at as little metadata as possible. self.filesearch.search(|path, kind| { - let mut path = path.to_owned(); - if cfg!(not(feature="llvm")) { - // This is a hack to make crates both defined as dylib - // and rlib to be findable without LLVM - path.set_extension("rlib"); - } - let path = &path; - let file = match path.file_name().and_then(|s| s.to_str()) { None => return FileDoesntMatch, Some(file) => file, @@ -753,15 +745,7 @@ impl<'a> Context<'a> { let mut rmetas = FxHashMap(); let mut dylibs = FxHashMap(); { - let locs = locs.map(|l| PathBuf::from(l)) - .map(|mut l| { - if cfg!(not(feature="llvm")) { - // This is a hack to make crates both defined as dylib - // and rlib to be findable without LLVM - l.set_extension("rlib"); - } - l - }).filter(|loc| { + let locs = locs.map(|l| PathBuf::from(l)).filter(|loc| { if !loc.exists() { sess.err(&format!("extern location for {} does not exist: {}", self.crate_name, From 44c184382fda86692d61e4042d5ccecc83c43e90 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 16 Sep 2017 17:27:29 +0200 Subject: [PATCH 06/17] Add TransCrate trait --- src/Cargo.lock | 12 +++ src/librustc_driver/Cargo.toml | 1 + src/librustc_driver/driver.rs | 43 ++++---- src/librustc_driver/lib.rs | 140 ++++++++++++++++++++++----- src/librustc_driver/test.rs | 2 +- src/librustc_trans/Cargo.toml | 1 + src/librustc_trans/lib.rs | 55 +++++++++++ src/librustc_trans_traits/Cargo.toml | 17 ++++ src/librustc_trans_traits/lib.rs | 116 ++++++++++++++++++++++ 9 files changed, 337 insertions(+), 50 deletions(-) create mode 100644 src/librustc_trans_traits/Cargo.toml create mode 100644 src/librustc_trans_traits/lib.rs diff --git a/src/Cargo.lock b/src/Cargo.lock index a5ad7d6ff697e..693bf5b2619ff 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -1575,6 +1575,7 @@ dependencies = [ "rustc_resolve 0.0.0", "rustc_save_analysis 0.0.0", "rustc_trans 0.0.0", + "rustc_trans_traits 0.0.0", "rustc_trans_utils 0.0.0", "rustc_typeck 0.0.0", "serialize 0.0.0", @@ -1769,12 +1770,23 @@ dependencies = [ "rustc_incremental 0.0.0", "rustc_llvm 0.0.0", "rustc_platform_intrinsics 0.0.0", + "rustc_trans_traits 0.0.0", "rustc_trans_utils 0.0.0", "serialize 0.0.0", "syntax 0.0.0", "syntax_pos 0.0.0", ] +[[package]] +name = "rustc_trans_traits" +version = "0.0.0" +dependencies = [ + "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc 0.0.0", + "rustc_back 0.0.0", + "rustc_incremental 0.0.0", +] + [[package]] name = "rustc_trans_utils" version = "0.0.0" diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml index 2aac1b085e95a..6399f3ad2687e 100644 --- a/src/librustc_driver/Cargo.toml +++ b/src/librustc_driver/Cargo.toml @@ -33,6 +33,7 @@ rustc_resolve = { path = "../librustc_resolve" } rustc_save_analysis = { path = "../librustc_save_analysis" } rustc_trans = { path = "../librustc_trans", optional = true } rustc_trans_utils = { path = "../librustc_trans_utils" } +rustc_trans_traits = { path = "../librustc_trans_traits" } rustc_typeck = { path = "../librustc_typeck" } serialize = { path = "../libserialize" } syntax = { path = "../libsyntax" } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 457c9357336b3..9aab169023c95 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -34,8 +34,8 @@ use rustc_incremental; use rustc_resolve::{MakeGlobMap, Resolver}; use rustc_metadata::creader::CrateLoader; use rustc_metadata::cstore::{self, CStore}; -use rustc_trans::back::write; use rustc_trans as trans; +use rustc_trans_traits::TransCrate; use rustc_typeck as typeck; use rustc_privacy; use rustc_plugin::registry::Registry; @@ -43,6 +43,7 @@ use rustc_plugin as plugin; use rustc_passes::{ast_validation, no_asm, loops, consts, static_recursion, hir_stats}; use rustc_const_eval::{self, check_match}; use super::Compilation; +use ::DefaultTransCrate; use serialize::json; @@ -76,7 +77,6 @@ pub fn compile_input(sess: &Session, output: &Option, addl_plugins: Option>, control: &CompileController) -> CompileResult { - use rustc_trans::back::write::OngoingCrateTranslation; use rustc::session::config::CrateType; macro_rules! controller_entry_point { @@ -122,7 +122,7 @@ pub fn compile_input(sess: &Session, // We need nested scopes here, because the intermediate results can keep // large chunks of memory alive and we want to free them as soon as // possible to keep the peak memory usage low - let (outputs, trans, dep_graph): (OutputFilenames, OngoingCrateTranslation, DepGraph) = { + let (outputs, trans, dep_graph) = { let krate = match phase_1_parse_input(control, sess, input) { Ok(krate) => krate, Err(mut parse_error) => { @@ -251,7 +251,7 @@ pub fn compile_input(sess: &Session, tcx.print_debug_stats(); } - let trans = phase_4_translate_to_llvm(tcx, rx); + let trans = phase_4_translate_to_llvm::(tcx, rx); if log_enabled!(::log::LogLevel::Info) { println!("Post-trans"); @@ -285,7 +285,7 @@ pub fn compile_input(sess: &Session, sess.code_stats.borrow().print_type_sizes(); } - let (phase5_result, trans) = phase_5_run_llvm_passes(sess, &dep_graph, trans); + let (phase5_result, trans) = phase_5_run_llvm_passes::(sess, &dep_graph, trans); controller_entry_point!(after_llvm, sess, @@ -293,7 +293,7 @@ pub fn compile_input(sess: &Session, phase5_result); phase5_result?; - phase_6_link_output(sess, &trans, &outputs); + phase_6_link_output::(sess, &trans, &outputs); // Now that we won't touch anything in the incremental compilation directory // any more, we can finalize it (which involves renaming it) @@ -972,7 +972,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, mir::provide(&mut local_providers); reachable::provide(&mut local_providers); rustc_privacy::provide(&mut local_providers); - trans::provide_local(&mut local_providers); + DefaultTransCrate::provide_local(&mut local_providers); typeck::provide(&mut local_providers); ty::provide(&mut local_providers); traits::provide(&mut local_providers); @@ -984,7 +984,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, let mut extern_providers = ty::maps::Providers::default(); cstore::provide(&mut extern_providers); - trans::provide_extern(&mut extern_providers); + DefaultTransCrate::provide_extern(&mut extern_providers); ty::provide_extern(&mut extern_providers); traits::provide_extern(&mut extern_providers); // FIXME(eddyb) get rid of this once we replace const_eval with miri. @@ -1130,9 +1130,9 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, /// Run the translation phase to LLVM, after which the AST and analysis can /// be discarded. -pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, +pub fn phase_4_translate_to_llvm<'a, 'tcx, T: TransCrate>(tcx: TyCtxt<'a, 'tcx, 'tcx>, rx: mpsc::Receiver>) - -> write::OngoingCrateTranslation { + -> ::OngoingCrateTranslation { let time_passes = tcx.sess.time_passes(); time(time_passes, @@ -1141,9 +1141,8 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let translation = time(time_passes, "translation", move || { - trans::trans_crate(tcx, rx) + T::trans_crate(tcx, rx) }); - if tcx.sess.profile_queries() { profile::dump("profile_queries".to_string()) } @@ -1153,15 +1152,14 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, /// Run LLVM itself, producing a bitcode file, assembly file or object file /// as a side effect. -#[cfg(feature="llvm")] -pub fn phase_5_run_llvm_passes(sess: &Session, +pub fn phase_5_run_llvm_passes(sess: &Session, dep_graph: &DepGraph, - trans: write::OngoingCrateTranslation) - -> (CompileResult, trans::CrateTranslation) { - let trans = trans.join(sess, dep_graph); + trans: ::OngoingCrateTranslation) + -> (CompileResult, ::TranslatedCrate) { + let trans = T::join_trans(trans, sess, dep_graph); if sess.opts.debugging_opts.incremental_info { - write::dump_incremental_data(&trans); + T::dump_incremental_data(&trans); } time(sess.time_passes(), @@ -1174,14 +1172,11 @@ pub fn phase_5_run_llvm_passes(sess: &Session, /// Run the linker on any artifacts that resulted from the LLVM run. /// This should produce either a finished executable or library. #[cfg(feature="llvm")] -pub fn phase_6_link_output(sess: &Session, - trans: &trans::CrateTranslation, +pub fn phase_6_link_output(sess: &Session, + trans: &::TranslatedCrate, outputs: &OutputFilenames) { time(sess.time_passes(), "linking", || { - ::rustc_trans::back::link::link_binary(sess, - trans, - outputs, - &trans.crate_name.as_str()) + T::link_binary(sess, trans, outputs) }); } diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 7af5ad3410fce..fda738db85fd8 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -25,9 +25,7 @@ #![feature(rustc_diagnostic_macros)] #![feature(set_stdio)] -#[cfg(not(feature="llvm"))] extern crate ar; -#[cfg(not(feature="llvm"))] extern crate flate2; extern crate arena; extern crate getopts; @@ -54,6 +52,7 @@ extern crate rustc_save_analysis; #[cfg(feature="llvm")] extern crate rustc_trans; extern crate rustc_trans_utils; +extern crate rustc_trans_traits; extern crate rustc_typeck; extern crate serialize; #[macro_use] @@ -79,6 +78,7 @@ use rustc::middle::cstore::CrateStore; use rustc_metadata::locator; use rustc_metadata::cstore::CStore; use rustc::util::common::{time, ErrorReported}; +use rustc_trans_traits::TransCrate; use serialize::json::ToJson; @@ -155,11 +155,10 @@ pub fn run(run_compiler: F) -> isize } #[cfg(not(feature="llvm"))] -pub use no_llvm_metadata_loader::NoLLvmMetadataLoader as MetadataLoader; +pub use trans_metadata_only::MetadataOnlyTransCrate as DefaultTransCrate; #[cfg(feature="llvm")] -pub use rustc_trans::LlvmMetadataLoader as MetadataLoader; +pub use rustc_trans::LlvmTransCrate as DefaultTransCrate; -#[cfg(not(feature="llvm"))] mod no_llvm_metadata_loader { extern crate owning_ref; @@ -172,9 +171,9 @@ mod no_llvm_metadata_loader { use ar::Archive; use self::owning_ref::{OwningRef, ErasedBoxRef}; - pub struct NoLLvmMetadataLoader; + pub struct NoLlvmMetadataLoader; - impl MetadataLoaderTrait for NoLLvmMetadataLoader { + impl MetadataLoaderTrait for NoLlvmMetadataLoader { fn get_rlib_metadata( &self, _: &Target, @@ -210,40 +209,131 @@ mod no_llvm_metadata_loader { } } -#[cfg(not(feature="llvm"))] -mod rustc_trans { - use syntax_pos::symbol::Symbol; +mod trans_metadata_only { + use std::io::prelude::*; + use std::io::Cursor; + use std::fs::File; + + use ar::{Builder, Header}; + use flate2::Compression; + use flate2::write::DeflateEncoder; + + use syntax::symbol::Symbol; + use rustc::hir::def_id::LOCAL_CRATE; use rustc::session::Session; - use rustc::session::config::{PrintRequest, OutputFilenames}; + use rustc::session::config::{OutputFilenames, CrateType}; use rustc::ty::{TyCtxt, CrateAnalysis}; use rustc::ty::maps::Providers; + use rustc::middle::cstore::{MetadataLoader, EncodedMetadata}; + use rustc::dep_graph::DepGraph; use rustc_incremental::IncrementalHashesMap; + use rustc_trans_utils::find_exported_symbols; + use rustc_trans_utils::link::{out_filename, build_link_meta}; + use rustc_trans_traits::TransCrate; + + #[allow(dead_code)] + pub struct MetadataOnlyTransCrate; + pub struct OngoingCrateTranslation { + metadata: EncodedMetadata, + metadata_version: Vec, + crate_name: Symbol, + } + pub struct TranslatedCrate(OngoingCrateTranslation); + + impl MetadataOnlyTransCrate { + #[allow(dead_code)] + pub fn new(/*_sess: &Session*/) -> Self { + MetadataOnlyTransCrate + } + } + + impl TransCrate for MetadataOnlyTransCrate { + type MetadataLoader = ::no_llvm_metadata_loader::NoLlvmMetadataLoader; + type OngoingCrateTranslation = OngoingCrateTranslation; + type TranslatedCrate = TranslatedCrate; + + fn metadata_loader() -> Box { + box ::no_llvm_metadata_loader::NoLlvmMetadataLoader + } + + fn provide(_providers: &mut Providers) {} + + fn trans_crate<'a, 'tcx>( + tcx: TyCtxt<'a, 'tcx, 'tcx>, + analysis: CrateAnalysis, + incr_hashes_map: IncrementalHashesMap, + _output_filenames: &OutputFilenames + ) -> Self::OngoingCrateTranslation { + let link_meta = build_link_meta(&incr_hashes_map); + let exported_symbols = find_exported_symbols(tcx, &analysis.reachable); + let (metadata, _hashes) = tcx.encode_metadata(&link_meta, &exported_symbols); + + OngoingCrateTranslation { + metadata: metadata, + metadata_version: tcx.metadata_encoding_version().to_vec(), + crate_name: tcx.crate_name(LOCAL_CRATE), + } + } - use self::back::write::OngoingCrateTranslation; + fn join_trans( + trans: Self::OngoingCrateTranslation, + _sess: &Session, + _dep_graph: &DepGraph, + ) -> Self::TranslatedCrate { + TranslatedCrate(trans) + } + + fn link_binary(sess: &Session, + trans: &Self::TranslatedCrate, + outputs: &OutputFilenames) { + for &crate_type in sess.opts.crate_types.iter() { + if crate_type != CrateType::CrateTypeRlib && + crate_type != CrateType::CrateTypeDylib { + continue; + } + let output_name = + out_filename(sess, crate_type, &outputs, &trans.0.crate_name.as_str()); + let mut compressed = trans.0.metadata_version.clone(); + let metadata = if crate_type == CrateType::CrateTypeDylib { + DeflateEncoder::new(&mut compressed, Compression::Fast) + .write_all(&trans.0.metadata.raw_data).unwrap(); + &compressed + } else { + &trans.0.metadata.raw_data + }; + let mut builder = Builder::new(File::create(&output_name).unwrap()); + let header = Header::new( + "rust.metadata.bin".to_string(), + metadata.len() as u64 + ); + builder + .append(&header, Cursor::new(metadata)) + .unwrap(); + } + } + + fn dump_incremental_data(_trans: &Self::TranslatedCrate) {} + } +} + +#[cfg(not(feature="llvm"))] +mod rustc_trans { + use syntax_pos::symbol::Symbol; + use rustc::session::Session; + use rustc::session::config::PrintRequest; + pub use trans_metadata_only::MetadataOnlyTransCrate as LlvmTransCrate; pub fn init(_sess: &Session) {} pub fn enable_llvm_debug() {} - pub fn provide(_providers: &mut Providers) {} pub fn print_version() {} pub fn print_passes() {} pub fn print(_req: PrintRequest, _sess: &Session) {} pub fn target_features(_sess: &Session) -> Vec { vec![] } - pub fn trans_crate<'a, 'tcx>( - _tcx: TyCtxt<'a, 'tcx, 'tcx>, - _analysis: CrateAnalysis, - _incr_hashes_map: IncrementalHashesMap, - _output_filenames: &OutputFilenames - ) -> OngoingCrateTranslation { - OngoingCrateTranslation(()) - } - pub struct CrateTranslation(()); pub mod back { pub mod write { - pub struct OngoingCrateTranslation(pub (in ::rustc_trans) ()); - pub const RELOC_MODEL_ARGS: [(&'static str, ()); 0] = []; pub const CODE_GEN_MODEL_ARGS: [(&'static str, ()); 0] = []; } @@ -297,7 +387,7 @@ pub fn run_compiler<'a>(args: &[String], }, }; - let cstore = Rc::new(CStore::new(box ::MetadataLoader)); + let cstore = Rc::new(CStore::new(DefaultTransCrate::metadata_loader())); let loader = file_loader.unwrap_or(box RealFileLoader); let codemap = Rc::new(CodeMap::with_file_loader(loader, sopts.file_path_mapping())); diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index fad24e6a0f2b6..cadd63f31f5b4 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -105,7 +105,7 @@ fn test_env(source_string: &str, options.unstable_features = UnstableFeatures::Allow; let diagnostic_handler = errors::Handler::with_emitter(true, false, emitter); - let cstore = Rc::new(CStore::new(box ::MetadataLoader)); + let cstore = Rc::new(CStore::new(DefaultTransCrate::metadata_loader())); let sess = session::build_session_(options, None, diagnostic_handler, diff --git a/src/librustc_trans/Cargo.toml b/src/librustc_trans/Cargo.toml index 6f1f5b4a123d8..479d12b7440d2 100644 --- a/src/librustc_trans/Cargo.toml +++ b/src/librustc_trans/Cargo.toml @@ -27,6 +27,7 @@ rustc_incremental = { path = "../librustc_incremental" } rustc_llvm = { path = "../librustc_llvm" } rustc_platform_intrinsics = { path = "../librustc_platform_intrinsics" } rustc_trans_utils = { path = "../librustc_trans_utils" } +rustc_trans_traits = { path = "../librustc_trans_traits" } serialize = { path = "../libserialize" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index f45a011e94d8d..9023f5c3e6169 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -50,6 +50,7 @@ extern crate rustc_incremental; extern crate rustc_llvm as llvm; extern crate rustc_platform_intrinsics as intrinsics; extern crate rustc_const_math; +extern crate rustc_trans_traits; extern crate rustc_trans_utils; extern crate rustc_demangle; extern crate jobserver; @@ -138,6 +139,60 @@ mod type_; mod type_of; mod value; +use rustc::ty::{self, TyCtxt, CrateAnalysis}; +use rustc::session::Session; +use rustc::session::config::OutputFilenames; +use rustc::middle::cstore::MetadataLoader; +use rustc::dep_graph::DepGraph; +use rustc_incremental::IncrementalHashesMap; + +pub struct LlvmTransCrate(()); + +impl LlvmTransCrate { + pub fn new() -> Self { + LlvmTransCrate(()) + } +} + +impl rustc_trans_traits::TransCrate for LlvmTransCrate { + type MetadataLoader = metadata::LlvmMetadataLoader; + type OngoingCrateTranslation = back::write::OngoingCrateTranslation; + type TranslatedCrate = CrateTranslation; + + fn metadata_loader() -> Box { + box metadata::LlvmMetadataLoader + } + + fn provide(providers: &mut ty::maps::Providers) { + back::symbol_names::provide(providers); + } + + fn trans_crate<'a, 'tcx>( + tcx: TyCtxt<'a, 'tcx, 'tcx>, + analysis: CrateAnalysis, + incr_hashes_map: IncrementalHashesMap, + output_filenames: &OutputFilenames + ) -> Self::OngoingCrateTranslation { + base::trans_crate(tcx, analysis, incr_hashes_map, output_filenames) + } + + fn join_trans( + trans: Self::OngoingCrateTranslation, + sess: &Session, + dep_graph: &DepGraph + ) -> Self::TranslatedCrate { + trans.join(sess, dep_graph) + } + + fn link_binary(sess: &Session, trans: &Self::TranslatedCrate, outputs: &OutputFilenames) { + back::link::link_binary(sess, trans, outputs, &trans.crate_name.as_str()); + } + + fn dump_incremental_data(trans: &Self::TranslatedCrate) { + back::write::dump_incremental_data(trans); + } +} + pub struct ModuleTranslation { /// The name of the module. When the crate may be saved between /// compilations, incremental compilation requires that name be diff --git a/src/librustc_trans_traits/Cargo.toml b/src/librustc_trans_traits/Cargo.toml new file mode 100644 index 0000000000000..418de173fd14a --- /dev/null +++ b/src/librustc_trans_traits/Cargo.toml @@ -0,0 +1,17 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_trans_traits" +version = "0.0.0" + +[lib] +name = "rustc_trans_traits" +path = "lib.rs" +crate-type = ["dylib"] +test = false + +[dependencies] +owning_ref = "0.3.3" + +rustc = { path = "../librustc" } +rustc_back = { path = "../librustc_back" } +rustc_incremental = { path = "../librustc_incremental" } diff --git a/src/librustc_trans_traits/lib.rs b/src/librustc_trans_traits/lib.rs new file mode 100644 index 0000000000000..340d54c1029fc --- /dev/null +++ b/src/librustc_trans_traits/lib.rs @@ -0,0 +1,116 @@ +// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! The Rust compiler. +//! +//! # Note +//! +//! This API is completely unstable and subject to change. + +#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", + html_root_url = "https://doc.rust-lang.org/nightly/")] +#![deny(warnings)] + +#![feature(box_syntax)] + +extern crate owning_ref; + +#[macro_use] +extern crate rustc; +extern crate rustc_back; +extern crate rustc_incremental; + +use std::path::Path; +use owning_ref::ErasedBoxRef; + +use rustc::session::Session; +use rustc::session::config::OutputFilenames; +use rustc::ty::{TyCtxt, CrateAnalysis}; +use rustc::ty::maps::Providers; +use rustc::middle::cstore::MetadataLoader as MetadataLoaderTrait; +use rustc::dep_graph::DepGraph; +use rustc_back::target::Target; +use rustc_incremental::IncrementalHashesMap; + +pub trait TransCrate { + type MetadataLoader: MetadataLoaderTrait; + type OngoingCrateTranslation; + type TranslatedCrate; + + fn metadata_loader() -> Box; + fn provide(_providers: &mut Providers); + fn trans_crate<'a, 'tcx>( + tcx: TyCtxt<'a, 'tcx, 'tcx>, + analysis: CrateAnalysis, + incr_hashes_map: IncrementalHashesMap, + output_filenames: &OutputFilenames + ) -> Self::OngoingCrateTranslation; + fn join_trans( + trans: Self::OngoingCrateTranslation, + sess: &Session, + dep_graph: &DepGraph + ) -> Self::TranslatedCrate; + fn link_binary(sess: &Session, trans: &Self::TranslatedCrate, outputs: &OutputFilenames); + fn dump_incremental_data(trans: &Self::TranslatedCrate); +} + +pub struct DummyTransCrate; + +impl TransCrate for DummyTransCrate { + type MetadataLoader = DummyMetadataLoader; + type OngoingCrateTranslation = (); + type TranslatedCrate = (); + + fn metadata_loader() -> Box { + box DummyMetadataLoader(()) + } + + fn provide(_providers: &mut Providers) { + bug!("DummyTransCrate::provide"); + } + + fn trans_crate<'a, 'tcx>( + _tcx: TyCtxt<'a, 'tcx, 'tcx>, + _analysis: CrateAnalysis, + _incr_hashes_map: IncrementalHashesMap, + _output_filenames: &OutputFilenames + ) -> Self::OngoingCrateTranslation { + bug!("DummyTransCrate::trans_crate"); + } + + fn join_trans( + _trans: Self::OngoingCrateTranslation, + _sess: &Session, + _dep_graph: &DepGraph + ) -> Self::TranslatedCrate { + bug!("DummyTransCrate::join_trans"); + } + + fn link_binary(_sess: &Session, _trans: &Self::TranslatedCrate, _outputs: &OutputFilenames) { + bug!("DummyTransCrate::link_binary"); + } + + fn dump_incremental_data(_trans: &Self::TranslatedCrate) { + bug!("DummyTransCrate::dump_incremental_data"); + } +} + +pub struct DummyMetadataLoader(()); + +impl MetadataLoaderTrait for DummyMetadataLoader { + fn get_rlib_metadata(&self, _target: &Target, _filename: &Path) -> Result, String> { + bug!("DummyMetadataLoader::get_rlib_metadata"); + } + + fn get_dylib_metadata(&self, _target: &Target, _filename: &Path) -> Result, String> { + bug!("DummyMetadataLoader::get_dylib_metadata"); + } +} From 9eeaba18bd31e63c5ae576ea6c7b88cfd50fcb60 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 18 Sep 2017 17:37:57 +0200 Subject: [PATCH 07/17] Move NoLlvmMetadataLoader to rustc_trans_traits --- src/Cargo.lock | 4 + src/bootstrap/bin/rustc.rs | 4 - src/bootstrap/builder.rs | 3 + src/librustc_driver/driver.rs | 63 ++++------ src/librustc_driver/lib.rs | 166 +-------------------------- src/librustc_trans_traits/Cargo.toml | 4 + src/librustc_trans_traits/lib.rs | 136 +++++++++++++++++++++- 7 files changed, 169 insertions(+), 211 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index 693bf5b2619ff..49db077849c20 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -1781,10 +1781,14 @@ dependencies = [ name = "rustc_trans_traits" version = "0.0.0" dependencies = [ + "ar 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "flate2 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", "rustc_back 0.0.0", "rustc_incremental 0.0.0", + "rustc_trans_utils 0.0.0", + "syntax 0.0.0", ] [[package]] diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index 2768d9c7f04f1..848b10d312cea 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -159,10 +159,6 @@ fn main() { cmd.arg("-C").arg("panic=abort"); } - if env::var("RUSTC_LLVM_ENABLED") == Ok("0".to_string()) && stage != "0" { - cmd.arg("-Zno-trans"); - } - // Set various options from config.toml to configure how we're building // code. if env::var("RUSTC_DEBUGINFO") == Ok("true".to_string()) { diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 99712d9fcab7f..8307a536c339d 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -531,6 +531,9 @@ impl<'a> Builder<'a> { // For other crates, however, we know that we've already got a standard // library up and running, so we can use the normal compiler to compile // build scripts in that situation. + // + // If LLVM support is disabled we need to use the snapshot compiler to compile + // build scripts, as the new compiler doesnt support executables. if mode == Mode::Libstd || !self.build.config.llvm_enabled { cargo.env("RUSTC_SNAPSHOT", &self.initial_rustc) .env("RUSTC_SNAPSHOT_LIBDIR", self.rustc_snapshot_libdir()); diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 9aab169023c95..aa0000653cc87 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![cfg_attr(not(feature="llvm"), allow(dead_code))] - use rustc::dep_graph::DepGraph; use rustc::hir::{self, map as hir_map}; use rustc::hir::lowering::lower_crate; @@ -96,10 +94,6 @@ pub fn compile_input(sess: &Session, } if cfg!(not(feature="llvm")) { - if !sess.opts.debugging_opts.no_trans && sess.opts.output_types.should_trans() { - sess.err("LLVM is not supported by this rustc. Please use -Z no-trans to compile") - } - for cty in sess.opts.crate_types.iter() { match *cty { CrateType::CrateTypeRlib | CrateType::CrateTypeDylib | @@ -269,48 +263,36 @@ pub fn compile_input(sess: &Session, })?? }; - if cfg!(not(feature="llvm")) { - let (_, _) = (outputs, trans); - - if sess.opts.crate_types.contains(&CrateType::CrateTypeRlib) - || sess.opts.crate_types.contains(&CrateType::CrateTypeDylib) { - return Ok(()) - } - sess.fatal("LLVM is not supported by this rustc"); + if sess.opts.debugging_opts.print_type_sizes { + sess.code_stats.borrow().print_type_sizes(); } - #[cfg(feature="llvm")] - { - if sess.opts.debugging_opts.print_type_sizes { - sess.code_stats.borrow().print_type_sizes(); - } - - let (phase5_result, trans) = phase_5_run_llvm_passes::(sess, &dep_graph, trans); - - controller_entry_point!(after_llvm, - sess, - CompileState::state_after_llvm(input, sess, outdir, output, &trans), - phase5_result); - phase5_result?; + let (phase5_result, trans) = phase_5_run_llvm_passes::(sess, &dep_graph, trans); - phase_6_link_output::(sess, &trans, &outputs); + controller_entry_point!(after_llvm, + sess, + CompileState::state_after_llvm(input, sess, outdir, output, &trans), + phase5_result); + phase5_result?; - // Now that we won't touch anything in the incremental compilation directory - // any more, we can finalize it (which involves renaming it) - rustc_incremental::finalize_session_directory(sess, trans.link.crate_hash); + phase_6_link_output::(sess, &trans, &outputs); - if sess.opts.debugging_opts.perf_stats { - sess.print_perf_stats(); - } + // Now that we won't touch anything in the incremental compilation directory + // any more, we can finalize it (which involves renaming it) + #[cfg(feature="llvm")] + rustc_incremental::finalize_session_directory(sess, trans.link.crate_hash); - controller_entry_point!( - compilation_done, - sess, - CompileState::state_when_compilation_done(input, sess, outdir, output), - Ok(()) - ); + if sess.opts.debugging_opts.perf_stats { + sess.print_perf_stats(); } + controller_entry_point!( + compilation_done, + sess, + CompileState::state_when_compilation_done(input, sess, outdir, output), + Ok(()) + ); + Ok(()) } @@ -1171,7 +1153,6 @@ pub fn phase_5_run_llvm_passes(sess: &Session, /// Run the linker on any artifacts that resulted from the LLVM run. /// This should produce either a finished executable or library. -#[cfg(feature="llvm")] pub fn phase_6_link_output(sess: &Session, trans: &::TranslatedCrate, outputs: &OutputFilenames) { diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index fda738db85fd8..db56ff7afc334 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -25,8 +25,6 @@ #![feature(rustc_diagnostic_macros)] #![feature(set_stdio)] -extern crate ar; -extern crate flate2; extern crate arena; extern crate getopts; extern crate graphviz; @@ -155,173 +153,17 @@ pub fn run(run_compiler: F) -> isize } #[cfg(not(feature="llvm"))] -pub use trans_metadata_only::MetadataOnlyTransCrate as DefaultTransCrate; +pub use rustc_trans_traits::MetadataOnlyTransCrate as DefaultTransCrate; #[cfg(feature="llvm")] pub use rustc_trans::LlvmTransCrate as DefaultTransCrate; -mod no_llvm_metadata_loader { - extern crate owning_ref; - - use rustc::middle::cstore::MetadataLoader as MetadataLoaderTrait; - use rustc_back::target::Target; - use std::io; - use std::fs::File; - use std::path::Path; - - use ar::Archive; - use self::owning_ref::{OwningRef, ErasedBoxRef}; - - pub struct NoLlvmMetadataLoader; - - impl MetadataLoaderTrait for NoLlvmMetadataLoader { - fn get_rlib_metadata( - &self, - _: &Target, - filename: &Path - ) -> Result, String> { - let file = File::open(filename).map_err(|e| { - format!("metadata file open err: {:?}", e) - })?; - let mut archive = Archive::new(file); - - while let Some(entry_result) = archive.next_entry() { - let mut entry = entry_result.map_err(|e| { - format!("metadata section read err: {:?}", e) - })?; - if entry.header().identifier() == "rust.metadata.bin" { - let mut buf = Vec::new(); - io::copy(&mut entry, &mut buf).unwrap(); - let buf: OwningRef, [u8]> = OwningRef::new(buf).into(); - return Ok(buf.map_owner_box().erase_owner()); - } - } - - Err("Couldnt find metadata section".to_string()) - } - - fn get_dylib_metadata(&self, - _target: &Target, - _filename: &Path) - -> Result, String> { - // FIXME: Support reading dylibs from llvm enabled rustc - self.get_rlib_metadata(_target, _filename) - } - } -} - -mod trans_metadata_only { - use std::io::prelude::*; - use std::io::Cursor; - use std::fs::File; - - use ar::{Builder, Header}; - use flate2::Compression; - use flate2::write::DeflateEncoder; - - use syntax::symbol::Symbol; - use rustc::hir::def_id::LOCAL_CRATE; - use rustc::session::Session; - use rustc::session::config::{OutputFilenames, CrateType}; - use rustc::ty::{TyCtxt, CrateAnalysis}; - use rustc::ty::maps::Providers; - use rustc::middle::cstore::{MetadataLoader, EncodedMetadata}; - use rustc::dep_graph::DepGraph; - use rustc_incremental::IncrementalHashesMap; - use rustc_trans_utils::find_exported_symbols; - use rustc_trans_utils::link::{out_filename, build_link_meta}; - use rustc_trans_traits::TransCrate; - - #[allow(dead_code)] - pub struct MetadataOnlyTransCrate; - pub struct OngoingCrateTranslation { - metadata: EncodedMetadata, - metadata_version: Vec, - crate_name: Symbol, - } - pub struct TranslatedCrate(OngoingCrateTranslation); - - impl MetadataOnlyTransCrate { - #[allow(dead_code)] - pub fn new(/*_sess: &Session*/) -> Self { - MetadataOnlyTransCrate - } - } - - impl TransCrate for MetadataOnlyTransCrate { - type MetadataLoader = ::no_llvm_metadata_loader::NoLlvmMetadataLoader; - type OngoingCrateTranslation = OngoingCrateTranslation; - type TranslatedCrate = TranslatedCrate; - - fn metadata_loader() -> Box { - box ::no_llvm_metadata_loader::NoLlvmMetadataLoader - } - - fn provide(_providers: &mut Providers) {} - - fn trans_crate<'a, 'tcx>( - tcx: TyCtxt<'a, 'tcx, 'tcx>, - analysis: CrateAnalysis, - incr_hashes_map: IncrementalHashesMap, - _output_filenames: &OutputFilenames - ) -> Self::OngoingCrateTranslation { - let link_meta = build_link_meta(&incr_hashes_map); - let exported_symbols = find_exported_symbols(tcx, &analysis.reachable); - let (metadata, _hashes) = tcx.encode_metadata(&link_meta, &exported_symbols); - - OngoingCrateTranslation { - metadata: metadata, - metadata_version: tcx.metadata_encoding_version().to_vec(), - crate_name: tcx.crate_name(LOCAL_CRATE), - } - } - - fn join_trans( - trans: Self::OngoingCrateTranslation, - _sess: &Session, - _dep_graph: &DepGraph, - ) -> Self::TranslatedCrate { - TranslatedCrate(trans) - } - - fn link_binary(sess: &Session, - trans: &Self::TranslatedCrate, - outputs: &OutputFilenames) { - for &crate_type in sess.opts.crate_types.iter() { - if crate_type != CrateType::CrateTypeRlib && - crate_type != CrateType::CrateTypeDylib { - continue; - } - let output_name = - out_filename(sess, crate_type, &outputs, &trans.0.crate_name.as_str()); - let mut compressed = trans.0.metadata_version.clone(); - let metadata = if crate_type == CrateType::CrateTypeDylib { - DeflateEncoder::new(&mut compressed, Compression::Fast) - .write_all(&trans.0.metadata.raw_data).unwrap(); - &compressed - } else { - &trans.0.metadata.raw_data - }; - let mut builder = Builder::new(File::create(&output_name).unwrap()); - let header = Header::new( - "rust.metadata.bin".to_string(), - metadata.len() as u64 - ); - builder - .append(&header, Cursor::new(metadata)) - .unwrap(); - } - } - - fn dump_incremental_data(_trans: &Self::TranslatedCrate) {} - } -} - #[cfg(not(feature="llvm"))] mod rustc_trans { use syntax_pos::symbol::Symbol; use rustc::session::Session; use rustc::session::config::PrintRequest; - pub use trans_metadata_only::MetadataOnlyTransCrate as LlvmTransCrate; + pub use rustc_trans_traits::MetadataOnlyTransCrate as LlvmTransCrate; + pub use rustc_trans_traits::TranslatedCrate as CrateTranslation; pub fn init(_sess: &Session) {} pub fn enable_llvm_debug() {} @@ -330,8 +172,6 @@ mod rustc_trans { pub fn print(_req: PrintRequest, _sess: &Session) {} pub fn target_features(_sess: &Session) -> Vec { vec![] } - pub struct CrateTranslation(()); - pub mod back { pub mod write { pub const RELOC_MODEL_ARGS: [(&'static str, ()); 0] = []; diff --git a/src/librustc_trans_traits/Cargo.toml b/src/librustc_trans_traits/Cargo.toml index 418de173fd14a..4ba0ed1e1c7ee 100644 --- a/src/librustc_trans_traits/Cargo.toml +++ b/src/librustc_trans_traits/Cargo.toml @@ -10,8 +10,12 @@ crate-type = ["dylib"] test = false [dependencies] +ar = "0.3.0" +flate2 = "0.2" owning_ref = "0.3.3" +syntax = { path = "../libsyntax" } rustc = { path = "../librustc" } rustc_back = { path = "../librustc_back" } rustc_incremental = { path = "../librustc_incremental" } +rustc_trans_utils = { path = "../librustc_trans_utils" } diff --git a/src/librustc_trans_traits/lib.rs b/src/librustc_trans_traits/lib.rs index 340d54c1029fc..3f5f44eb90647 100644 --- a/src/librustc_trans_traits/lib.rs +++ b/src/librustc_trans_traits/lib.rs @@ -21,24 +21,40 @@ #![feature(box_syntax)] +extern crate ar; +extern crate flate2; extern crate owning_ref; +extern crate syntax; #[macro_use] extern crate rustc; extern crate rustc_back; extern crate rustc_incremental; +extern crate rustc_trans_utils; +use std::io::prelude::*; +use std::io::{self, Cursor}; +use std::fs::File; use std::path::Path; -use owning_ref::ErasedBoxRef; +use owning_ref::{ErasedBoxRef, OwningRef}; +use ar::{Archive, Builder, Header}; +use flate2::Compression; +use flate2::write::DeflateEncoder; + +use syntax::symbol::Symbol; +use rustc::hir::def_id::LOCAL_CRATE; use rustc::session::Session; -use rustc::session::config::OutputFilenames; -use rustc::ty::{TyCtxt, CrateAnalysis}; +use rustc::session::config::{CrateType, OutputFilenames}; +use rustc::ty::{CrateAnalysis, TyCtxt}; use rustc::ty::maps::Providers; +use rustc::middle::cstore::EncodedMetadata; use rustc::middle::cstore::MetadataLoader as MetadataLoaderTrait; use rustc::dep_graph::DepGraph; use rustc_back::target::Target; use rustc_incremental::IncrementalHashesMap; +use rustc_trans_utils::find_exported_symbols; +use rustc_trans_utils::link::{build_link_meta, out_filename}; pub trait TransCrate { type MetadataLoader: MetadataLoaderTrait; @@ -114,3 +130,117 @@ impl MetadataLoaderTrait for DummyMetadataLoader { bug!("DummyMetadataLoader::get_dylib_metadata"); } } + +pub struct NoLlvmMetadataLoader; + +impl MetadataLoaderTrait for NoLlvmMetadataLoader { + fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result, String> { + let file = File::open(filename) + .map_err(|e| format!("metadata file open err: {:?}", e))?; + let mut archive = Archive::new(file); + + while let Some(entry_result) = archive.next_entry() { + let mut entry = entry_result + .map_err(|e| format!("metadata section read err: {:?}", e))?; + if entry.header().identifier() == "rust.metadata.bin" { + let mut buf = Vec::new(); + io::copy(&mut entry, &mut buf).unwrap(); + let buf: OwningRef, [u8]> = OwningRef::new(buf).into(); + return Ok(buf.map_owner_box().erase_owner()); + } + } + + Err("Couldnt find metadata section".to_string()) + } + + fn get_dylib_metadata( + &self, + _target: &Target, + _filename: &Path, + ) -> Result, String> { + // FIXME: Support reading dylibs from llvm enabled rustc + self.get_rlib_metadata(_target, _filename) + } +} + +#[allow(dead_code)] +pub struct MetadataOnlyTransCrate; +pub struct OngoingCrateTranslation { + metadata: EncodedMetadata, + metadata_version: Vec, + crate_name: Symbol, +} +pub struct TranslatedCrate(OngoingCrateTranslation); + +impl MetadataOnlyTransCrate { + #[allow(dead_code)] + pub fn new() -> Self { + MetadataOnlyTransCrate + } +} + +impl TransCrate for MetadataOnlyTransCrate { + type MetadataLoader = NoLlvmMetadataLoader; + type OngoingCrateTranslation = OngoingCrateTranslation; + type TranslatedCrate = TranslatedCrate; + + fn metadata_loader() -> Box { + box NoLlvmMetadataLoader + } + + fn provide(_providers: &mut Providers) {} + + fn trans_crate<'a, 'tcx>( + tcx: TyCtxt<'a, 'tcx, 'tcx>, + analysis: CrateAnalysis, + incr_hashes_map: IncrementalHashesMap, + _output_filenames: &OutputFilenames, + ) -> Self::OngoingCrateTranslation { + let link_meta = build_link_meta(&incr_hashes_map); + let exported_symbols = find_exported_symbols(tcx, &analysis.reachable); + let (metadata, _hashes) = tcx.encode_metadata(&link_meta, &exported_symbols); + + OngoingCrateTranslation { + metadata: metadata, + metadata_version: tcx.metadata_encoding_version().to_vec(), + crate_name: tcx.crate_name(LOCAL_CRATE), + } + } + + fn join_trans( + trans: Self::OngoingCrateTranslation, + _sess: &Session, + _dep_graph: &DepGraph, + ) -> Self::TranslatedCrate { + TranslatedCrate(trans) + } + + fn link_binary(sess: &Session, trans: &Self::TranslatedCrate, outputs: &OutputFilenames) { + for &crate_type in sess.opts.crate_types.iter() { + if crate_type != CrateType::CrateTypeRlib && crate_type != CrateType::CrateTypeDylib { + continue; + } + let output_name = + out_filename(sess, crate_type, &outputs, &trans.0.crate_name.as_str()); + let mut compressed = trans.0.metadata_version.clone(); + let metadata = if crate_type == CrateType::CrateTypeDylib { + DeflateEncoder::new(&mut compressed, Compression::Fast) + .write_all(&trans.0.metadata.raw_data) + .unwrap(); + &compressed + } else { + &trans.0.metadata.raw_data + }; + let mut builder = Builder::new(File::create(&output_name).unwrap()); + let header = Header::new("rust.metadata.bin".to_string(), metadata.len() as u64); + builder.append(&header, Cursor::new(metadata)).unwrap(); + } + + if !sess.opts.crate_types.contains(&CrateType::CrateTypeRlib) + && !sess.opts.crate_types.contains(&CrateType::CrateTypeDylib) { + sess.fatal("Executables are not supported by the metadata-only backend."); + } + } + + fn dump_incremental_data(_trans: &Self::TranslatedCrate) {} +} From d703552325edc118cb6bb2fbea1be3dceab7632c Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 18 Sep 2017 18:12:07 +0200 Subject: [PATCH 08/17] Merge rustc_trans_trait into rustc_trans_utils --- src/Cargo.lock | 16 ++------------ src/librustc_driver/Cargo.toml | 1 - src/librustc_driver/driver.rs | 2 +- src/librustc_driver/lib.rs | 9 ++++---- src/librustc_trans/Cargo.toml | 1 - src/librustc_trans/lib.rs | 3 +-- src/librustc_trans_traits/Cargo.toml | 21 ------------------- src/librustc_trans_utils/Cargo.toml | 9 ++++++-- src/librustc_trans_utils/lib.rs | 7 +++++++ .../trans_crate.rs} | 16 ++------------ 10 files changed, 24 insertions(+), 61 deletions(-) delete mode 100644 src/librustc_trans_traits/Cargo.toml rename src/{librustc_trans_traits/lib.rs => librustc_trans_utils/trans_crate.rs} (95%) diff --git a/src/Cargo.lock b/src/Cargo.lock index 49db077849c20..476b33b372dd1 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -1575,7 +1575,6 @@ dependencies = [ "rustc_resolve 0.0.0", "rustc_save_analysis 0.0.0", "rustc_trans 0.0.0", - "rustc_trans_traits 0.0.0", "rustc_trans_utils 0.0.0", "rustc_typeck 0.0.0", "serialize 0.0.0", @@ -1770,7 +1769,6 @@ dependencies = [ "rustc_incremental 0.0.0", "rustc_llvm 0.0.0", "rustc_platform_intrinsics 0.0.0", - "rustc_trans_traits 0.0.0", "rustc_trans_utils 0.0.0", "serialize 0.0.0", "syntax 0.0.0", @@ -1778,26 +1776,16 @@ dependencies = [ ] [[package]] -name = "rustc_trans_traits" +name = "rustc_trans_utils" version = "0.0.0" dependencies = [ "ar 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", "rustc_back 0.0.0", "rustc_incremental 0.0.0", - "rustc_trans_utils 0.0.0", - "syntax 0.0.0", -] - -[[package]] -name = "rustc_trans_utils" -version = "0.0.0" -dependencies = [ - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc 0.0.0", - "rustc_incremental 0.0.0", "syntax 0.0.0", "syntax_pos 0.0.0", ] diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml index 6399f3ad2687e..2aac1b085e95a 100644 --- a/src/librustc_driver/Cargo.toml +++ b/src/librustc_driver/Cargo.toml @@ -33,7 +33,6 @@ rustc_resolve = { path = "../librustc_resolve" } rustc_save_analysis = { path = "../librustc_save_analysis" } rustc_trans = { path = "../librustc_trans", optional = true } rustc_trans_utils = { path = "../librustc_trans_utils" } -rustc_trans_traits = { path = "../librustc_trans_traits" } rustc_typeck = { path = "../librustc_typeck" } serialize = { path = "../libserialize" } syntax = { path = "../libsyntax" } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index aa0000653cc87..ba54301d83599 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -33,7 +33,7 @@ use rustc_resolve::{MakeGlobMap, Resolver}; use rustc_metadata::creader::CrateLoader; use rustc_metadata::cstore::{self, CStore}; use rustc_trans as trans; -use rustc_trans_traits::TransCrate; +use rustc_trans_utils::trans_crate::TransCrate; use rustc_typeck as typeck; use rustc_privacy; use rustc_plugin::registry::Registry; diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index db56ff7afc334..e7520858c673c 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -50,7 +50,6 @@ extern crate rustc_save_analysis; #[cfg(feature="llvm")] extern crate rustc_trans; extern crate rustc_trans_utils; -extern crate rustc_trans_traits; extern crate rustc_typeck; extern crate serialize; #[macro_use] @@ -76,7 +75,7 @@ use rustc::middle::cstore::CrateStore; use rustc_metadata::locator; use rustc_metadata::cstore::CStore; use rustc::util::common::{time, ErrorReported}; -use rustc_trans_traits::TransCrate; +use rustc_trans_utils::trans_crate::TransCrate; use serialize::json::ToJson; @@ -153,7 +152,7 @@ pub fn run(run_compiler: F) -> isize } #[cfg(not(feature="llvm"))] -pub use rustc_trans_traits::MetadataOnlyTransCrate as DefaultTransCrate; +pub use rustc_trans_utils::trans_crate::MetadataOnlyTransCrate as DefaultTransCrate; #[cfg(feature="llvm")] pub use rustc_trans::LlvmTransCrate as DefaultTransCrate; @@ -162,8 +161,8 @@ mod rustc_trans { use syntax_pos::symbol::Symbol; use rustc::session::Session; use rustc::session::config::PrintRequest; - pub use rustc_trans_traits::MetadataOnlyTransCrate as LlvmTransCrate; - pub use rustc_trans_traits::TranslatedCrate as CrateTranslation; + pub use rustc_trans_utils::trans_crate::MetadataOnlyTransCrate as LlvmTransCrate; + pub use rustc_trans_utils::trans_crate::TranslatedCrate as CrateTranslation; pub fn init(_sess: &Session) {} pub fn enable_llvm_debug() {} diff --git a/src/librustc_trans/Cargo.toml b/src/librustc_trans/Cargo.toml index 479d12b7440d2..6f1f5b4a123d8 100644 --- a/src/librustc_trans/Cargo.toml +++ b/src/librustc_trans/Cargo.toml @@ -27,7 +27,6 @@ rustc_incremental = { path = "../librustc_incremental" } rustc_llvm = { path = "../librustc_llvm" } rustc_platform_intrinsics = { path = "../librustc_platform_intrinsics" } rustc_trans_utils = { path = "../librustc_trans_utils" } -rustc_trans_traits = { path = "../librustc_trans_traits" } serialize = { path = "../libserialize" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 9023f5c3e6169..13c3ce6924872 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -50,7 +50,6 @@ extern crate rustc_incremental; extern crate rustc_llvm as llvm; extern crate rustc_platform_intrinsics as intrinsics; extern crate rustc_const_math; -extern crate rustc_trans_traits; extern crate rustc_trans_utils; extern crate rustc_demangle; extern crate jobserver; @@ -154,7 +153,7 @@ impl LlvmTransCrate { } } -impl rustc_trans_traits::TransCrate for LlvmTransCrate { +impl rustc_trans_utils::trans_crate::TransCrate for LlvmTransCrate { type MetadataLoader = metadata::LlvmMetadataLoader; type OngoingCrateTranslation = back::write::OngoingCrateTranslation; type TranslatedCrate = CrateTranslation; diff --git a/src/librustc_trans_traits/Cargo.toml b/src/librustc_trans_traits/Cargo.toml deleted file mode 100644 index 4ba0ed1e1c7ee..0000000000000 --- a/src/librustc_trans_traits/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_trans_traits" -version = "0.0.0" - -[lib] -name = "rustc_trans_traits" -path = "lib.rs" -crate-type = ["dylib"] -test = false - -[dependencies] -ar = "0.3.0" -flate2 = "0.2" -owning_ref = "0.3.3" - -syntax = { path = "../libsyntax" } -rustc = { path = "../librustc" } -rustc_back = { path = "../librustc_back" } -rustc_incremental = { path = "../librustc_incremental" } -rustc_trans_utils = { path = "../librustc_trans_utils" } diff --git a/src/librustc_trans_utils/Cargo.toml b/src/librustc_trans_utils/Cargo.toml index b91a397711140..2a4a27dd892b9 100644 --- a/src/librustc_trans_utils/Cargo.toml +++ b/src/librustc_trans_utils/Cargo.toml @@ -10,8 +10,13 @@ crate-type = ["dylib"] test = false [dependencies] +ar = "0.3.0" +flate2 = "0.2" +owning_ref = "0.3.3" log = "0.3" -rustc = { path = "../librustc" } -rustc_incremental = { path = "../librustc_incremental" } + syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } +rustc = { path = "../librustc" } +rustc_back = { path = "../librustc_back" } +rustc_incremental = { path = "../librustc_incremental" } diff --git a/src/librustc_trans_utils/lib.rs b/src/librustc_trans_utils/lib.rs index 49251a9ecf543..06500e944ca9d 100644 --- a/src/librustc_trans_utils/lib.rs +++ b/src/librustc_trans_utils/lib.rs @@ -29,9 +29,15 @@ #![cfg_attr(stage0, feature(const_fn))] +extern crate ar; +extern crate flate2; +extern crate owning_ref; #[macro_use] extern crate log; + +#[macro_use] extern crate rustc; +extern crate rustc_back; extern crate rustc_incremental; extern crate syntax; extern crate syntax_pos; @@ -44,6 +50,7 @@ use rustc::util::nodemap::NodeSet; use syntax::attr; pub mod link; +pub mod trans_crate; /// The context provided lists a set of reachable ids as calculated by /// middle::reachable, but this contains far more ids and symbols than we're diff --git a/src/librustc_trans_traits/lib.rs b/src/librustc_trans_utils/trans_crate.rs similarity index 95% rename from src/librustc_trans_traits/lib.rs rename to src/librustc_trans_utils/trans_crate.rs index 3f5f44eb90647..df85fae2cb6cf 100644 --- a/src/librustc_trans_traits/lib.rs +++ b/src/librustc_trans_utils/trans_crate.rs @@ -21,17 +21,6 @@ #![feature(box_syntax)] -extern crate ar; -extern crate flate2; -extern crate owning_ref; - -extern crate syntax; -#[macro_use] -extern crate rustc; -extern crate rustc_back; -extern crate rustc_incremental; -extern crate rustc_trans_utils; - use std::io::prelude::*; use std::io::{self, Cursor}; use std::fs::File; @@ -53,8 +42,7 @@ use rustc::middle::cstore::MetadataLoader as MetadataLoaderTrait; use rustc::dep_graph::DepGraph; use rustc_back::target::Target; use rustc_incremental::IncrementalHashesMap; -use rustc_trans_utils::find_exported_symbols; -use rustc_trans_utils::link::{build_link_meta, out_filename}; +use link::{build_link_meta, out_filename}; pub trait TransCrate { type MetadataLoader: MetadataLoaderTrait; @@ -197,7 +185,7 @@ impl TransCrate for MetadataOnlyTransCrate { _output_filenames: &OutputFilenames, ) -> Self::OngoingCrateTranslation { let link_meta = build_link_meta(&incr_hashes_map); - let exported_symbols = find_exported_symbols(tcx, &analysis.reachable); + let exported_symbols = ::find_exported_symbols(tcx, &analysis.reachable); let (metadata, _hashes) = tcx.encode_metadata(&link_meta, &exported_symbols); OngoingCrateTranslation { From e130ccc54e4a25a81c6e3492e6611c5f3ae90e09 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 23 Sep 2017 14:46:15 +0200 Subject: [PATCH 09/17] Fix for upstream changes --- src/Cargo.lock | 1 - src/librustc_trans/base.rs | 3 +- src/librustc_trans/lib.rs | 19 +++++++----- src/librustc_trans_utils/Cargo.toml | 1 - src/librustc_trans_utils/lib.rs | 6 ++-- src/librustc_trans_utils/link.rs | 8 ++--- src/librustc_trans_utils/trans_crate.rs | 40 ++++++++++++++----------- 7 files changed, 41 insertions(+), 37 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index 476b33b372dd1..45396a45a4c25 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -1785,7 +1785,6 @@ dependencies = [ "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", "rustc_back 0.0.0", - "rustc_incremental 0.0.0", "syntax 0.0.0", "syntax_pos 0.0.0", ] diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 154e54f92a83f..ec4cec331d0c4 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -94,6 +94,8 @@ use syntax::ast; use mir::lvalue::Alignment; +pub use rustc_trans_utils::find_exported_symbols; + pub struct StatRecorder<'a, 'tcx: 'a> { ccx: &'a CrateContext<'a, 'tcx>, name: Option, @@ -887,7 +889,6 @@ fn iter_globals(llmod: llvm::ModuleRef) -> ValueIter { pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, rx: mpsc::Receiver>) -> OngoingCrateTranslation { - use rustc_trans_utils::find_exported_symbols; check_for_rustc_errors_attr(tcx); diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 13c3ce6924872..8a2c478cea061 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -138,12 +138,13 @@ mod type_; mod type_of; mod value; -use rustc::ty::{self, TyCtxt, CrateAnalysis}; +use std::sync::mpsc; +use std::any::Any; +use rustc::ty::{self, TyCtxt}; use rustc::session::Session; use rustc::session::config::OutputFilenames; use rustc::middle::cstore::MetadataLoader; use rustc::dep_graph::DepGraph; -use rustc_incremental::IncrementalHashesMap; pub struct LlvmTransCrate(()); @@ -162,17 +163,19 @@ impl rustc_trans_utils::trans_crate::TransCrate for LlvmTransCrate { box metadata::LlvmMetadataLoader } - fn provide(providers: &mut ty::maps::Providers) { - back::symbol_names::provide(providers); + fn provide_local(providers: &mut ty::maps::Providers) { + provide_local(providers); + } + + fn provide_extern(providers: &mut ty::maps::Providers) { + provide_extern(providers); } fn trans_crate<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, - analysis: CrateAnalysis, - incr_hashes_map: IncrementalHashesMap, - output_filenames: &OutputFilenames + rx: mpsc::Receiver> ) -> Self::OngoingCrateTranslation { - base::trans_crate(tcx, analysis, incr_hashes_map, output_filenames) + base::trans_crate(tcx, rx) } fn join_trans( diff --git a/src/librustc_trans_utils/Cargo.toml b/src/librustc_trans_utils/Cargo.toml index 2a4a27dd892b9..bedbea0068874 100644 --- a/src/librustc_trans_utils/Cargo.toml +++ b/src/librustc_trans_utils/Cargo.toml @@ -19,4 +19,3 @@ syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } rustc = { path = "../librustc" } rustc_back = { path = "../librustc_back" } -rustc_incremental = { path = "../librustc_incremental" } diff --git a/src/librustc_trans_utils/lib.rs b/src/librustc_trans_utils/lib.rs index 06500e944ca9d..1de3175e2fcd8 100644 --- a/src/librustc_trans_utils/lib.rs +++ b/src/librustc_trans_utils/lib.rs @@ -38,12 +38,12 @@ extern crate log; #[macro_use] extern crate rustc; extern crate rustc_back; -extern crate rustc_incremental; extern crate syntax; extern crate syntax_pos; use rustc::ty::TyCtxt; use rustc::hir; +use rustc::hir::def_id::LOCAL_CRATE; use rustc::hir::map as hir_map; use rustc::util::nodemap::NodeSet; @@ -60,8 +60,8 @@ pub mod trans_crate; /// /// This list is later used by linkers to determine the set of symbols needed to /// be exposed from a dynamic library and it's also encoded into the metadata. -pub fn find_exported_symbols(tcx: TyCtxt, reachable: &NodeSet) -> NodeSet { - reachable.iter().cloned().filter(|&id| { +pub fn find_exported_symbols(tcx: TyCtxt) -> NodeSet { + tcx.reachable_set(LOCAL_CRATE).0.iter().cloned().filter(|&id| { // Next, we want to ignore some FFI functions that are not exposed from // this crate. Reachable FFI functions can be lumped into two // categories: diff --git a/src/librustc_trans_utils/link.rs b/src/librustc_trans_utils/link.rs index ccd5739efe021..47484488fb8e8 100644 --- a/src/librustc_trans_utils/link.rs +++ b/src/librustc_trans_utils/link.rs @@ -8,12 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use rustc::ich::Fingerprint; use rustc::session::config::{self, OutputFilenames, Input, OutputType}; use rustc::session::Session; use rustc::middle::cstore::{self, LinkMeta}; -use rustc::dep_graph::{DepKind, DepNode}; use rustc::hir::svh::Svh; -use rustc_incremental::IncrementalHashesMap; use std::path::{Path, PathBuf}; use syntax::ast; use syntax_pos::Span; @@ -51,10 +50,9 @@ fn is_writeable(p: &Path) -> bool { } } -pub fn build_link_meta(incremental_hashes_map: &IncrementalHashesMap) -> LinkMeta { - let krate_dep_node = &DepNode::new_no_params(DepKind::Krate); +pub fn build_link_meta(crate_hash: Fingerprint) -> LinkMeta { let r = LinkMeta { - crate_hash: Svh::new(incremental_hashes_map[krate_dep_node].to_smaller_hash()), + crate_hash: Svh::new(crate_hash.to_smaller_hash()), }; info!("{:?}", r); return r; diff --git a/src/librustc_trans_utils/trans_crate.rs b/src/librustc_trans_utils/trans_crate.rs index df85fae2cb6cf..d8f87ee834c0e 100644 --- a/src/librustc_trans_utils/trans_crate.rs +++ b/src/librustc_trans_utils/trans_crate.rs @@ -21,10 +21,12 @@ #![feature(box_syntax)] +use std::any::Any; use std::io::prelude::*; use std::io::{self, Cursor}; use std::fs::File; use std::path::Path; +use std::sync::mpsc; use owning_ref::{ErasedBoxRef, OwningRef}; use ar::{Archive, Builder, Header}; @@ -35,13 +37,12 @@ use syntax::symbol::Symbol; use rustc::hir::def_id::LOCAL_CRATE; use rustc::session::Session; use rustc::session::config::{CrateType, OutputFilenames}; -use rustc::ty::{CrateAnalysis, TyCtxt}; +use rustc::ty::TyCtxt; use rustc::ty::maps::Providers; use rustc::middle::cstore::EncodedMetadata; use rustc::middle::cstore::MetadataLoader as MetadataLoaderTrait; -use rustc::dep_graph::DepGraph; +use rustc::dep_graph::{DepGraph, DepNode, DepKind}; use rustc_back::target::Target; -use rustc_incremental::IncrementalHashesMap; use link::{build_link_meta, out_filename}; pub trait TransCrate { @@ -50,12 +51,11 @@ pub trait TransCrate { type TranslatedCrate; fn metadata_loader() -> Box; - fn provide(_providers: &mut Providers); + fn provide_local(_providers: &mut Providers); + fn provide_extern(_providers: &mut Providers); fn trans_crate<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, - analysis: CrateAnalysis, - incr_hashes_map: IncrementalHashesMap, - output_filenames: &OutputFilenames + rx: mpsc::Receiver> ) -> Self::OngoingCrateTranslation; fn join_trans( trans: Self::OngoingCrateTranslation, @@ -77,15 +77,17 @@ impl TransCrate for DummyTransCrate { box DummyMetadataLoader(()) } - fn provide(_providers: &mut Providers) { - bug!("DummyTransCrate::provide"); + fn provide_local(_providers: &mut Providers) { + bug!("DummyTransCrate::provide_local"); + } + + fn provide_extern(_providers: &mut Providers) { + bug!("DummyTransCrate::provide_extern"); } fn trans_crate<'a, 'tcx>( _tcx: TyCtxt<'a, 'tcx, 'tcx>, - _analysis: CrateAnalysis, - _incr_hashes_map: IncrementalHashesMap, - _output_filenames: &OutputFilenames + _rx: mpsc::Receiver> ) -> Self::OngoingCrateTranslation { bug!("DummyTransCrate::trans_crate"); } @@ -176,16 +178,18 @@ impl TransCrate for MetadataOnlyTransCrate { box NoLlvmMetadataLoader } - fn provide(_providers: &mut Providers) {} + fn provide_local(_providers: &mut Providers) {} + fn provide_extern(_providers: &mut Providers) {} fn trans_crate<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, - analysis: CrateAnalysis, - incr_hashes_map: IncrementalHashesMap, - _output_filenames: &OutputFilenames, + _rx: mpsc::Receiver> ) -> Self::OngoingCrateTranslation { - let link_meta = build_link_meta(&incr_hashes_map); - let exported_symbols = ::find_exported_symbols(tcx, &analysis.reachable); + let crate_hash = tcx.dep_graph + .fingerprint_of(&DepNode::new_no_params(DepKind::Krate)) + .unwrap(); + let link_meta = build_link_meta(crate_hash); + let exported_symbols = ::find_exported_symbols(tcx); let (metadata, _hashes) = tcx.encode_metadata(&link_meta, &exported_symbols); OngoingCrateTranslation { From 43bfd4cd545348836f0739dcfa2d47dcc3569d96 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 23 Sep 2017 15:00:49 +0200 Subject: [PATCH 10/17] Fix some nits --- src/librustc_driver/driver.rs | 32 ++++++++++--------------- src/librustc_trans_utils/trans_crate.rs | 1 - 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index ba54301d83599..06c3dae68e338 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -275,7 +275,11 @@ pub fn compile_input(sess: &Session, phase5_result); phase5_result?; - phase_6_link_output::(sess, &trans, &outputs); + // Run the linker on any artifacts that resulted from the LLVM run. + // This should produce either a finished executable or library. + time(sess.time_passes(), "linking", || { + DefaultTransCrate::link_binary(sess, &trans, &outputs) + }); // Now that we won't touch anything in the incremental compilation directory // any more, we can finalize it (which involves renaming it) @@ -1112,9 +1116,9 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, /// Run the translation phase to LLVM, after which the AST and analysis can /// be discarded. -pub fn phase_4_translate_to_llvm<'a, 'tcx, T: TransCrate>(tcx: TyCtxt<'a, 'tcx, 'tcx>, +pub fn phase_4_translate_to_llvm<'a, 'tcx, Trans: TransCrate>(tcx: TyCtxt<'a, 'tcx, 'tcx>, rx: mpsc::Receiver>) - -> ::OngoingCrateTranslation { + -> ::OngoingCrateTranslation { let time_passes = tcx.sess.time_passes(); time(time_passes, @@ -1123,7 +1127,7 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx, T: TransCrate>(tcx: TyCtxt<'a, 'tcx, let translation = time(time_passes, "translation", move || { - T::trans_crate(tcx, rx) + Trans::trans_crate(tcx, rx) }); if tcx.sess.profile_queries() { profile::dump("profile_queries".to_string()) @@ -1134,14 +1138,14 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx, T: TransCrate>(tcx: TyCtxt<'a, 'tcx, /// Run LLVM itself, producing a bitcode file, assembly file or object file /// as a side effect. -pub fn phase_5_run_llvm_passes(sess: &Session, +pub fn phase_5_run_llvm_passes(sess: &Session, dep_graph: &DepGraph, - trans: ::OngoingCrateTranslation) - -> (CompileResult, ::TranslatedCrate) { - let trans = T::join_trans(trans, sess, dep_graph); + trans: ::OngoingCrateTranslation) + -> (CompileResult, ::TranslatedCrate) { + let trans = Trans::join_trans(trans, sess, dep_graph); if sess.opts.debugging_opts.incremental_info { - T::dump_incremental_data(&trans); + Trans::dump_incremental_data(&trans); } time(sess.time_passes(), @@ -1151,16 +1155,6 @@ pub fn phase_5_run_llvm_passes(sess: &Session, (sess.compile_status(), trans) } -/// Run the linker on any artifacts that resulted from the LLVM run. -/// This should produce either a finished executable or library. -pub fn phase_6_link_output(sess: &Session, - trans: &::TranslatedCrate, - outputs: &OutputFilenames) { - time(sess.time_passes(), "linking", || { - T::link_binary(sess, trans, outputs) - }); -} - fn escape_dep_filename(filename: &str) -> String { // Apparently clang and gcc *only* escape spaces: // http://llvm.org/klaus/clang/commit/9d50634cfc268ecc9a7250226dd5ca0e945240d4 diff --git a/src/librustc_trans_utils/trans_crate.rs b/src/librustc_trans_utils/trans_crate.rs index d8f87ee834c0e..1a03d95ebaa79 100644 --- a/src/librustc_trans_utils/trans_crate.rs +++ b/src/librustc_trans_utils/trans_crate.rs @@ -153,7 +153,6 @@ impl MetadataLoaderTrait for NoLlvmMetadataLoader { } } -#[allow(dead_code)] pub struct MetadataOnlyTransCrate; pub struct OngoingCrateTranslation { metadata: EncodedMetadata, From 793c02db7fb982a6e158438137aeccf9a9074bd3 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 23 Sep 2017 15:10:00 +0200 Subject: [PATCH 11/17] Remove build_diagnostic_array hack --- src/librustc_driver/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index e7520858c673c..6bdad0b212cf5 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -177,8 +177,6 @@ mod rustc_trans { pub const CODE_GEN_MODEL_ARGS: [(&'static str, ()); 0] = []; } } - - __build_diagnostic_array! { librustc_trans, DIAGNOSTICS } } // Parse args and run the compiler. This is the primary entry point for rustc. @@ -1264,6 +1262,7 @@ pub fn diagnostics_registry() -> errors::registry::Registry { all_errors.extend_from_slice(&rustc_borrowck::DIAGNOSTICS); all_errors.extend_from_slice(&rustc_resolve::DIAGNOSTICS); all_errors.extend_from_slice(&rustc_privacy::DIAGNOSTICS); + #[cfg(feature="llvm")] all_errors.extend_from_slice(&rustc_trans::DIAGNOSTICS); all_errors.extend_from_slice(&rustc_const_eval::DIAGNOSTICS); all_errors.extend_from_slice(&rustc_metadata::DIAGNOSTICS); From 70e5baeb71a6b956cd2dd84502903413f735c215 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 23 Sep 2017 15:23:40 +0200 Subject: [PATCH 12/17] Fix tidy errors --- src/librustc_driver/driver.rs | 3 ++- src/librustc_trans_utils/trans_crate.rs | 12 ++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 06c3dae68e338..56c17036cc5e3 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -267,7 +267,8 @@ pub fn compile_input(sess: &Session, sess.code_stats.borrow().print_type_sizes(); } - let (phase5_result, trans) = phase_5_run_llvm_passes::(sess, &dep_graph, trans); + let (phase5_result, trans) = + phase_5_run_llvm_passes::(sess, &dep_graph, trans); controller_entry_point!(after_llvm, sess, diff --git a/src/librustc_trans_utils/trans_crate.rs b/src/librustc_trans_utils/trans_crate.rs index 1a03d95ebaa79..26aa7b0204695 100644 --- a/src/librustc_trans_utils/trans_crate.rs +++ b/src/librustc_trans_utils/trans_crate.rs @@ -112,11 +112,19 @@ impl TransCrate for DummyTransCrate { pub struct DummyMetadataLoader(()); impl MetadataLoaderTrait for DummyMetadataLoader { - fn get_rlib_metadata(&self, _target: &Target, _filename: &Path) -> Result, String> { + fn get_rlib_metadata( + &self, + _target: &Target, + _filename: &Path + ) -> Result, String> { bug!("DummyMetadataLoader::get_rlib_metadata"); } - fn get_dylib_metadata(&self, _target: &Target, _filename: &Path) -> Result, String> { + fn get_dylib_metadata( + &self, + _target: &Target, + _filename: &Path + ) -> Result, String> { bug!("DummyMetadataLoader::get_dylib_metadata"); } } From 95fb1d008f20943e61f1c40460cbb2f89818cf4b Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 23 Sep 2017 15:26:34 +0200 Subject: [PATCH 13/17] Remove leftover --- src/bootstrap/builder.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 8307a536c339d..ffd959d86f580 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -542,12 +542,6 @@ impl<'a> Builder<'a> { .env("RUSTC_SNAPSHOT_LIBDIR", self.rustc_libdir(compiler)); } - if self.build.config.llvm_enabled { - cargo.env("RUSTC_LLVM_ENABLED", "1"); - } else { - cargo.env("RUSTC_LLVM_ENABLED", "0"); - } - // Ignore incremental modes except for stage0, since we're // not guaranteeing correctness across builds if the compiler // is changing under your feet.` From 18005203e15f092eddfc950d0e003bce1907cc88 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 23 Sep 2017 15:27:54 +0200 Subject: [PATCH 14/17] Remove now unused dependency on flate2 from rustc_driver --- src/Cargo.lock | 1 - src/librustc_driver/Cargo.toml | 1 - 2 files changed, 2 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index 45396a45a4c25..e9a20a7c79ca7 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -1554,7 +1554,6 @@ dependencies = [ "ar 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "arena 0.0.0", "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "flate2 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", "graphviz 0.0.0", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml index 2aac1b085e95a..d6155f53485e3 100644 --- a/src/librustc_driver/Cargo.toml +++ b/src/librustc_driver/Cargo.toml @@ -10,7 +10,6 @@ crate-type = ["dylib"] [dependencies] arena = { path = "../libarena" } -flate2 = "0.2" graphviz = { path = "../libgraphviz" } log = { version = "0.3", features = ["release_max_level_info"] } owning_ref = "0.3.3" From 56c46707ed19caaadfe8b0e7fdb034d140eb45fb Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 23 Sep 2017 16:50:05 +0200 Subject: [PATCH 15/17] Fix error --- src/librustc_driver/test.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index cadd63f31f5b4..6de36820f0c19 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -30,6 +30,7 @@ use rustc::hir::map as hir_map; use rustc::mir::transform::Passes; use rustc::session::{self, config}; use rustc::session::config::{OutputFilenames, OutputTypes}; +use rustc_trans_utils::trans_crate::TransCrate; use std::rc::Rc; use syntax::ast; use syntax::abi::Abi; @@ -105,7 +106,7 @@ fn test_env(source_string: &str, options.unstable_features = UnstableFeatures::Allow; let diagnostic_handler = errors::Handler::with_emitter(true, false, emitter); - let cstore = Rc::new(CStore::new(DefaultTransCrate::metadata_loader())); + let cstore = Rc::new(CStore::new(::DefaultTransCrate::metadata_loader())); let sess = session::build_session_(options, None, diagnostic_handler, From 3c32c6aa8dceb0759df7f1aadb46fbd35e40b003 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 23 Sep 2017 18:15:58 +0200 Subject: [PATCH 16/17] Fix some tests with no llvm build --- src/librustc_trans/base.rs | 16 +--------------- src/librustc_trans_utils/lib.rs | 14 ++++++++++++++ src/librustc_trans_utils/trans_crate.rs | 5 +++++ 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index ec4cec331d0c4..b0d24670daeaa 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -94,7 +94,7 @@ use syntax::ast; use mir::lvalue::Alignment; -pub use rustc_trans_utils::find_exported_symbols; +pub use rustc_trans_utils::{find_exported_symbols, check_for_rustc_errors_attr}; pub struct StatRecorder<'a, 'tcx: 'a> { ccx: &'a CrateContext<'a, 'tcx>, @@ -661,20 +661,6 @@ pub fn set_link_section(ccx: &CrateContext, } } -// check for the #[rustc_error] annotation, which forces an -// error in trans. This is used to write compile-fail tests -// that actually test that compilation succeeds without -// reporting an error. -fn check_for_rustc_errors_attr(tcx: TyCtxt) { - if let Some((id, span)) = *tcx.sess.entry_fn.borrow() { - let main_def_id = tcx.hir.local_def_id(id); - - if tcx.has_attr(main_def_id, "rustc_error") { - tcx.sess.span_fatal(span, "compilation successful"); - } - } -} - /// Create the `main` function which will initialize the rust runtime and call /// users main function. fn maybe_create_entry_wrapper(ccx: &CrateContext) { diff --git a/src/librustc_trans_utils/lib.rs b/src/librustc_trans_utils/lib.rs index 1de3175e2fcd8..6873befd2bfca 100644 --- a/src/librustc_trans_utils/lib.rs +++ b/src/librustc_trans_utils/lib.rs @@ -52,6 +52,20 @@ use syntax::attr; pub mod link; pub mod trans_crate; +/// check for the #[rustc_error] annotation, which forces an +/// error in trans. This is used to write compile-fail tests +/// that actually test that compilation succeeds without +/// reporting an error. +pub fn check_for_rustc_errors_attr(tcx: TyCtxt) { + if let Some((id, span)) = *tcx.sess.entry_fn.borrow() { + let main_def_id = tcx.hir.local_def_id(id); + + if tcx.has_attr(main_def_id, "rustc_error") { + tcx.sess.span_fatal(span, "compilation successful"); + } + } +} + /// The context provided lists a set of reachable ids as calculated by /// middle::reachable, but this contains far more ids and symbols than we're /// actually exposing from the object file. This function will filter the set in diff --git a/src/librustc_trans_utils/trans_crate.rs b/src/librustc_trans_utils/trans_crate.rs index 26aa7b0204695..76a15920b2402 100644 --- a/src/librustc_trans_utils/trans_crate.rs +++ b/src/librustc_trans_utils/trans_crate.rs @@ -192,6 +192,11 @@ impl TransCrate for MetadataOnlyTransCrate { tcx: TyCtxt<'a, 'tcx, 'tcx>, _rx: mpsc::Receiver> ) -> Self::OngoingCrateTranslation { + ::check_for_rustc_errors_attr(tcx); + let _ = tcx.link_args(LOCAL_CRATE); + let _ = tcx.native_libraries(LOCAL_CRATE); + tcx.sess.abort_if_errors(); + let crate_hash = tcx.dep_graph .fingerprint_of(&DepNode::new_no_params(DepKind::Krate)) .unwrap(); From 843cd5bacc56dc7a9ec45d3aaebf717566f5bf36 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 25 Sep 2017 08:17:37 +0200 Subject: [PATCH 17/17] Fix error --- src/librustc_trans_utils/trans_crate.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/librustc_trans_utils/trans_crate.rs b/src/librustc_trans_utils/trans_crate.rs index 76a15920b2402..f51a463fcc23e 100644 --- a/src/librustc_trans_utils/trans_crate.rs +++ b/src/librustc_trans_utils/trans_crate.rs @@ -198,8 +198,7 @@ impl TransCrate for MetadataOnlyTransCrate { tcx.sess.abort_if_errors(); let crate_hash = tcx.dep_graph - .fingerprint_of(&DepNode::new_no_params(DepKind::Krate)) - .unwrap(); + .fingerprint_of(&DepNode::new_no_params(DepKind::Krate)); let link_meta = build_link_meta(crate_hash); let exported_symbols = ::find_exported_symbols(tcx); let (metadata, _hashes) = tcx.encode_metadata(&link_meta, &exported_symbols);