Skip to content

Commit 921ebab

Browse files
committed
Auto merge of #51966 - alexcrichton:llvm7, r=<try>
Upgrade to LLVM's master branch (LLVM 7) 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 cc #50543
2 parents 81d5c3e + 6bc9edf commit 921ebab

32 files changed

+186
-186
lines changed

src/librustc/dep_graph/dep_node.rs

-2
Original file line numberDiff line numberDiff line change
@@ -664,8 +664,6 @@ define_dep_nodes!( <'tcx>
664664

665665
[] InstanceDefSizeEstimate { instance_def: InstanceDef<'tcx> },
666666

667-
[] WasmCustomSections(CrateNum),
668-
669667
[input] Features,
670668

671669
[] ProgramClausesFor(DefId),

src/librustc/mir/mono.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ pub enum MonoItem<'tcx> {
2424
Fn(Instance<'tcx>),
2525
Static(DefId),
2626
GlobalAsm(NodeId),
27+
CustomSection(DefId),
2728
}
2829

2930
impl<'tcx> MonoItem<'tcx> {
@@ -36,7 +37,9 @@ impl<'tcx> MonoItem<'tcx> {
3637
},
3738
// Conservatively estimate the size of a static declaration
3839
// or assembly to be 1.
39-
MonoItem::Static(_) | MonoItem::GlobalAsm(_) => 1,
40+
MonoItem::Static(_) |
41+
MonoItem::GlobalAsm(_) |
42+
MonoItem::CustomSection(_) => 1,
4043
}
4144
}
4245
}
@@ -51,7 +54,8 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for MonoItem<'tcx> {
5154
MonoItem::Fn(ref instance) => {
5255
instance.hash_stable(hcx, hasher);
5356
}
54-
MonoItem::Static(def_id) => {
57+
MonoItem::Static(def_id) |
58+
MonoItem::CustomSection(def_id) => {
5559
def_id.hash_stable(hcx, hasher);
5660
}
5761
MonoItem::GlobalAsm(node_id) => {

src/librustc/ty/query/config.rs

-6
Original file line numberDiff line numberDiff line change
@@ -776,12 +776,6 @@ impl<'tcx> QueryDescription<'tcx> for queries::instance_def_size_estimate<'tcx>
776776
}
777777
}
778778

779-
impl<'tcx> QueryDescription<'tcx> for queries::wasm_custom_sections<'tcx> {
780-
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
781-
format!("custom wasm sections for a crate")
782-
}
783-
}
784-
785779
impl<'tcx> QueryDescription<'tcx> for queries::generics_of<'tcx> {
786780
#[inline]
787781
fn cache_on_disk(def_id: Self::Key) -> bool {

src/librustc/ty/query/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,6 @@ define_queries! { <'tcx>
521521
ty::ParamEnv<'tcx>
522522
) -> Clauses<'tcx>,
523523

524-
[] fn wasm_custom_sections: WasmCustomSections(CrateNum) -> Lrc<Vec<DefId>>,
525524
[] fn wasm_import_module_map: WasmImportModuleMap(CrateNum)
526525
-> Lrc<FxHashMap<DefId, String>>,
527526
}

src/librustc/ty/query/plumbing.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1207,7 +1207,6 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
12071207
DepKind::Features => { force!(features_query, LOCAL_CRATE); }
12081208

12091209
DepKind::ProgramClausesFor => { force!(program_clauses_for, def_id!()); }
1210-
DepKind::WasmCustomSections => { force!(wasm_custom_sections, krate!()); }
12111210
DepKind::WasmImportModuleMap => { force!(wasm_import_module_map, krate!()); }
12121211
DepKind::ForeignModules => { force!(foreign_modules, krate!()); }
12131212

src/librustc_codegen_llvm/attributes.rs

+1-30
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@
1111
1212
use std::ffi::{CStr, CString};
1313

14-
use rustc::hir::{self, CodegenFnAttrFlags};
14+
use rustc::hir::CodegenFnAttrFlags;
1515
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
16-
use rustc::hir::itemlikevisit::ItemLikeVisitor;
1716
use rustc::session::Session;
1817
use rustc::session::config::Sanitizer;
1918
use rustc::ty::TyCtxt;
@@ -222,37 +221,9 @@ pub fn provide(providers: &mut Providers) {
222221
}
223222
};
224223

225-
providers.wasm_custom_sections = |tcx, cnum| {
226-
assert_eq!(cnum, LOCAL_CRATE);
227-
let mut finder = WasmSectionFinder { tcx, list: Vec::new() };
228-
tcx.hir.krate().visit_all_item_likes(&mut finder);
229-
Lrc::new(finder.list)
230-
};
231-
232224
provide_extern(providers);
233225
}
234226

