mirror of
https://github.com/rust-lang/rust.git
synced 2025-10-03 02:40:40 +00:00
compiler: change Conv to CanonAbi
This commit is contained in:
parent
2d637f70a8
commit
72ecde27ff
@ -1,5 +1,6 @@
|
||||
use std::collections::hash_map::Entry::*;
|
||||
|
||||
use rustc_abi::{CanonAbi, X86Call};
|
||||
use rustc_ast::expand::allocator::{ALLOCATOR_METHODS, NO_ALLOC_SHIM_IS_UNSTABLE, global_fn_name};
|
||||
use rustc_data_structures::unord::UnordMap;
|
||||
use rustc_hir::def::DefKind;
|
||||
@ -14,7 +15,6 @@ use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, Instance, SymbolNam
|
||||
use rustc_middle::util::Providers;
|
||||
use rustc_session::config::{CrateType, OomStrategy};
|
||||
use rustc_symbol_mangling::mangle_internal_symbol;
|
||||
use rustc_target::callconv::Conv;
|
||||
use rustc_target::spec::{SanitizerSet, TlsModel};
|
||||
use tracing::debug;
|
||||
|
||||
@ -652,7 +652,7 @@ pub(crate) fn symbol_name_for_instance_in_crate<'tcx>(
|
||||
fn calling_convention_for_symbol<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
symbol: ExportedSymbol<'tcx>,
|
||||
) -> (Conv, &'tcx [rustc_target::callconv::ArgAbi<'tcx, Ty<'tcx>>]) {
|
||||
) -> (CanonAbi, &'tcx [rustc_target::callconv::ArgAbi<'tcx, Ty<'tcx>>]) {
|
||||
let instance = match symbol {
|
||||
ExportedSymbol::NonGeneric(def_id) | ExportedSymbol::Generic(def_id, _)
|
||||
if tcx.is_static(def_id) =>
|
||||
@ -683,7 +683,7 @@ fn calling_convention_for_symbol<'tcx>(
|
||||
})
|
||||
.map(|fnabi| (fnabi.conv, &fnabi.args[..]))
|
||||
// FIXME(workingjubilee): why don't we know the convention here?
|
||||
.unwrap_or((Conv::Rust, &[]))
|
||||
.unwrap_or((CanonAbi::Rust, &[]))
|
||||
}
|
||||
|
||||
/// This is the symbol name of the given instance as seen by the linker.
|
||||
@ -717,14 +717,14 @@ pub(crate) fn linking_symbol_name_for_instance_in_crate<'tcx>(
|
||||
_ => return undecorated,
|
||||
};
|
||||
|
||||
let (conv, args) = calling_convention_for_symbol(tcx, symbol);
|
||||
let (callconv, args) = calling_convention_for_symbol(tcx, symbol);
|
||||
|
||||
// Decorate symbols with prefixes, suffixes and total number of bytes of arguments.
|
||||
// Reference: https://docs.microsoft.com/en-us/cpp/build/reference/decorated-names?view=msvc-170
|
||||
let (prefix, suffix) = match conv {
|
||||
Conv::X86Fastcall => ("@", "@"),
|
||||
Conv::X86Stdcall => ("_", "@"),
|
||||
Conv::X86VectorCall => ("", "@@"),
|
||||
let (prefix, suffix) = match callconv {
|
||||
CanonAbi::X86(X86Call::Fastcall) => ("@", "@"),
|
||||
CanonAbi::X86(X86Call::Stdcall) => ("_", "@"),
|
||||
CanonAbi::X86(X86Call::Vectorcall) => ("", "@@"),
|
||||
_ => {
|
||||
if let Some(prefix) = prefix {
|
||||
undecorated.insert(0, prefix);
|
||||
@ -758,9 +758,9 @@ pub(crate) fn extend_exported_symbols<'tcx>(
|
||||
symbol: ExportedSymbol<'tcx>,
|
||||
instantiating_crate: CrateNum,
|
||||
) {
|
||||
let (conv, _) = calling_convention_for_symbol(tcx, symbol);
|
||||
let (callconv, _) = calling_convention_for_symbol(tcx, symbol);
|
||||
|
||||
if conv != Conv::GpuKernel || tcx.sess.target.os != "amdhsa" {
|
||||
if callconv != CanonAbi::GpuKernel || tcx.sess.target.os != "amdhsa" {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -118,7 +118,7 @@ const_eval_frame_note_inner = inside {$where_ ->
|
||||
const_eval_frame_note_last = the failure occurred here
|
||||
|
||||
const_eval_incompatible_calling_conventions =
|
||||
calling a function with calling convention {$callee_conv} using calling convention {$caller_conv}
|
||||
calling a function with calling convention "{$callee_conv}" using calling convention "{$caller_conv}"
|
||||
|
||||
const_eval_incompatible_return_types =
|
||||
calling a function with return type {$callee_ty} passing return place of type {$caller_ty}
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! This module ensures that if a function's ABI requires a particular target feature,
|
||||
//! that target feature is enabled both on the callee and all callers.
|
||||
use rustc_abi::{BackendRepr, RegKind};
|
||||
use rustc_abi::{BackendRepr, CanonAbi, RegKind, X86Call};
|
||||
use rustc_hir::{CRATE_HIR_ID, HirId};
|
||||
use rustc_middle::mir::{self, Location, traversal};
|
||||
use rustc_middle::ty::layout::LayoutCx;
|
||||
@ -8,7 +8,7 @@ use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TyCtxt, TypingEnv};
|
||||
use rustc_session::lint::builtin::WASM_C_ABI;
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::{DUMMY_SP, Span, Symbol, sym};
|
||||
use rustc_target::callconv::{ArgAbi, Conv, FnAbi, PassMode};
|
||||
use rustc_target::callconv::{ArgAbi, FnAbi, PassMode};
|
||||
use rustc_target::spec::{HasWasmCAbiOpt, WasmCAbi};
|
||||
|
||||
use crate::errors;
|
||||
@ -72,7 +72,7 @@ fn do_check_simd_vector_abi<'tcx>(
|
||||
}
|
||||
}
|
||||
// The `vectorcall` ABI is special in that it requires SSE2 no matter which types are being passed.
|
||||
if abi.conv == Conv::X86VectorCall && !have_feature(sym::sse2) {
|
||||
if abi.conv == CanonAbi::X86(X86Call::Vectorcall) && !have_feature(sym::sse2) {
|
||||
let (span, _hir_id) = loc();
|
||||
tcx.dcx().emit_err(errors::AbiRequiredTargetFeature {
|
||||
span,
|
||||
@ -128,7 +128,7 @@ fn do_check_wasm_abi<'tcx>(
|
||||
if !(tcx.sess.target.arch == "wasm32"
|
||||
&& tcx.sess.target.os == "unknown"
|
||||
&& tcx.wasm_c_abi_opt() == WasmCAbi::Legacy { with_lint: true }
|
||||
&& abi.conv == Conv::C)
|
||||
&& abi.conv == CanonAbi::C)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -4,10 +4,11 @@
|
||||
//! For more information about LLVM CFI and cross-language LLVM CFI support for the Rust compiler,
|
||||
//! see design document in the tracking issue #89653.
|
||||
|
||||
use rustc_abi::CanonAbi;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
|
||||
use rustc_target::callconv::{Conv, FnAbi, PassMode};
|
||||
use rustc_target::callconv::{FnAbi, PassMode};
|
||||
use tracing::instrument;
|
||||
|
||||
mod encode;
|
||||
@ -45,7 +46,7 @@ pub fn typeid_for_fnabi<'tcx>(
|
||||
let mut encode_ty_options = EncodeTyOptions::from_bits(options.bits())
|
||||
.unwrap_or_else(|| bug!("typeid_for_fnabi: invalid option(s) `{:?}`", options.bits()));
|
||||
match fn_abi.conv {
|
||||
Conv::C => {
|
||||
CanonAbi::C => {
|
||||
encode_ty_options.insert(EncodeTyOptions::GENERALIZE_REPR_C);
|
||||
}
|
||||
_ => {
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#![allow(rustc::usage_of_qualified_ty)]
|
||||
|
||||
use rustc_abi::{ArmCall, CanonAbi, InterruptKind, X86Call};
|
||||
use rustc_middle::ty;
|
||||
use rustc_target::callconv::{self, Conv};
|
||||
use stable_mir::abi::{
|
||||
@ -69,7 +70,7 @@ impl<'tcx> Stable<'tcx> for callconv::FnAbi<'tcx, ty::Ty<'tcx>> {
|
||||
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
assert!(self.args.len() >= self.fixed_count as usize);
|
||||
assert!(!self.c_variadic || matches!(self.conv, Conv::C));
|
||||
assert!(!self.c_variadic || matches!(self.conv, CanonAbi::C));
|
||||
FnAbi {
|
||||
args: self.args.as_ref().stable(tables),
|
||||
ret: self.ret.stable(tables),
|
||||
@ -121,6 +122,41 @@ impl<'tcx> Stable<'tcx> for callconv::Conv {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for CanonAbi {
|
||||
type T = CallConvention;
|
||||
|
||||
fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
|
||||
match self {
|
||||
CanonAbi::C => CallConvention::C,
|
||||
CanonAbi::Rust => CallConvention::Rust,
|
||||
CanonAbi::RustCold => CallConvention::Cold,
|
||||
CanonAbi::Arm(arm_call) => match arm_call {
|
||||
ArmCall::Aapcs => CallConvention::ArmAapcs,
|
||||
ArmCall::CCmseNonSecureCall => CallConvention::CCmseNonSecureCall,
|
||||
ArmCall::CCmseNonSecureEntry => CallConvention::CCmseNonSecureEntry,
|
||||
},
|
||||
CanonAbi::GpuKernel => CallConvention::GpuKernel,
|
||||
CanonAbi::Interrupt(interrupt_kind) => match interrupt_kind {
|
||||
InterruptKind::Avr => CallConvention::AvrInterrupt,
|
||||
InterruptKind::AvrNonBlocking => CallConvention::AvrNonBlockingInterrupt,
|
||||
InterruptKind::Msp430 => CallConvention::Msp430Intr,
|
||||
InterruptKind::RiscvMachine | InterruptKind::RiscvSupervisor => {
|
||||
CallConvention::RiscvInterrupt
|
||||
}
|
||||
InterruptKind::X86 => CallConvention::X86Intr,
|
||||
},
|
||||
CanonAbi::X86(x86_call) => match x86_call {
|
||||
X86Call::Fastcall => CallConvention::X86Fastcall,
|
||||
X86Call::Stdcall => CallConvention::X86Stdcall,
|
||||
X86Call::SysV64 => CallConvention::X86_64SysV,
|
||||
X86Call::Thiscall => CallConvention::X86ThisCall,
|
||||
X86Call::Vectorcall => CallConvention::X86VectorCall,
|
||||
X86Call::Win64 => CallConvention::X86_64Win64,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for callconv::PassMode {
|
||||
type T = PassMode;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
use rustc_abi::{HasDataLayout, TyAbiInterface};
|
||||
use rustc_abi::{ArmCall, CanonAbi, HasDataLayout, TyAbiInterface};
|
||||
|
||||
use crate::callconv::{ArgAbi, Conv, FnAbi, Reg, RegKind, Uniform};
|
||||
use crate::callconv::{ArgAbi, FnAbi, Reg, RegKind, Uniform};
|
||||
use crate::spec::HasTargetSpec;
|
||||
|
||||
fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) -> Option<Uniform>
|
||||
@ -90,7 +90,7 @@ where
|
||||
// If this is a target with a hard-float ABI, and the function is not explicitly
|
||||
// `extern "aapcs"`, then we must use the VFP registers for homogeneous aggregates.
|
||||
let vfp = cx.target_spec().llvm_target.ends_with("hf")
|
||||
&& fn_abi.conv != Conv::ArmAapcs
|
||||
&& fn_abi.conv != CanonAbi::Arm(ArmCall::Aapcs)
|
||||
&& !fn_abi.c_variadic;
|
||||
|
||||
if !fn_abi.ret.is_ignore() {
|
||||
|
@ -3,8 +3,8 @@ use std::str::FromStr;
|
||||
use std::{fmt, iter};
|
||||
|
||||
use rustc_abi::{
|
||||
AddressSpace, Align, BackendRepr, ExternAbi, HasDataLayout, Primitive, Reg, RegKind, Scalar,
|
||||
Size, TyAbiInterface, TyAndLayout,
|
||||
AddressSpace, Align, BackendRepr, CanonAbi, ExternAbi, HasDataLayout, Primitive, Reg, RegKind,
|
||||
Scalar, Size, TyAbiInterface, TyAndLayout,
|
||||
};
|
||||
use rustc_macros::HashStable_Generic;
|
||||
|
||||
@ -606,7 +606,7 @@ pub struct FnAbi<'a, Ty> {
|
||||
/// This can be used to know whether an argument is variadic or not.
|
||||
pub fixed_count: u32,
|
||||
/// The calling convention of this function.
|
||||
pub conv: Conv,
|
||||
pub conv: CanonAbi,
|
||||
/// Indicates if an unwind may happen across a call to this function.
|
||||
pub can_unwind: bool,
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ use rustc_middle::ty::{self, InstanceKind, Ty, TyCtxt};
|
||||
use rustc_session::config::OptLevel;
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_target::callconv::{
|
||||
ArgAbi, ArgAttribute, ArgAttributes, ArgExtension, Conv, FnAbi, PassMode, RiscvInterruptKind,
|
||||
AbiMap, ArgAbi, ArgAttribute, ArgAttributes, ArgExtension, FnAbi, PassMode,
|
||||
};
|
||||
use tracing::debug;
|
||||
|
||||
@ -240,45 +240,6 @@ fn fn_sig_for_fn_abi<'tcx>(
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: ExternAbi, c_variadic: bool) -> Conv {
|
||||
use rustc_abi::ExternAbi::*;
|
||||
match tcx.sess.target.adjust_abi(abi, c_variadic) {
|
||||
Rust | RustCall => Conv::Rust,
|
||||
|
||||
// This is intentionally not using `Conv::Cold`, as that has to preserve
|
||||
// even SIMD registers, which is generally not a good trade-off.
|
||||
RustCold => Conv::PreserveMost,
|
||||
|
||||
// It's the ABI's job to select this, not ours.
|
||||
System { .. } => bug!("system abi should be selected elsewhere"),
|
||||
EfiApi => bug!("eficall abi should be selected elsewhere"),
|
||||
|
||||
Stdcall { .. } => Conv::X86Stdcall,
|
||||
Fastcall { .. } => Conv::X86Fastcall,
|
||||
Vectorcall { .. } => Conv::X86VectorCall,
|
||||
Thiscall { .. } => Conv::X86ThisCall,
|
||||
C { .. } => Conv::C,
|
||||
Unadjusted => Conv::C,
|
||||
Win64 { .. } => Conv::X86_64Win64,
|
||||
SysV64 { .. } => Conv::X86_64SysV,
|
||||
Aapcs { .. } => Conv::ArmAapcs,
|
||||
CCmseNonSecureCall => Conv::CCmseNonSecureCall,
|
||||
CCmseNonSecureEntry => Conv::CCmseNonSecureEntry,
|
||||
PtxKernel => Conv::GpuKernel,
|
||||
Msp430Interrupt => Conv::Msp430Intr,
|
||||
X86Interrupt => Conv::X86Intr,
|
||||
GpuKernel => Conv::GpuKernel,
|
||||
AvrInterrupt => Conv::AvrInterrupt,
|
||||
AvrNonBlockingInterrupt => Conv::AvrNonBlockingInterrupt,
|
||||
RiscvInterruptM => Conv::RiscvInterrupt { kind: RiscvInterruptKind::Machine },
|
||||
RiscvInterruptS => Conv::RiscvInterrupt { kind: RiscvInterruptKind::Supervisor },
|
||||
|
||||
// These API constants ought to be more specific...
|
||||
Cdecl { .. } => Conv::C,
|
||||
}
|
||||
}
|
||||
|
||||
fn fn_abi_of_fn_ptr<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
query: ty::PseudoCanonicalInput<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>)>,
|
||||
@ -529,7 +490,8 @@ fn fn_abi_new_uncached<'tcx>(
|
||||
};
|
||||
let sig = tcx.normalize_erasing_regions(cx.typing_env, sig);
|
||||
|
||||
let conv = conv_from_spec_abi(cx.tcx(), sig.abi, sig.c_variadic);
|
||||
let abi_map = AbiMap::from_target(&tcx.sess.target);
|
||||
let conv = abi_map.canonize_abi(sig.abi, sig.c_variadic).unwrap();
|
||||
|
||||
let mut inputs = sig.inputs();
|
||||
let extra_args = if sig.abi == ExternAbi::RustCall {
|
||||
|
Loading…
x
Reference in New Issue
Block a user