This commit upgrades the main LLVM submodule to LLVM's current master branch. The LLD submodule is updated in tandem as well as compiler-builtins. Along the way support was also added for LLVM 7's new features. This primarily includes the support for custom section concatenation natively in LLD so we now add wasm custom sections in LLVM IR rather than having custom support in rustc itself for doing so. Some other miscellaneous changes are: * We now pass `--gc-sections` to `wasm-ld` * The optimization level is now passed to `wasm-ld` * A `--stack-first` option is passed to LLD to have stack overflow always cause a trap instead of corrupting static data * The wasm target for LLVM switched to `wasm32-unknown-unknown`. * The syntax for aligned pointers has changed in LLVM IR and tests are updated to reflect this. * The `thumbv6m-none-eabi` target is disabled due to an [LLVM bug][llbug] Nowadays we've been mostly only upgrading whenever there's a major release of LLVM but enough changes have been happening on the wasm target that there's been growing motivation for quite some time now to upgrade out version of LLD. To upgrade LLD, however, we need to upgrade LLVM to avoid needing to build yet another version of LLVM on the builders. The revision of LLVM in use here is arbitrarily chosen. We will likely need to continue to update it over time if and when we discover bugs. Once LLVM 7 is fully released we can switch to that channel as well. [llbug]: https://bugs.llvm.org/show_bug.cgi?id=37382
230 lines
7.9 KiB
Rust
230 lines
7.9 KiB
Rust
// 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 <LICENSE-APACHE or
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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)]
|
|
|
|
use std::any::Any;
|
|
use std::io::{self, Write};
|
|
use std::fs::File;
|
|
use std::path::Path;
|
|
use std::sync::{mpsc, Arc};
|
|
|
|
use rustc_data_structures::owning_ref::OwningRef;
|
|
use rustc_data_structures::sync::Lrc;
|
|
use flate2::Compression;
|
|
use flate2::write::DeflateEncoder;
|
|
|
|
use syntax::symbol::Symbol;
|
|
use rustc::hir::def_id::LOCAL_CRATE;
|
|
use rustc::session::{Session, CompileIncomplete};
|
|
use rustc::session::config::{CrateType, OutputFilenames, PrintRequest};
|
|
use rustc::ty::TyCtxt;
|
|
use rustc::ty::query::Providers;
|
|
use rustc::middle::cstore::EncodedMetadata;
|
|
use rustc::middle::cstore::MetadataLoader;
|
|
use rustc::dep_graph::DepGraph;
|
|
use rustc_target::spec::Target;
|
|
use rustc_data_structures::fx::FxHashMap;
|
|
use rustc_mir::monomorphize::collector;
|
|
use link::{build_link_meta, out_filename};
|
|
|
|
pub use rustc_data_structures::sync::MetadataRef;
|
|
|
|
pub trait CodegenBackend {
|
|
fn init(&self, _sess: &Session) {}
|
|
fn print(&self, _req: PrintRequest, _sess: &Session) {}
|
|
fn target_features(&self, _sess: &Session) -> Vec<Symbol> { vec![] }
|
|
fn print_passes(&self) {}
|
|
fn print_version(&self) {}
|
|
fn diagnostics(&self) -> &[(&'static str, &'static str)] { &[] }
|
|
|
|
fn metadata_loader(&self) -> Box<MetadataLoader + Sync>;
|
|
fn provide(&self, _providers: &mut Providers);
|
|
fn provide_extern(&self, _providers: &mut Providers);
|
|
fn codegen_crate<'a, 'tcx>(
|
|
&self,
|
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|
rx: mpsc::Receiver<Box<Any + Send>>
|
|
) -> Box<Any>;
|
|
|
|
/// This is called on the returned `Box<Any>` from `codegen_backend`
|
|
///
|
|
/// # Panics
|
|
///
|
|
/// Panics when the passed `Box<Any>` was not returned by `codegen_backend`.
|
|
fn join_codegen_and_link(
|
|
&self,
|
|
ongoing_codegen: Box<Any>,
|
|
sess: &Session,
|
|
dep_graph: &DepGraph,
|
|
outputs: &OutputFilenames,
|
|
) -> Result<(), CompileIncomplete>;
|
|
}
|
|
|
|
pub struct NoLlvmMetadataLoader;
|
|
|
|
impl MetadataLoader for NoLlvmMetadataLoader {
|
|
fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result<MetadataRef, String> {
|
|
let mut file = File::open(filename)
|
|
.map_err(|e| format!("metadata file open err: {:?}", e))?;
|
|
|
|
let mut buf = Vec::new();
|
|
io::copy(&mut file, &mut buf).unwrap();
|
|
let buf: OwningRef<Vec<u8>, [u8]> = OwningRef::new(buf).into();
|
|
return Ok(rustc_erase_owner!(buf.map_owner_box()));
|
|
}
|
|
|
|
fn get_dylib_metadata(&self, target: &Target, filename: &Path) -> Result<MetadataRef, String> {
|
|
self.get_rlib_metadata(target, filename)
|
|
}
|
|
}
|
|
|
|
pub struct MetadataOnlyCodegenBackend(());
|
|
pub struct OngoingCodegen {
|
|
metadata: EncodedMetadata,
|
|
metadata_version: Vec<u8>,
|
|
crate_name: Symbol,
|
|
}
|
|
|
|
impl MetadataOnlyCodegenBackend {
|
|
pub fn new() -> Box<CodegenBackend> {
|
|
box MetadataOnlyCodegenBackend(())
|
|
}
|
|
}
|
|
|
|
impl CodegenBackend for MetadataOnlyCodegenBackend {
|
|
fn init(&self, sess: &Session) {
|
|
for cty in sess.opts.crate_types.iter() {
|
|
match *cty {
|
|
CrateType::CrateTypeRlib | CrateType::CrateTypeDylib |
|
|
CrateType::CrateTypeExecutable => {},
|
|
_ => {
|
|
sess.parse_sess.span_diagnostic.warn(
|
|
&format!("LLVM unsupported, so output type {} is not supported", cty)
|
|
);
|
|
},
|
|
}
|
|
}
|
|
}
|
|
|
|
fn metadata_loader(&self) -> Box<MetadataLoader + Sync> {
|
|
box NoLlvmMetadataLoader
|
|
}
|
|
|
|
fn provide(&self, providers: &mut Providers) {
|
|
::symbol_names::provide(providers);
|
|
|
|
providers.target_features_whitelist = |_tcx, _cnum| {
|
|
Lrc::new(FxHashMap()) // Just a dummy
|
|
};
|
|
providers.is_reachable_non_generic = |_tcx, _defid| true;
|
|
providers.exported_symbols = |_tcx, _crate| Arc::new(Vec::new());
|
|
}
|
|
fn provide_extern(&self, providers: &mut Providers) {
|
|
providers.is_reachable_non_generic = |_tcx, _defid| true;
|
|
}
|
|
|
|
fn codegen_crate<'a, 'tcx>(
|
|
&self,
|
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|
_rx: mpsc::Receiver<Box<Any + Send>>
|
|
) -> Box<Any> {
|
|
use rustc_mir::monomorphize::item::MonoItem;
|
|
|
|
::check_for_rustc_errors_attr(tcx);
|
|
::symbol_names_test::report_symbol_names(tcx);
|
|
::rustc_incremental::assert_dep_graph(tcx);
|
|
::rustc_incremental::assert_module_sources::assert_module_sources(tcx);
|
|
::rustc_mir::monomorphize::assert_symbols_are_distinct(tcx,
|
|
collector::collect_crate_mono_items(
|
|
tcx,
|
|
collector::MonoItemCollectionMode::Eager
|
|
).0.iter()
|
|
);
|
|
// FIXME: Fix this
|
|
// ::rustc::middle::dependency_format::calculate(tcx);
|
|
let _ = tcx.link_args(LOCAL_CRATE);
|
|
let _ = tcx.native_libraries(LOCAL_CRATE);
|
|
for mono_item in
|
|
collector::collect_crate_mono_items(
|
|
tcx,
|
|
collector::MonoItemCollectionMode::Eager
|
|
).0 {
|
|
match mono_item {
|
|
MonoItem::Fn(inst) => {
|
|
let def_id = inst.def_id();
|
|
if def_id.is_local() {
|
|
let _ = inst.def.is_inline(tcx);
|
|
let _ = tcx.codegen_fn_attrs(def_id);
|
|
}
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
tcx.sess.abort_if_errors();
|
|
|
|
let link_meta = build_link_meta(tcx.crate_hash(LOCAL_CRATE));
|
|
let metadata = tcx.encode_metadata(&link_meta);
|
|
|
|
box OngoingCodegen {
|
|
metadata: metadata,
|
|
metadata_version: tcx.metadata_encoding_version().to_vec(),
|
|
crate_name: tcx.crate_name(LOCAL_CRATE),
|
|
}
|
|
}
|
|
|
|
fn join_codegen_and_link(
|
|
&self,
|
|
ongoing_codegen: Box<Any>,
|
|
sess: &Session,
|
|
_dep_graph: &DepGraph,
|
|
outputs: &OutputFilenames,
|
|
) -> Result<(), CompileIncomplete> {
|
|
let ongoing_codegen = ongoing_codegen.downcast::<OngoingCodegen>()
|
|
.expect("Expected MetadataOnlyCodegenBackend's OngoingCodegen, found Box<Any>");
|
|
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, &ongoing_codegen.crate_name.as_str());
|
|
let mut compressed = ongoing_codegen.metadata_version.clone();
|
|
let metadata = if crate_type == CrateType::CrateTypeDylib {
|
|
DeflateEncoder::new(&mut compressed, Compression::fast())
|
|
.write_all(&ongoing_codegen.metadata.raw_data)
|
|
.unwrap();
|
|
&compressed
|
|
} else {
|
|
&ongoing_codegen.metadata.raw_data
|
|
};
|
|
let mut file = File::create(&output_name).unwrap();
|
|
file.write_all(metadata).unwrap();
|
|
}
|
|
|
|
sess.abort_if_errors();
|
|
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.");
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|