235-
struct WasmSectionFinder<'a, 'tcx: 'a> {
236-
tcx: TyCtxt<'a, 'tcx, 'tcx>,
237-
list: Vec<DefId>,
238-
}
239-
240-
impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for WasmSectionFinder<'a, 'tcx> {
241-
fn visit_item(&mut self, i: &'tcx hir::Item) {
242-
match i.node {
243-
hir::ItemConst(..) => {}
244-
_ => return,
245-
}
246-
if i.attrs.iter().any(|i| i.check_name("wasm_custom_section")) {
247-
self.list.push(self.tcx.hir.local_def_id(i.id));
248-
}
249-
}
250-
251-
fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem) {}
252-
253-
fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) {}
254-
}
255-
256227
pub fn provide_extern(providers: &mut Providers) {
257228
providers.wasm_import_module_map = |tcx, cnum| {
258229
let mut ret = FxHashMap();

src/librustc_codegen_llvm/back/link.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use rustc::util::common::time;
2929
use rustc::util::fs::fix_windows_verbatim_for_gcc;
3030
use rustc::hir::def_id::CrateNum;
3131
use tempfile::{Builder as TempFileBuilder, TempDir};
32-
use rustc_target::spec::{PanicStrategy, RelroLevel, LinkerFlavor, TargetTriple};
32+
use rustc_target::spec::{PanicStrategy, RelroLevel, LinkerFlavor};
3333
use rustc_data_structures::fx::FxHashSet;
3434
use context::get_reloc_model;
3535
use llvm;
@@ -837,10 +837,8 @@ fn link_natively(sess: &Session,
837837
}
838838
}
839839

840-
if sess.opts.target_triple == TargetTriple::from_triple("wasm32-unknown-unknown") {
840+
if sess.opts.target_triple.triple() == "wasm32-unknown-unknown" {
841841
wasm::rewrite_imports(&out_filename, &codegen_results.crate_info.wasm_imports);
842-
wasm::add_custom_sections(&out_filename,
843-
&codegen_results.crate_info.wasm_custom_sections);
844842
}
845843
}
846844

src/librustc_codegen_llvm/back/linker.rs

+35-2
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ impl LinkerInfo {
8686
LinkerFlavor::Lld(LldFlavor::Wasm) => {
8787
Box::new(WasmLd {
8888
cmd,
89+
sess,
8990
}) as Box<Linker>
9091
}
9192
}
@@ -909,11 +910,12 @@ fn exported_symbols(tcx: TyCtxt, crate_type: CrateType) -> Vec<String> {
909910
symbols
910911
}
911912

912-
pub struct WasmLd {
913+
pub struct WasmLd<'a> {
913914
cmd: Command,
915+
sess: &'a Session,
914916
}
915917

916-
impl Linker for WasmLd {
918+
impl<'a> Linker for WasmLd<'a> {
917919
fn link_dylib(&mut self, lib: &str) {
918920
self.cmd.arg("-l").arg(lib);
919921
}
@@ -978,9 +980,20 @@ impl Linker for WasmLd {
978980
}
979981

980982
fn gc_sections(&mut self, _keep_metadata: bool) {
983+
self.cmd.arg("--gc-sections");
981984
}
982985

983986
fn optimize(&mut self) {
987+
self.cmd.arg(match self.sess.opts.optimize {
988+
OptLevel::No => "-O0",
989+
OptLevel::Less => "-O1",
990+
OptLevel::Default => "-O2",
991+
OptLevel::Aggressive => "-O3",
992+
// Currently LLD doesn't support `Os` and `Oz`, so pass through `O2`
993+
// instead.
994+
OptLevel::Size => "-O2",
995+
OptLevel::SizeMin => "-O2"
996+
});
984997
}
985998

986999
fn pgo_gen(&mut self) {
@@ -1010,8 +1023,28 @@ impl Linker for WasmLd {
10101023
// this isn't yet the bottleneck of compilation at all anyway.
10111024
self.cmd.arg("--no-threads");
10121025

1026+
// By default LLD only gives us one page of stack (64k) which is a
1027+
// little small. Default to a larger stack closer to other PC platforms
1028+
// (1MB) and users can always inject their own link-args to override this.
10131029
self.cmd.arg("-z").arg("stack-size=1048576");
10141030

1031+
// By default LLD's memory layout is:
1032+
//
1033+
// 1. First, a blank page
1034+
// 2. Next, all static data
1035+
// 3. Finally, the main stack (which grows down)
1036+
//
1037+
// This has the unfortunate consequence that on stack overflows you
1038+
// corrupt static data and can cause some exceedingly weird bugs. To
1039+
// help detect this a little sooner we instead request that the stack is
1040+
// placed before static data.
1041+
//
1042+
// This means that we'll generate slightly larger binaries as references
1043+
// to static data will take more bytes in the ULEB128 encoding, but
1044+
// stack overflow will be guaranteed to trap as it underflows instead of
1045+
// corrupting static data.
1046+
self.cmd.arg("--stack-first");
1047+
10151048
// FIXME we probably shouldn't pass this but instead pass an explicit
10161049
// whitelist of symbols we'll allow to be undefined. Unfortunately
10171050
// though we can't handle symbols like `log10` that LLVM injects at a

src/librustc_codegen_llvm/back/wasm.rs

+1-41
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use std::collections::BTreeMap;
1211
use std::fs;
1312
use std::path::Path;
1413
use std::str;
@@ -24,45 +23,6 @@ const WASM_EXTERNAL_KIND_TABLE: u8 = 1;
2423
const WASM_EXTERNAL_KIND_MEMORY: u8 = 2;
2524
const WASM_EXTERNAL_KIND_GLOBAL: u8 = 3;
2625

27-
/// Append all the custom sections listed in `sections` to the wasm binary
28-
/// specified at `path`.
29-
///
30-
/// LLVM 6 which we're using right now doesn't have the ability to create custom
31-
/// sections in wasm files nor does LLD have the ability to merge these sections
32-
/// into one larger section when linking. It's expected that this will
33-
/// eventually get implemented, however!
34-
///
35-
/// Until that time though this is a custom implementation in rustc to append
36-
/// all sections to a wasm file to the finished product that LLD produces.
37-
///
38-
/// Support for this is landing in LLVM in https://reviews.llvm.org/D43097,
39-
/// although after that support will need to be in LLD as well.
40-
pub fn add_custom_sections(path: &Path, sections: &BTreeMap<String, Vec<u8>>) {
41-
if sections.len() == 0 {
42-
return
43-
}
44-
45-
let wasm = fs::read(path).expect("failed to read wasm output");
46-
47-
// see https://webassembly.github.io/spec/core/binary/modules.html#custom-section
48-
let mut wasm = WasmEncoder { data: wasm };
49-
for (section, bytes) in sections {
50-
// write the `id` identifier, 0 for a custom section
51-
wasm.byte(0);
52-
53-
// figure out how long our name descriptor will be
54-
let mut name = WasmEncoder::new();
55-
name.str(section);
56-
57-
// write the length of the payload followed by all its contents
58-
wasm.u32((bytes.len() + name.data.len()) as u32);
59-
wasm.data.extend_from_slice(&name.data);
60-
wasm.data.extend_from_slice(bytes);
61-
}
62-
63-
fs::write(path, &wasm.data).expect("failed to write wasm output");
64-
}
65-
6626
/// Rewrite the module imports are listed from in a wasm module given the field
6727
/// name to module name mapping in `import_map`.
6828
///
@@ -80,7 +40,7 @@ pub fn add_custom_sections(path: &Path, sections: &BTreeMap<String, Vec<u8>>) {
8040
///
8141
/// Support for this was added to LLVM in
8242
/// https://github.com/llvm-mirror/llvm/commit/0f32e1365, although support still
83-
/// needs to be added (AFAIK at the time of this writing) to LLD
43+
/// needs to be added, tracked at https://bugs.llvm.org/show_bug.cgi?id=37168
8444
pub fn rewrite_imports(path: &Path, import_map: &FxHashMap<String, String>) {
8545
if import_map.len() == 0 {
8646
return

src/librustc_codegen_llvm/base.rs

+30-24
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ use back::link;
3333
use back::write::{self, OngoingCodegen, create_target_machine};
3434
use llvm::{ContextRef, ModuleRef, ValueRef, Vector, get_param};
3535
use llvm;
36+
use libc::c_uint;
3637
use metadata;
3738
use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
3839
use rustc::middle::lang_items::StartFnLangItem;
@@ -73,10 +74,8 @@ use type_of::LayoutLlvmExt;
7374
use rustc::util::nodemap::{FxHashMap, FxHashSet, DefIdSet};
7475
use CrateInfo;
7576
use rustc_data_structures::sync::Lrc;
76-
use rustc_target::spec::TargetTriple;
7777

7878
use std::any::Any;
79-
use std::collections::BTreeMap;
8079
use std::ffi::CString;
8180
use std::str;
8281
use std::sync::Arc;
@@ -1094,7 +1093,6 @@ impl CrateInfo {
10941093
used_crates_dynamic: cstore::used_crates(tcx, LinkagePreference::RequireDynamic),
10951094
used_crates_static: cstore::used_crates(tcx, LinkagePreference::RequireStatic),
10961095
used_crate_source: FxHashMap(),
1097-
wasm_custom_sections: BTreeMap::new(),
10981096
wasm_imports: FxHashMap(),
10991097
lang_item_to_crate: FxHashMap(),
11001098
missing_lang_items: FxHashMap(),
@@ -1104,16 +1102,9 @@ impl CrateInfo {
11041102
let load_wasm_items = tcx.sess.crate_types.borrow()
11051103
.iter()
11061104
.any(|c| *c != config::CrateTypeRlib) &&
1107-
tcx.sess.opts.target_triple == TargetTriple::from_triple("wasm32-unknown-unknown");
1105+
tcx.sess.opts.target_triple.triple() == "wasm32-unknown-unknown";
11081106

11091107
if load_wasm_items {
1110-
info!("attempting to load all wasm sections");
1111-
for &id in tcx.wasm_custom_sections(LOCAL_CRATE).iter() {
1112-
let (name, contents) = fetch_wasm_section(tcx, id);
1113-
info.wasm_custom_sections.entry(name)
1114-
.or_insert(Vec::new())
1115-
.extend(contents);
1116-
}
11171108
info.load_wasm_imports(tcx, LOCAL_CRATE);
11181109
}
11191110

@@ -1137,12 +1128,6 @@ impl CrateInfo {
11371128
info.is_no_builtins.insert(cnum);
11381129
}
11391130
if load_wasm_items {
1140-
for &id in tcx.wasm_custom_sections(cnum).iter() {
1141-
let (name, contents) = fetch_wasm_section(tcx, id);
1142-
info.wasm_custom_sections.entry(name)
1143-
.or_insert(Vec::new())
1144-
.extend(contents);
1145-
}
11461131
info.load_wasm_imports(tcx, cnum);
11471132
}
11481133
let missing = tcx.missing_lang_items(cnum);
@@ -1379,25 +1364,46 @@ mod temp_stable_hash_impls {
13791364
}
13801365
}
13811366

1382-
fn fetch_wasm_section(tcx: TyCtxt, id: DefId) -> (String, Vec<u8>) {
1367+
pub fn define_custom_section(cx: &CodegenCx, def_id: DefId) {
13831368
use rustc::mir::interpret::GlobalId;
13841369

1385-
info!("loading wasm section {:?}", id);
1370+
assert!(cx.tcx.sess.opts.target_triple.triple().starts_with("wasm32"));
1371+
1372+
info!("loading wasm section {:?}", def_id);
13861373

1387-
let section = tcx.get_attrs(id)
1374+
let section = cx.tcx.get_attrs(def_id)
13881375
.iter()
13891376
.find(|a| a.check_name("wasm_custom_section"))
13901377
.expect("missing #[wasm_custom_section] attribute")
13911378
.value_str()
13921379
.expect("malformed #[wasm_custom_section] attribute");
13931380

1394-
let instance = ty::Instance::mono(tcx, id);
1381+
let instance = ty::Instance::mono(cx.tcx, def_id);
13951382
let cid = GlobalId {
13961383
instance,
13971384
promoted: None
13981385
};
13991386
let param_env = ty::ParamEnv::reveal_all();
1400-
let val = tcx.const_eval(param_env.and(cid)).unwrap();
1401-
let alloc = tcx.const_value_to_allocation(val);
1402-
(section.to_string(), alloc.bytes.clone())
1387+
let val = cx.tcx.const_eval(param_env.and(cid)).unwrap();
1388+
let alloc = cx.tcx.const_value_to_allocation(val);
1389+
1390+
unsafe {
1391+
let section = llvm::LLVMMDStringInContext(
1392+
cx.llcx,
1393+
section.as_str().as_ptr() as *const _,
1394+
section.as_str().len() as c_uint,
1395+
);
1396+
let alloc = llvm::LLVMMDStringInContext(
1397+
cx.llcx,
1398+
alloc.bytes.as_ptr() as *const _,
1399+
alloc.bytes.len() as c_uint,
1400+
);
1401+
let data = [section, alloc];
1402+
let meta = llvm::LLVMMDNodeInContext(cx.llcx, data.as_ptr(), 2);
1403+
llvm::LLVMAddNamedMetadataOperand(
1404+
cx.llmod,
1405+
"wasm.custom_sections\0".as_ptr() as *const _,
1406+
meta,
1407+
);
1408+
}
14031409
}

0 commit comments

Comments
 (0)