Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 5 pull requests #83979

Closed
wants to merge 15 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions compiler/rustc_ast_passes/src/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,14 @@ impl<'a> PostExpansionVisitor<'a> {
"thiscall-unwind ABI is experimental and subject to change"
);
}
"wasm" => {
gate_feature_post!(
&self,
wasm_abi,
span,
"wasm ABI is experimental and subject to change"
);
}
abi => self
.sess
.parse_sess
Expand Down
44 changes: 28 additions & 16 deletions compiler/rustc_codegen_llvm/src/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, TyCtxt};
use rustc_session::config::OptLevel;
use rustc_session::Session;
use rustc_target::spec::abi::Abi;
use rustc_target::spec::{SanitizerSet, StackProbeType};

use crate::attributes;
Expand Down Expand Up @@ -293,7 +294,7 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value, instance: ty::
// The target doesn't care; the subtarget reads our attribute.
apply_tune_cpu_attr(cx, llfn);

let function_features = codegen_fn_attrs
let mut function_features = codegen_fn_attrs
.target_features
.iter()
.map(|f| {
Expand All @@ -305,23 +306,10 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value, instance: ty::
InstructionSetAttr::ArmT32 => "+thumb-mode".to_string(),
}))
.collect::<Vec<String>>();
if !function_features.is_empty() {
let mut global_features = llvm_util::llvm_global_features(cx.tcx.sess);
global_features.extend(function_features.into_iter());
let features = global_features.join(",");
let val = CString::new(features).unwrap();
llvm::AddFunctionAttrStringValue(
llfn,
llvm::AttributePlace::Function,
cstr!("target-features"),
&val,
);
}

// 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.is_like_wasm {
// If this function is an import from the environment but the wasm
// import has a specific module/name, apply them here.
if let Some(module) = wasm_import_module(cx.tcx, instance.def_id()) {
llvm::AddFunctionAttrStringValue(
llfn,
Expand All @@ -340,6 +328,30 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value, instance: ty::
&name,
);
}

// The `"wasm"` abi on wasm targets automatically enables the
// `+multivalue` feature because the purpose of the wasm abi is to match
// the WebAssembly specification, which has this feature. This won't be
// needed when LLVM enables this `multivalue` feature by default.
if !cx.tcx.is_closure(instance.def_id()) {
let abi = cx.tcx.fn_sig(instance.def_id()).abi();
if abi == Abi::Wasm {
function_features.push("+multivalue".to_string());
}
}
}

if !function_features.is_empty() {
let mut global_features = llvm_util::llvm_global_features(cx.tcx.sess);
global_features.extend(function_features.into_iter());
let features = global_features.join(",");
let val = CString::new(features).unwrap();
llvm::AddFunctionAttrStringValue(
llfn,
llvm::AttributePlace::Function,
cstr!("target-features"),
&val,
);
}
}

Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_feature/src/active.rs
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,9 @@ declare_features! (
/// Allows using `#[repr(align(...))]` on function items
(active, fn_align, "1.53.0", Some(82232), None),

/// Allows `extern "wasm" fn`
(active, wasm_abi, "1.53.0", Some(83788), None),

// -------------------------------------------------------------------------
// feature-group-end: actual feature gates
// -------------------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir/src/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ where
}
}

#[derive(Copy, Clone)]
#[derive(Copy, Clone, Debug)]
pub enum FnKind<'a> {
/// `#[xxx] pub async/const/extern "Abi" fn foo()`
ItemFn(Ident, &'a Generics<'a>, FnHeader, &'a Visibility<'a>),
Expand Down
14 changes: 7 additions & 7 deletions compiler/rustc_interface/src/callbacks.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Throughout the compiler tree, there are several places which want to have
//! access to state or queries while being inside crates that are dependencies
//! of librustc_middle. To facilitate this, we have the
//! of `rustc_middle`. To facilitate this, we have the
//! `rustc_data_structures::AtomicRef` type, which allows us to setup a global
//! static which can then be set in this file at program startup.
//!
Expand All @@ -13,8 +13,8 @@ use rustc_errors::{Diagnostic, TRACK_DIAGNOSTICS};
use rustc_middle::ty::tls;
use std::fmt;

