compiler: change Conv to CanonAbi

This commit is contained in:
Jubilee Young 2025-05-21 22:50:21 +02:00
parent 2d637f70a8
commit 72ecde27ff
8 changed files with 64 additions and 65 deletions

View File

@ -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;
}

View File

@ -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}

View File

@ -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;
}

View File

@ -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);
}
_ => {

View File

@ -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;

View File

@ -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() {

View File

@ -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,
}

View File

@ -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 {