diff options
| author | bors <bors@rust-lang.org> | 2021-04-05 01:26:57 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-04-05 01:26:57 +0000 |
| commit | 015d2bc3fec48cef3cbfaec71c54fa31ce420853 (patch) | |
| tree | 78f07dccce940c12922d9af6e94143edee0e2ed4 /compiler | |
| parent | 35aa636159b84a771000ee025828798fd959933d (diff) | |
| parent | f8709ec96211b821c9fe8516d73d512eb718a15e (diff) | |
| download | rust-015d2bc3fec48cef3cbfaec71c54fa31ce420853.tar.gz rust-015d2bc3fec48cef3cbfaec71c54fa31ce420853.zip | |
Auto merge of #83864 - Dylan-DPC:rollup-78an86n, r=Dylan-DPC
Rollup of 7 pull requests Successful merges: - #80525 (wasm64 support) - #83019 (core: disable `ptr::swap_nonoverlapping_one`'s block optimization on SPIR-V.) - #83717 (rustdoc: Separate filter-empty-string out into its own function) - #83807 (Tests: Remove redundant `ignore-tidy-linelength` annotations) - #83815 (ptr::addr_of documentation improvements) - #83820 (Remove attribute `#[link_args]`) - #83841 (Allow clobbering unsupported registers in asm!) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'compiler')
29 files changed, 209 insertions, 136 deletions
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 32fb8d1c8f4..d5a9d7ee6e3 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -1499,46 +1499,64 @@ impl<'hir> LoweringContext<'_, 'hir> { // previous iteration. required_features.clear(); - // Validate register classes against currently enabled target - // features. We check that at least one type is available for - // the current target. let reg_class = reg.reg_class(); if reg_class == asm::InlineAsmRegClass::Err { continue; } - for &(_, feature) in reg_class.supported_types(asm_arch.unwrap()) { - if let Some(feature) = feature { - if self.sess.target_features.contains(&Symbol::intern(feature)) { + + // We ignore target feature requirements for clobbers: if the + // feature is disabled then the compiler doesn't care what we + // do with the registers. + // + // Note that this is only possible for explicit register + // operands, which cannot be used in the asm string. + let is_clobber = matches!( + op, + hir::InlineAsmOperand::Out { + reg: asm::InlineAsmRegOrRegClass::Reg(_), + late: _, + expr: None + } + ); + + if !is_clobber { + // Validate register classes against currently enabled target + // features. We check that at least one type is available for + // the current target. + for &(_, feature) in reg_class.supported_types(asm_arch.unwrap()) { + if let Some(feature) = feature { + if self.sess.target_features.contains(&Symbol::intern(feature)) { + required_features.clear(); + break; + } else { + required_features.push(feature); + } + } else { required_features.clear(); break; - } else { - required_features.push(feature); } - } else { - required_features.clear(); - break; } - } - // We are sorting primitive strs here and can use unstable sort here - required_features.sort_unstable(); - required_features.dedup(); - match &required_features[..] { - [] => {} - [feature] => { - let msg = format!( - "register class `{}` requires the `{}` target feature", - reg_class.name(), - feature - ); - sess.struct_span_err(op_sp, &msg).emit(); - } - features => { - let msg = format!( - "register class `{}` requires at least one target feature: {}", - reg_class.name(), - features.join(", ") - ); - sess.struct_span_err(op_sp, &msg).emit(); + // We are sorting primitive strs here and can use unstable sort here + required_features.sort_unstable(); + required_features.dedup(); + match &required_features[..] { + [] => {} + [feature] => { + let msg = format!( + "register class `{}` requires the `{}` target feature", + reg_class.name(), + feature + ); + sess.struct_span_err(op_sp, &msg).emit(); + } + features => { + let msg = format!( + "register class `{}` requires at least one target feature: {}", + reg_class.name(), + features.join(", ") + ); + sess.struct_span_err(op_sp, &msg).emit(); + } } } diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index e7d359c4f14..84b091d8d4d 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -14,7 +14,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; use rustc_middle::ty::layout::TyAndLayout; use rustc_middle::{bug, span_bug}; -use rustc_span::{Pos, Span}; +use rustc_span::{Pos, Span, Symbol}; use rustc_target::abi::*; use rustc_target::asm::*; @@ -125,15 +125,39 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { // Collect the types of output operands let mut constraints = vec![]; + let mut clobbers = vec![]; let mut output_types = vec![]; let mut op_idx = FxHashMap::default(); for (idx, op) in operands.iter().enumerate() { match *op { InlineAsmOperandRef::Out { reg, late, place } => { + let is_target_supported = |reg_class: InlineAsmRegClass| { + for &(_, feature) in reg_class.supported_types(asm_arch) { + if let Some(feature) = feature { + if self.tcx.sess.target_features.contains(&Symbol::intern(feature)) + { + return true; + } + } else { + // Register class is unconditionally supported + return true; + } + } + false + }; + let mut layout = None; let ty = if let Some(ref place) = place { layout = Some(&place.layout); llvm_fixup_output_type(self.cx, reg.reg_class(), &place.layout) + } else if !is_target_supported(reg.reg_class()) { + // We turn discarded outputs into clobber constraints + // if the target feature needed by the register class is + // disabled. This is necessary otherwise LLVM will try + // to actually allocate a register for the dummy output. + assert!(matches!(reg, InlineAsmRegOrRegClass::Reg(_))); + clobbers.push(format!("~{}", reg_to_llvm(reg, None))); + continue; } else { // If the output is discarded, we don't really care what // type is used. We're just using this to tell LLVM to @@ -244,6 +268,7 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { } } + constraints.append(&mut clobbers); if !options.contains(InlineAsmOptions::PRESERVES_FLAGS) { match asm_arch { InlineAsmArch::AArch64 | InlineAsmArch::Arm => { diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 594d42c9366..6e1d4eba842 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -317,7 +317,7 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value, instance: ty:: // Note that currently the `wasm-import-module` doesn't do anything, but // eventually LLVM 7 should read this and ferry the appropriate import // module to the output file. - if cx.tcx.sess.target.arch == "wasm32" { + if cx.tcx.sess.target.is_like_wasm { if let Some(module) = wasm_import_module(cx.tcx, instance.def_id()) { llvm::AddFunctionAttrStringValue( llfn, diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index b3551177323..82f3ee07c93 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -170,10 +170,7 @@ pub fn target_machine_factory( // On the wasm target once the `atomics` feature is enabled that means that // we're no longer single-threaded, or otherwise we don't want LLVM to // lower atomic operations to single-threaded operations. - if singlethread - && sess.target.llvm_target.contains("wasm32") - && sess.target_features.contains(&sym::atomics) - { + if singlethread && sess.target.is_like_wasm && sess.target_features.contains(&sym::atomics) { singlethread = false; } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index d90e93f116c..e6fa852155b 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -1083,9 +1083,9 @@ pub fn compile_unit_metadata( ); } - // Insert `llvm.ident` metadata on the wasm32 targets since that will + // Insert `llvm.ident` metadata on the wasm targets since that will // get hooked up to the "producer" sections `processed-by` information. - if tcx.sess.opts.target_triple.triple().starts_with("wasm32") { + if tcx.sess.target.is_like_wasm { let name_metadata = llvm::LLVMMDStringInContext( debug_context.llcontext, rustc_producer.as_ptr().cast(), diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 217b8f43229..ea75943d6f3 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1411,15 +1411,10 @@ fn add_link_script(cmd: &mut dyn Linker, sess: &Session, tmpdir: &Path, crate_ty } } -/// Add arbitrary "user defined" args defined from command line and by `#[link_args]` attributes. +/// Add arbitrary "user defined" args defined from command line. /// FIXME: Determine where exactly these args need to be inserted. -fn add_user_defined_link_args( - cmd: &mut dyn Linker, - sess: &Session, - codegen_results: &CodegenResults, -) { +fn add_user_defined_link_args(cmd: &mut dyn Linker, sess: &Session) { cmd.args(&sess.opts.cg.link_args); - cmd.args(&*codegen_results.crate_info.link_args); } /// Add arbitrary "late link" args defined by the target spec. @@ -1761,7 +1756,7 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>( add_rpath_args(cmd, sess, codegen_results, out_filename); // OBJECT-FILES-MAYBE, CUSTOMIZATION-POINT - add_user_defined_link_args(cmd, sess, codegen_results); + add_user_defined_link_args(cmd, sess); // NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER cmd.finalize(); diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index e19274e579b..77d8ab49ff2 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -186,7 +186,7 @@ impl<'a> GccLinker<'a> { // * On OSX they have their own linker, not binutils' // * For WebAssembly the only functional linker is LLD, which doesn't // support hint flags - !self.sess.target.is_like_osx && self.sess.target.arch != "wasm32" + !self.sess.target.is_like_osx && !self.sess.target.is_like_wasm } // Some platforms take hints about whether a library is static or dynamic. diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 08e31c3b37f..318eed76acf 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -754,7 +754,6 @@ impl CrateInfo { is_no_builtins: Default::default(), native_libraries: Default::default(), used_libraries: tcx.native_libraries(LOCAL_CRATE).iter().map(Into::into).collect(), - link_args: tcx.link_args(LOCAL_CRATE), crate_name: Default::default(), used_crates_dynamic: cstore::used_crates(tcx, LinkagePreference::RequireDynamic), used_crates_static: cstore::used_crates(tcx, LinkagePreference::RequireStatic), diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 56b4ef79383..f0f45b067b3 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -139,7 +139,6 @@ pub struct CrateInfo { pub native_libraries: FxHashMap<CrateNum, Vec<NativeLib>>, pub crate_name: FxHashMap<CrateNum, String>, pub used_libraries: Vec<NativeLib>, - pub link_args: Lrc<Vec<String>>, pub used_crate_source: FxHashMap<CrateNum, Lrc<CrateSource>>, pub used_crates_static: Vec<(CrateNum, LibSource)>, pub used_crates_dynamic: Vec<(CrateNum, LibSource)>, diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index a69e6d2b86d..4e987908b4e 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -161,7 +161,7 @@ pub fn supported_target_features(sess: &Session) -> &'static [(&'static str, Opt "mips" | "mips64" => MIPS_ALLOWED_FEATURES, "powerpc" | "powerpc64" => POWERPC_ALLOWED_FEATURES, "riscv32" | "riscv64" => RISCV_ALLOWED_FEATURES, - "wasm32" => WASM_ALLOWED_FEATURES, + "wasm32" | "wasm64" => WASM_ALLOWED_FEATURES, _ => &[], } } diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 040260f5cf5..abbeb9554e3 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -258,9 +258,6 @@ declare_features! ( // feature-group-start: actual feature gates // ------------------------------------------------------------------------- - /// Allows using the `#[link_args]` attribute. - (active, link_args, "1.0.0", Some(29596), None), - /// Allows defining identifiers beyond ASCII. (active, non_ascii_idents, "1.0.0", Some(55467), None), diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 072062dd615..7df9b3f0a79 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -280,11 +280,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ // Linking: gated!(naked, AssumedUsed, template!(Word), naked_functions, experimental!(naked)), gated!( - link_args, Normal, template!(NameValueStr: "args"), - "the `link_args` attribute is experimental and not portable across platforms, \ - it is recommended to use `#[link(name = \"foo\")] instead", - ), - gated!( link_ordinal, AssumedUsed, template!(List: "ordinal"), raw_dylib, experimental!(link_ordinal) ), diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index 8ba67a00f8d..e1491576616 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -128,6 +128,10 @@ declare_features! ( /// Allows comparing raw pointers during const eval. (removed, const_compare_raw_pointers, "1.46.0", Some(53020), None, Some("cannot be allowed in const eval in any meaningful way")), + /// Allows using the `#[link_args]` attribute. + (removed, link_args, "1.53.0", Some(29596), None, + Some("removed in favor of using `-C link-arg=ARG` on command line, \ + which is available from cargo build scripts with `cargo:rustc-link-arg` now")), // ------------------------------------------------------------------------- // feature-group-end: removed features diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs index fe93f4230e9..c4d9e3f77f0 100644 --- a/compiler/rustc_metadata/src/lib.rs +++ b/compiler/rustc_metadata/src/lib.rs @@ -26,7 +26,6 @@ pub use rmeta::{provide, provide_extern}; mod dependency_format; mod foreign_modules; -mod link_args; mod native_libs; mod rmeta; diff --git a/compiler/rustc_metadata/src/link_args.rs b/compiler/rustc_metadata/src/link_args.rs deleted file mode 100644 index 9e1ac33368c..00000000000 --- a/compiler/rustc_metadata/src/link_args.rs +++ /dev/null @@ -1,57 +0,0 @@ -use rustc_hir as hir; -use rustc_hir::itemlikevisit::ItemLikeVisitor; -use rustc_middle::ty::TyCtxt; -use rustc_span::symbol::{sym, Symbol}; -use rustc_target::spec::abi::Abi; - -crate fn collect(tcx: TyCtxt<'_>) -> Vec<String> { - let mut collector = Collector { tcx, args: Vec::new() }; - tcx.hir().krate().visit_all_item_likes(&mut collector); - - for attr in tcx.hir().attrs(hir::CRATE_HIR_ID).iter() { - if attr.has_name(sym::link_args) { - if let Some(linkarg) = attr.value_str() { - collector.add_link_args(linkarg); - } - } - } - - collector.args -} - -struct Collector<'tcx> { - tcx: TyCtxt<'tcx>, - args: Vec<String>, -} - -impl<'tcx> ItemLikeVisitor<'tcx> for Collector<'tcx> { - fn visit_item(&mut self, it: &'tcx hir::Item<'tcx>) { - let abi = match it.kind { - hir::ItemKind::ForeignMod { abi, .. } => abi, - _ => return, - }; - if abi == Abi::Rust || abi == Abi::RustIntrinsic || abi == Abi::PlatformIntrinsic { - return; - } - - // First, add all of the custom #[link_args] attributes - let sess = &self.tcx.sess; - for m in - self.tcx.hir().attrs(it.hir_id()).iter().filter(|a| sess.check_name(a, sym::link_args)) - { - if let Some(linkarg) = m.value_str() { - self.add_link_args(linkarg); - } - } - } - - fn visit_trait_item(&mut self, _it: &'tcx hir::TraitItem<'tcx>) {} - fn visit_impl_item(&mut self, _it: &'tcx hir::ImplItem<'tcx>) {} - fn visit_foreign_item(&mut self, _it: &'tcx hir::ForeignItem<'tcx>) {} -} - -impl<'tcx> Collector<'tcx> { - fn add_link_args(&mut self, args: Symbol) { - self.args.extend(args.as_str().split(' ').filter(|s| !s.is_empty()).map(|s| s.to_string())) - } -} diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index e10041a2971..bebee9dac3b 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -1,6 +1,5 @@ use crate::creader::{CStore, LoadedMacro}; use crate::foreign_modules; -use crate::link_args; use crate::native_libs; use crate::rmeta::{self, encoder}; @@ -295,10 +294,6 @@ pub fn provide(providers: &mut Providers) { foreign_modules::collect(tcx).into_iter().map(|m| (m.def_id, m)).collect(); Lrc::new(modules) }, - link_args: |tcx, cnum| { - assert_eq!(cnum, LOCAL_CRATE); - Lrc::new(link_args::collect(tcx)) - }, // Returns a map from a sufficiently visible external item (i.e., an // external item that is visible from at least one local module) to a diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index bf39b1da8f0..bac69e282a5 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1253,11 +1253,6 @@ rustc_queries! { desc { |tcx| "native_library_kind({})", tcx.def_path_str(def_id) } } - query link_args(_: CrateNum) -> Lrc<Vec<String>> { - eval_always - desc { "looking up link arguments for a crate" } - } - /// Does lifetime resolution, but does not descend into trait items. This /// should only be used for resolving lifetimes of on trait definitions, /// and is used to avoid cycles. Importantly, `resolve_lifetimes` still visits diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index c7d561f760b..b67feb47173 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -822,6 +822,9 @@ pub fn default_configuration(sess: &Session) -> CrateConfig { } } ret.insert((sym::target_arch, Some(Symbol::intern(arch)))); + if sess.target.is_like_wasm { + ret.insert((sym::wasm, None)); + } ret.insert((sym::target_endian, Some(Symbol::intern(end.as_str())))); ret.insert((sym::target_pointer_width, Some(Symbol::intern(&wordsz)))); ret.insert((sym::target_env, Some(Symbol::intern(env)))); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index c5f929ab183..e4810fe7059 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1294,6 +1294,7 @@ symbols! { vreg, vreg_low16, warn, + wasm, wasm_import_module, wasm_target_feature, while_let, diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index 3dd7ce93deb..c050bbc9b9d 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -198,7 +198,7 @@ fn compute_symbol_name( // // [1]: https://bugs.llvm.org/show_bug.cgi?id=44316 if is_foreign - && (tcx.sess.target.arch != "wasm32" + && (!tcx.sess.target.is_like_wasm || !tcx.wasm_import_module_map(def_id.krate).contains_key(&def_id)) { if let Some(name) = attrs.link_name { diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index 2c3f7762759..395235399ea 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -20,6 +20,7 @@ mod sparc; mod sparc64; mod wasm32; mod wasm32_bindgen_compat; +mod wasm64; mod x86; mod x86_64; mod x86_win64; @@ -652,6 +653,7 @@ impl<'a, Ty> FnAbi<'a, Ty> { _ => wasm32_bindgen_compat::compute_abi_info(self), }, "asmjs" => wasm32::compute_abi_info(cx, self), + "wasm64" => wasm64::compute_abi_info(cx, self), a => return Err(format!("unrecognized arch \"{}\" in target specification", a)), } diff --git a/compiler/rustc_target/src/abi/call/wasm64.rs b/compiler/rustc_target/src/abi/call/wasm64.rs new file mode 100644 index 00000000000..46d670d1689 --- /dev/null +++ b/compiler/rustc_target/src/abi/call/wasm64.rs @@ -0,0 +1,58 @@ +use crate::abi::call::{ArgAbi, FnAbi, Uniform}; +use crate::abi::{HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods}; + +fn unwrap_trivial_aggregate<'a, Ty, C>(cx: &C, val: &mut ArgAbi<'a, Ty>) -> bool +where + Ty: TyAndLayoutMethods<'a, C> + Copy, + C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout, +{ + if val.layout.is_aggregate() { + if let Some(unit) = val.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()) { + let size = val.layout.size; + if unit.size == size { + val.cast_to(Uniform { unit, total: size }); + return true; + } + } + } + false +} + +fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>) +where + Ty: TyAndLayoutMethods<'a, C> + Copy, + C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout, +{ + ret.extend_integer_width_to(64); + if ret.layout.is_aggregate() && !unwrap_trivial_aggregate(cx, ret) { + ret.make_indirect(); + } +} + +fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) +where + Ty: TyAndLayoutMethods<'a, C> + Copy, + C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout, +{ + arg.extend_integer_width_to(64); + if arg.layout.is_aggregate() && !unwrap_trivial_aggregate(cx, arg) { + arg.make_indirect_byval(); + } +} + +pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) +where + Ty: TyAndLayoutMethods<'a, C> + Copy, + C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout, +{ + if !fn_abi.ret.is_ignore() { + classify_ret(cx, &mut fn_abi.ret); + } + + for arg in &mut fn_abi.args { + if arg.is_ignore() { + continue; + } + classify_arg(cx, arg); + } +} diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 89052ef390b..801cdd3ebe9 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -79,7 +79,7 @@ mod solaris_base; mod thumb_base; mod uefi_msvc_base; mod vxworks_base; -mod wasm32_base; +mod wasm_base; mod windows_gnu_base; mod windows_msvc_base; mod windows_uwp_gnu_base; @@ -842,6 +842,7 @@ supported_targets! { ("wasm32-unknown-emscripten", wasm32_unknown_emscripten), ("wasm32-unknown-unknown", wasm32_unknown_unknown), ("wasm32-wasi", wasm32_wasi), + ("wasm64-unknown-unknown", wasm64_unknown_unknown), ("thumbv6m-none-eabi", thumbv6m_none_eabi), ("thumbv7m-none-eabi", thumbv7m_none_eabi), @@ -1076,6 +1077,8 @@ pub struct TargetOptions { pub is_like_emscripten: bool, /// Whether the target toolchain is like Fuchsia's. pub is_like_fuchsia: bool, + /// Whether a target toolchain is like WASM. + pub is_like_wasm: bool, /// Version of DWARF to use if not using the default. /// Useful because some platforms (osx, bsd) only want up to DWARF2. pub dwarf_version: Option<u32>, @@ -1295,6 +1298,7 @@ impl Default for TargetOptions { is_like_emscripten: false, is_like_msvc: false, is_like_fuchsia: false, + is_like_wasm: false, dwarf_version: None, linker_is_gnu: false, allows_weak_linkage: true, @@ -1789,6 +1793,7 @@ impl Target { key!(is_like_msvc, bool); key!(is_like_emscripten, bool); key!(is_like_fuchsia, bool); + key!(is_like_wasm, bool); key!(dwarf_version, Option<u32>); key!(linker_is_gnu, bool); key!(allows_weak_linkage, bool); @@ -2027,6 +2032,7 @@ impl ToJson for Target { target_option_val!(is_like_msvc); target_option_val!(is_like_emscripten); target_option_val!(is_like_fuchsia); + target_option_val!(is_like_wasm); target_option_val!(dwarf_version); target_option_val!(linker_is_gnu); target_option_val!(allows_weak_linkage); diff --git a/compiler/rustc_target/src/spec/tests/tests_impl.rs b/compiler/rustc_target/src/spec/tests/tests_impl.rs index 9ec8467e0ac..f4de8bc0a58 100644 --- a/compiler/rustc_target/src/spec/tests/tests_impl.rs +++ b/compiler/rustc_target/src/spec/tests/tests_impl.rs @@ -50,6 +50,7 @@ impl Target { // and you certainly want "unknown" for the OS name. fn can_use_os_unknown(&self) -> bool { self.llvm_target == "wasm32-unknown-unknown" + || self.llvm_target == "wasm64-unknown-unknown" || (self.env == "sgx" && self.vendor == "fortanix") } } diff --git a/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs b/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs index 58d7633fa62..e028dbaa325 100644 --- a/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs +++ b/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs @@ -1,8 +1,8 @@ -use super::wasm32_base; +use super::wasm_base; use super::{LinkArgs, LinkerFlavor, PanicStrategy, Target, TargetOptions}; pub fn target() -> Target { - let mut options = wasm32_base::options(); + let mut options = wasm_base::options(); let clang_args = options.pre_link_args.entry(LinkerFlavor::Gcc).or_default(); diff --git a/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs b/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs index 73a5e16c82b..0a88ee42629 100644 --- a/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs +++ b/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs @@ -10,11 +10,11 @@ //! This target is more or less managed by the Rust and WebAssembly Working //! Group nowadays at <https://github.com/rustwasm>. -use super::wasm32_base; +use super::wasm_base; use super::{LinkerFlavor, LldFlavor, Target}; pub fn target() -> Target { - let mut options = wasm32_base::options(); + let mut options = wasm_base::options(); options.os = "unknown".to_string(); options.linker_flavor = LinkerFlavor::Lld(LldFlavor::Wasm); let clang_args = options.pre_link_args.entry(LinkerFlavor::Gcc).or_default(); diff --git a/compiler/rustc_target/src/spec/wasm32_wasi.rs b/compiler/rustc_target/src/spec/wasm32_wasi.rs index 3f44acdc36b..a6b12d2ee8f 100644 --- a/compiler/rustc_target/src/spec/wasm32_wasi.rs +++ b/compiler/rustc_target/src/spec/wasm32_wasi.rs @@ -72,11 +72,11 @@ //! best we can with this target. Don't start relying on too much here unless //! you know what you're getting in to! -use super::wasm32_base; +use super::wasm_base; use super::{crt_objects, LinkerFlavor, LldFlavor, Target}; pub fn target() -> Target { - let mut options = wasm32_base::options(); + let mut options = wasm_base::options(); options.os = "wasi".to_string(); options.linker_flavor = LinkerFlavor::Lld(LldFlavor::Wasm); diff --git a/compiler/rustc_target/src/spec/wasm64_unknown_unknown.rs b/compiler/rustc_target/src/spec/wasm64_unknown_unknown.rs new file mode 100644 index 00000000000..8bfb229d77f --- /dev/null +++ b/compiler/rustc_target/src/spec/wasm64_unknown_unknown.rs @@ -0,0 +1,39 @@ +//! A "bare wasm" target representing a WebAssembly output that makes zero +//! assumptions about its environment. +//! +//! The `wasm64-unknown-unknown` target is intended to encapsulate use cases +//! that do not rely on any imported functionality. The binaries generated are +//! entirely self-contained by default when using the standard library. Although +//! the standard library is available, most of it returns an error immediately +//! (e.g. trying to create a TCP stream or something like that). + +use super::wasm_base; +use super::{LinkerFlavor, LldFlavor, Target}; + +pub fn target() -> Target { + let mut options = wasm_base::options(); + options.os = "unknown".to_string(); + options.linker_flavor = LinkerFlavor::Lld(LldFlavor::Wasm); + let clang_args = options.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap(); + + // Make sure clang uses LLD as its linker and is configured appropriately + // otherwise + clang_args.push("--target=wasm64-unknown-unknown".to_string()); + + // For now this target just never has an entry symbol no matter the output + // type, so unconditionally pass this. + clang_args.push("-Wl,--no-entry".to_string()); + options + .pre_link_args + .get_mut(&LinkerFlavor::Lld(LldFlavor::Wasm)) + .unwrap() + .push("--no-entry".to_string()); + + Target { + llvm_target: "wasm64-unknown-unknown".to_string(), + pointer_width: 64, + data_layout: "e-m:e-p:64:64-i64:64-n32:64-S128".to_string(), + arch: "wasm64".to_string(), + options, + } +} diff --git a/compiler/rustc_target/src/spec/wasm32_base.rs b/compiler/rustc_target/src/spec/wasm_base.rs index bfef3d37228..c93ad24225a 100644 --- a/compiler/rustc_target/src/spec/wasm32_base.rs +++ b/compiler/rustc_target/src/spec/wasm_base.rs @@ -60,6 +60,8 @@ pub fn options() -> TargetOptions { pre_link_args.insert(LinkerFlavor::Gcc, clang_args); TargetOptions { + is_like_wasm: true, + // we allow dynamic linking, but only cdylibs. Basically we allow a // final library artifact that exports some symbols (a wasm module) but // we don't allow intermediate `dylib` crate types |