/// This is a callback from librustc_ast as it cannot access the implicit state
/// in librustc_middle otherwise.
/// This is a callback from `rustc_ast` as it cannot access the implicit state
/// in `rustc_middle` otherwise.
fn span_debug(span: rustc_span::Span, f: &mut fmt::Formatter<'_>) -> fmt::Result {
tls::with_opt(|tcx| {
if let Some(tcx) = tcx {
Expand All @@ -25,8 +25,8 @@ fn span_debug(span: rustc_span::Span, f: &mut fmt::Formatter<'_>) -> fmt::Result
})
}

/// This is a callback from librustc_ast as it cannot access the implicit state
/// in librustc_middle otherwise. It is used to when diagnostic messages are
/// This is a callback from `rustc_ast` as it cannot access the implicit state
/// in `rustc_middle` otherwise. It is used to when diagnostic messages are
/// emitted and stores them in the current query, if there is one.
fn track_diagnostic(diagnostic: &Diagnostic) {
tls::with_context_opt(|icx| {
Expand All @@ -39,8 +39,8 @@ fn track_diagnostic(diagnostic: &Diagnostic) {
})
}

/// This is a callback from librustc_hir as it cannot access the implicit state
/// in librustc_middle otherwise.
/// This is a callback from `rustc_hir` as it cannot access the implicit state
/// in `rustc_middle` otherwise.
fn def_id_debug(def_id: rustc_hir::def_id::DefId, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "DefId({}:{}", def_id.krate, def_id.index.index())?;
tls::with_opt(|opt_tcx| {
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_middle/src/ty/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2630,6 +2630,7 @@ fn fn_can_unwind(
| AvrInterrupt
| AvrNonBlockingInterrupt
| CCmseNonSecureCall
| Wasm
| RustIntrinsic
| PlatformIntrinsic
| Unadjusted => false,
Expand Down Expand Up @@ -2712,6 +2713,7 @@ where
AmdGpuKernel => Conv::AmdGpuKernel,
AvrInterrupt => Conv::AvrInterrupt,
AvrNonBlockingInterrupt => Conv::AvrNonBlockingInterrupt,
Wasm => Conv::C,

// These API constants ought to be more specific...
Cdecl => Conv::C,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_mir_build/src/build/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,7 @@ fn should_abort_on_panic(tcx: TyCtxt<'_>, fn_def_id: LocalDefId, abi: Abi) -> bo
| AvrInterrupt
| AvrNonBlockingInterrupt
| CCmseNonSecureCall
| Wasm
| RustIntrinsic
| PlatformIntrinsic
| Unadjusted => true,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1296,6 +1296,7 @@ symbols! {
vreg_low16,
warn,
wasm,
wasm_abi,
wasm_import_module,
wasm_target_feature,
while_let,
Expand Down
18 changes: 9 additions & 9 deletions compiler/rustc_target/src/abi/call/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ mod riscv;
mod s390x;
mod sparc;
mod sparc64;
mod wasm32;
mod wasm32_bindgen_compat;
mod wasm64;
mod wasm;
mod x86;
mod x86_64;
mod x86_win64;
Expand Down Expand Up @@ -648,12 +646,14 @@ impl<'a, Ty> FnAbi<'a, Ty> {
"nvptx64" => nvptx64::compute_abi_info(self),
"hexagon" => hexagon::compute_abi_info(self),
"riscv32" | "riscv64" => riscv::compute_abi_info(cx, self),
"wasm32" => match cx.target_spec().os.as_str() {
"emscripten" | "wasi" => wasm32::compute_abi_info(cx, self),
_ => wasm32_bindgen_compat::compute_abi_info(self),
},
"asmjs" => wasm32::compute_abi_info(cx, self),
"wasm64" => wasm64::compute_abi_info(cx, self),
"wasm32" | "wasm64" => {
if cx.target_spec().adjust_abi(abi) == spec::abi::Abi::Wasm {
wasm::compute_wasm_abi_info(self)
} else {
wasm::compute_c_abi_info(cx, self)
}
}
"asmjs" => wasm::compute_c_abi_info(cx, self),
a => return Err(format!("unrecognized arch \"{}\" in target specification", a)),
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ where
}
}

pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
/// The purpose of this ABI is to match the C ABI (aka clang) exactly.
pub fn compute_c_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,
Expand All @@ -56,3 +57,27 @@ where
classify_arg(cx, arg);
}
}

/// The purpose of this ABI is for matching the WebAssembly standard. This
/// intentionally diverges from the C ABI and is specifically crafted to take
/// advantage of LLVM's support of multiple returns in WebAssembly.
pub fn compute_wasm_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
if !fn_abi.ret.is_ignore() {
classify_ret(&mut fn_abi.ret);
}

for arg in &mut fn_abi.args {
if arg.is_ignore() {
continue;
}
classify_arg(arg);
}

fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
ret.extend_integer_width_to(32);
}

fn classify_arg<Ty>(arg: &mut ArgAbi<'_, Ty>) {
arg.extend_integer_width_to(32);
}
}
29 changes: 0 additions & 29 deletions compiler/rustc_target/src/abi/call/wasm32_bindgen_compat.rs

This file was deleted.

58 changes: 0 additions & 58 deletions compiler/rustc_target/src/abi/call/wasm64.rs

This file was deleted.

15 changes: 9 additions & 6 deletions compiler/rustc_target/src/spec/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ pub enum Abi {
AvrInterrupt,
AvrNonBlockingInterrupt,
CCmseNonSecureCall,
Wasm,

// Multiplatform / generic ABIs
System { unwind: bool },
Expand Down Expand Up @@ -83,6 +84,7 @@ const AbiDatas: &[AbiData] = &[
generic: false,
},
AbiData { abi: Abi::CCmseNonSecureCall, name: "C-cmse-nonsecure-call", generic: false },
AbiData { abi: Abi::Wasm, name: "wasm", generic: false },
// Cross-platform ABIs
AbiData { abi: Abi::System { unwind: false }, name: "system", generic: true },
AbiData { abi: Abi::System { unwind: true }, name: "system-unwind", generic: true },
Expand Down Expand Up @@ -131,13 +133,14 @@ impl Abi {
AvrInterrupt => 18,
AvrNonBlockingInterrupt => 19,
CCmseNonSecureCall => 20,
Wasm => 21,
// Cross-platform ABIs
System { unwind: false } => 21,
System { unwind: true } => 22,
RustIntrinsic => 23,
RustCall => 24,
PlatformIntrinsic => 25,
Unadjusted => 26,
System { unwind: false } => 22,
System { unwind: true } => 23,
RustIntrinsic => 24,
RustCall => 25,
PlatformIntrinsic => 26,
Unadjusted => 27,
};
debug_assert!(
AbiDatas
Expand Down
Loading