Auto merge of #88337 - eddyb:field-failure-is-not-an-option, r=nagisa
rustc_target: `TyAndLayout::field` should never error. This refactor (making `TyAndLayout::field` return `TyAndLayout` without any `Result` around it) is based on a simple observation, regarding `TyAndLayout::field`: If `cx.layout_of(ty)` succeeds (for some `cx` and `ty`), then `.field(cx, i)` on the resulting `TyAndLayout` should *always* succeed in computing `cx.layout_of(field_ty)` (where `field_ty` is the type of the `i`th field of `ty`). The reason for this is that no matter which field is chosen, `cx.layout_of(field_ty)` *will have already been computed*, as part of computing `cx.layout_of(ty)`, as we cannot determine the layout of *any* type without considering the layouts of *all* of its fields. And so it should be fine to turn any errors into ICEs, since they likely indicate a `cx` mismatch, or some other edge case that is due to a compiler bug (as opposed to ever being an user-facing error). <hr/> Each commit should probably be reviewed separately, though note that there's some `where` clauses (in `rustc_target::abi::call::*`) that change in most commits. cc `@nagisa` `@oli-obk`
This commit is contained in:
commit
9556d7a09a
32 changed files with 308 additions and 271 deletions
|
@ -1,10 +1,10 @@
|
|||
use crate::abi::call::{ArgAbi, FnAbi, Reg, RegKind, Uniform};
|
||||
use crate::abi::{HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods};
|
||||
use crate::abi::{HasDataLayout, TyAbiInterface};
|
||||
|
||||
fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) -> Option<Uniform>
|
||||
where
|
||||
Ty: TyAndLayoutMethods<'a, C> + Copy,
|
||||
C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
arg.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()).and_then(|unit| {
|
||||
let size = arg.layout.size;
|
||||
|
@ -26,8 +26,8 @@ where
|
|||
|
||||
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,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
if !ret.layout.is_aggregate() {
|
||||
ret.extend_integer_width_to(32);
|
||||
|
@ -48,8 +48,8 @@ where
|
|||
|
||||
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,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
if !arg.layout.is_aggregate() {
|
||||
arg.extend_integer_width_to(32);
|
||||
|
@ -70,8 +70,8 @@ where
|
|||
|
||||
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,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
if !fn_abi.ret.is_ignore() {
|
||||
classify_ret(cx, &mut fn_abi.ret);
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
use crate::abi::call::{ArgAbi, FnAbi};
|
||||
use crate::abi::{HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods};
|
||||
use crate::abi::{HasDataLayout, TyAbiInterface};
|
||||
|
||||
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,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
ret.extend_integer_width_to(32);
|
||||
}
|
||||
|
||||
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,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
arg.extend_integer_width_to(32);
|
||||
}
|
||||
|
||||
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,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
if !fn_abi.ret.is_ignore() {
|
||||
classify_ret(cx, &mut fn_abi.ret);
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
use crate::abi::call::{ArgAbi, Conv, FnAbi, Reg, RegKind, Uniform};
|
||||
use crate::abi::{HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods};
|
||||
use crate::abi::{HasDataLayout, TyAbiInterface};
|
||||
use crate::spec::HasTargetSpec;
|
||||
|
||||
fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) -> Option<Uniform>
|
||||
where
|
||||
Ty: TyAndLayoutMethods<'a, C> + Copy,
|
||||
C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
arg.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()).and_then(|unit| {
|
||||
let size = arg.layout.size;
|
||||
|
@ -27,8 +27,8 @@ where
|
|||
|
||||
fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>, vfp: bool)
|
||||
where
|
||||
Ty: TyAndLayoutMethods<'a, C> + Copy,
|
||||
C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
if !ret.layout.is_aggregate() {
|
||||
ret.extend_integer_width_to(32);
|
||||
|
@ -53,8 +53,8 @@ where
|
|||
|
||||
fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>, vfp: bool)
|
||||
where
|
||||
Ty: TyAndLayoutMethods<'a, C> + Copy,
|
||||
C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
if !arg.layout.is_aggregate() {
|
||||
arg.extend_integer_width_to(32);
|
||||
|
@ -75,8 +75,8 @@ where
|
|||
|
||||
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 + HasTargetSpec,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout + HasTargetSpec,
|
||||
{
|
||||
// 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.
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
use crate::abi::call::{ArgAbi, FnAbi, Reg, Uniform};
|
||||
use crate::abi::{HasDataLayout, LayoutOf, Size, TyAndLayoutMethods};
|
||||
use crate::abi::{HasDataLayout, Size};
|
||||
|
||||
fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'_, Ty>, offset: &mut Size)
|
||||
fn classify_ret<Ty, C>(cx: &C, ret: &mut ArgAbi<'_, Ty>, offset: &mut Size)
|
||||
where
|
||||
Ty: TyAndLayoutMethods<'a, C>,
|
||||
C: LayoutOf<Ty = Ty> + HasDataLayout,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
if !ret.layout.is_aggregate() {
|
||||
ret.extend_integer_width_to(32);
|
||||
|
@ -14,10 +13,9 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'_, Ty>, offset: &mut Size)
|
||||
fn classify_arg<Ty, C>(cx: &C, arg: &mut ArgAbi<'_, Ty>, offset: &mut Size)
|
||||
where
|
||||
Ty: TyAndLayoutMethods<'a, C>,
|
||||
C: LayoutOf<Ty = Ty> + HasDataLayout,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
let dl = cx.data_layout();
|
||||
let size = arg.layout.size;
|
||||
|
@ -35,10 +33,9 @@ where
|
|||
*offset = offset.align_to(align) + size.align_to(align);
|
||||
}
|
||||
|
||||
pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'_, Ty>)
|
||||
pub fn compute_abi_info<Ty, C>(cx: &C, fn_abi: &mut FnAbi<'_, Ty>)
|
||||
where
|
||||
Ty: TyAndLayoutMethods<'a, C>,
|
||||
C: LayoutOf<Ty = Ty> + HasDataLayout,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
let mut offset = Size::ZERO;
|
||||
if !fn_abi.ret.is_ignore() {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::abi::call::{ArgAbi, ArgExtension, CastTarget, FnAbi, PassMode, Reg, RegKind, Uniform};
|
||||
use crate::abi::{self, HasDataLayout, LayoutOf, Size, TyAndLayout, TyAndLayoutMethods};
|
||||
use crate::abi::{self, HasDataLayout, Size, TyAbiInterface};
|
||||
|
||||
fn extend_integer_width_mips<Ty>(arg: &mut ArgAbi<'_, Ty>, bits: u64) {
|
||||
// Always sign extend u32 values on 64-bit mips
|
||||
|
@ -19,8 +19,8 @@ fn extend_integer_width_mips<Ty>(arg: &mut ArgAbi<'_, Ty>, bits: u64) {
|
|||
|
||||
fn float_reg<'a, Ty, C>(cx: &C, ret: &ArgAbi<'a, Ty>, i: usize) -> Option<Reg>
|
||||
where
|
||||
Ty: TyAndLayoutMethods<'a, C> + Copy,
|
||||
C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
match ret.layout.field(cx, i).abi {
|
||||
abi::Abi::Scalar(ref scalar) => match scalar.value {
|
||||
|
@ -34,8 +34,8 @@ where
|
|||
|
||||
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,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
if !ret.layout.is_aggregate() {
|
||||
extend_integer_width_mips(ret, 64);
|
||||
|
@ -74,8 +74,8 @@ where
|
|||
|
||||
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,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
if !arg.layout.is_aggregate() {
|
||||
extend_integer_width_mips(arg, 64);
|
||||
|
@ -144,8 +144,8 @@ where
|
|||
|
||||
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,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
if !fn_abi.ret.is_ignore() {
|
||||
classify_ret(cx, &mut fn_abi.ret);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::abi::{self, Abi, Align, FieldsShape, Size};
|
||||
use crate::abi::{HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods};
|
||||
use crate::abi::{HasDataLayout, TyAbiInterface, TyAndLayout};
|
||||
use crate::spec::{self, HasTargetSpec};
|
||||
|
||||
mod aarch64;
|
||||
|
@ -316,8 +316,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
|
|||
/// specific targets.
|
||||
pub fn homogeneous_aggregate<C>(&self, cx: &C) -> Result<HomogeneousAggregate, Heterogeneous>
|
||||
where
|
||||
Ty: TyAndLayoutMethods<'a, C> + Copy,
|
||||
C: LayoutOf<Ty = Ty, TyAndLayout = Self>,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
{
|
||||
match self.abi {
|
||||
Abi::Uninhabited => Err(Heterogeneous),
|
||||
|
@ -603,8 +602,8 @@ pub struct FnAbi<'a, Ty> {
|
|||
impl<'a, Ty> FnAbi<'a, Ty> {
|
||||
pub fn adjust_for_cabi<C>(&mut self, cx: &C, abi: spec::abi::Abi) -> Result<(), String>
|
||||
where
|
||||
Ty: TyAndLayoutMethods<'a, C> + Copy,
|
||||
C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout + HasTargetSpec,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout + HasTargetSpec,
|
||||
{
|
||||
if abi == spec::abi::Abi::X86Interrupt {
|
||||
if let Some(arg) = self.args.first_mut() {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
// need to be fixed when PowerPC vector support is added.
|
||||
|
||||
use crate::abi::call::{ArgAbi, FnAbi, Reg, RegKind, Uniform};
|
||||
use crate::abi::{Endian, HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods};
|
||||
use crate::abi::{Endian, HasDataLayout, TyAbiInterface};
|
||||
use crate::spec::HasTargetSpec;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
|
@ -19,8 +19,8 @@ fn is_homogeneous_aggregate<'a, Ty, C>(
|
|||
abi: ABI,
|
||||
) -> Option<Uniform>
|
||||
where
|
||||
Ty: TyAndLayoutMethods<'a, C> + Copy,
|
||||
C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
arg.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()).and_then(|unit| {
|
||||
// ELFv1 only passes one-member aggregates transparently.
|
||||
|
@ -43,8 +43,8 @@ where
|
|||
|
||||
fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>, abi: ABI)
|
||||
where
|
||||
Ty: TyAndLayoutMethods<'a, C> + Copy,
|
||||
C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
if !ret.layout.is_aggregate() {
|
||||
ret.extend_integer_width_to(64);
|
||||
|
@ -86,8 +86,8 @@ where
|
|||
|
||||
fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>, abi: ABI)
|
||||
where
|
||||
Ty: TyAndLayoutMethods<'a, C> + Copy,
|
||||
C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
if !arg.layout.is_aggregate() {
|
||||
arg.extend_integer_width_to(64);
|
||||
|
@ -116,8 +116,8 @@ where
|
|||
|
||||
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 + HasTargetSpec,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout + HasTargetSpec,
|
||||
{
|
||||
let abi = if cx.target_spec().env == "musl" {
|
||||
ELFv2
|
||||
|
|
|
@ -5,9 +5,7 @@
|
|||
// https://github.com/llvm/llvm-project/blob/8e780252a7284be45cf1ba224cabd884847e8e92/clang/lib/CodeGen/TargetInfo.cpp#L9311-L9773
|
||||
|
||||
use crate::abi::call::{ArgAbi, ArgExtension, CastTarget, FnAbi, PassMode, Reg, RegKind, Uniform};
|
||||
use crate::abi::{
|
||||
self, Abi, FieldsShape, HasDataLayout, LayoutOf, Size, TyAndLayout, TyAndLayoutMethods,
|
||||
};
|
||||
use crate::abi::{self, Abi, FieldsShape, HasDataLayout, Size, TyAbiInterface, TyAndLayout};
|
||||
use crate::spec::HasTargetSpec;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
|
@ -43,8 +41,7 @@ fn should_use_fp_conv_helper<'a, Ty, C>(
|
|||
field2_kind: &mut RegPassKind,
|
||||
) -> Result<(), CannotUseFpConv>
|
||||
where
|
||||
Ty: TyAndLayoutMethods<'a, C> + Copy,
|
||||
C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>>,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
{
|
||||
match arg_layout.abi {
|
||||
Abi::Scalar(ref scalar) => match scalar.value {
|
||||
|
@ -130,8 +127,7 @@ fn should_use_fp_conv<'a, Ty, C>(
|
|||
flen: u64,
|
||||
) -> Option<FloatConv>
|
||||
where
|
||||
Ty: TyAndLayoutMethods<'a, C> + Copy,
|
||||
C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>>,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
{
|
||||
let mut field1_kind = RegPassKind::Unknown;
|
||||
let mut field2_kind = RegPassKind::Unknown;
|
||||
|
@ -149,8 +145,7 @@ where
|
|||
|
||||
fn classify_ret<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>, xlen: u64, flen: u64) -> bool
|
||||
where
|
||||
Ty: TyAndLayoutMethods<'a, C> + Copy,
|
||||
C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>>,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
{
|
||||
if let Some(conv) = should_use_fp_conv(cx, &arg.layout, xlen, flen) {
|
||||
match conv {
|
||||
|
@ -212,8 +207,7 @@ fn classify_arg<'a, Ty, C>(
|
|||
avail_gprs: &mut u64,
|
||||
avail_fprs: &mut u64,
|
||||
) where
|
||||
Ty: TyAndLayoutMethods<'a, C> + Copy,
|
||||
C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>>,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
{
|
||||
if !is_vararg {
|
||||
match should_use_fp_conv(cx, &arg.layout, xlen, flen) {
|
||||
|
@ -320,8 +314,8 @@ fn extend_integer_width<'a, Ty>(arg: &mut ArgAbi<'a, Ty>, xlen: u64) {
|
|||
|
||||
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 + HasTargetSpec,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout + HasTargetSpec,
|
||||
{
|
||||
let flen = match &cx.target_spec().llvm_abiname[..] {
|
||||
"ilp32f" | "lp64f" => 32,
|
||||
|
|
|
@ -2,13 +2,9 @@
|
|||
// for a pre-z13 machine or using -mno-vx.
|
||||
|
||||
use crate::abi::call::{ArgAbi, FnAbi, Reg};
|
||||
use crate::abi::{self, HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods};
|
||||
use crate::abi::{self, HasDataLayout, TyAbiInterface, TyAndLayout};
|
||||
|
||||
fn classify_ret<'a, Ty, C>(ret: &mut ArgAbi<'_, Ty>)
|
||||
where
|
||||
Ty: TyAndLayoutMethods<'a, C>,
|
||||
C: LayoutOf<Ty = Ty> + HasDataLayout,
|
||||
{
|
||||
fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
|
||||
if !ret.layout.is_aggregate() && ret.layout.size.bits() <= 64 {
|
||||
ret.extend_integer_width_to(64);
|
||||
} else {
|
||||
|
@ -18,8 +14,8 @@ where
|
|||
|
||||
fn is_single_fp_element<'a, Ty, C>(cx: &C, layout: TyAndLayout<'a, Ty>) -> bool
|
||||
where
|
||||
Ty: TyAndLayoutMethods<'a, C>,
|
||||
C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
|
||||
Ty: TyAbiInterface<'a, C>,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
match layout.abi {
|
||||
abi::Abi::Scalar(ref scalar) => scalar.value.is_float(),
|
||||
|
@ -36,8 +32,8 @@ where
|
|||
|
||||
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,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
if !arg.layout.is_aggregate() && arg.layout.size.bits() <= 64 {
|
||||
arg.extend_integer_width_to(64);
|
||||
|
@ -63,8 +59,8 @@ where
|
|||
|
||||
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,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
if !fn_abi.ret.is_ignore() {
|
||||
classify_ret(&mut fn_abi.ret);
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
use crate::abi::call::{ArgAbi, FnAbi, Reg, Uniform};
|
||||
use crate::abi::{HasDataLayout, LayoutOf, Size, TyAndLayoutMethods};
|
||||
use crate::abi::{HasDataLayout, Size};
|
||||
|
||||
fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'_, Ty>, offset: &mut Size)
|
||||
fn classify_ret<Ty, C>(cx: &C, ret: &mut ArgAbi<'_, Ty>, offset: &mut Size)
|
||||
where
|
||||
Ty: TyAndLayoutMethods<'a, C>,
|
||||
C: LayoutOf<Ty = Ty> + HasDataLayout,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
if !ret.layout.is_aggregate() {
|
||||
ret.extend_integer_width_to(32);
|
||||
|
@ -14,10 +13,9 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'_, Ty>, offset: &mut Size)
|
||||
fn classify_arg<Ty, C>(cx: &C, arg: &mut ArgAbi<'_, Ty>, offset: &mut Size)
|
||||
where
|
||||
Ty: TyAndLayoutMethods<'a, C>,
|
||||
C: LayoutOf<Ty = Ty> + HasDataLayout,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
let dl = cx.data_layout();
|
||||
let size = arg.layout.size;
|
||||
|
@ -35,10 +33,9 @@ where
|
|||
*offset = offset.align_to(align) + size.align_to(align);
|
||||
}
|
||||
|
||||
pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'_, Ty>)
|
||||
pub fn compute_abi_info<Ty, C>(cx: &C, fn_abi: &mut FnAbi<'_, Ty>)
|
||||
where
|
||||
Ty: TyAndLayoutMethods<'a, C>,
|
||||
C: LayoutOf<Ty = Ty> + HasDataLayout,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
let mut offset = Size::ZERO;
|
||||
if !fn_abi.ret.is_ignore() {
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
// FIXME: This needs an audit for correctness and completeness.
|
||||
|
||||
use crate::abi::call::{ArgAbi, FnAbi, Reg, RegKind, Uniform};
|
||||
use crate::abi::{HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods};
|
||||
use crate::abi::{HasDataLayout, TyAbiInterface};
|
||||
|
||||
fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) -> Option<Uniform>
|
||||
where
|
||||
Ty: TyAndLayoutMethods<'a, C> + Copy,
|
||||
C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
arg.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()).and_then(|unit| {
|
||||
// Ensure we have at most eight uniquely addressable members.
|
||||
|
@ -26,8 +26,8 @@ where
|
|||
|
||||
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,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
if !ret.layout.is_aggregate() {
|
||||
ret.extend_integer_width_to(64);
|
||||
|
@ -52,8 +52,8 @@ where
|
|||
|
||||
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,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
if !arg.layout.is_aggregate() {
|
||||
arg.extend_integer_width_to(64);
|
||||
|
@ -76,8 +76,8 @@ where
|
|||
|
||||
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,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
if !fn_abi.ret.is_ignore() {
|
||||
classify_ret(cx, &mut fn_abi.ret);
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
use crate::abi::call::{ArgAbi, FnAbi, Uniform};
|
||||
use crate::abi::{HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods};
|
||||
use crate::abi::{HasDataLayout, TyAbiInterface};
|
||||
|
||||
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,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
if val.layout.is_aggregate() {
|
||||
if let Some(unit) = val.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()) {
|
||||
|
@ -20,8 +20,8 @@ where
|
|||
|
||||
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,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
ret.extend_integer_width_to(32);
|
||||
if ret.layout.is_aggregate() && !unwrap_trivial_aggregate(cx, ret) {
|
||||
|
@ -31,8 +31,8 @@ where
|
|||
|
||||
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,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
arg.extend_integer_width_to(32);
|
||||
if arg.layout.is_aggregate() && !unwrap_trivial_aggregate(cx, arg) {
|
||||
|
@ -43,8 +43,8 @@ where
|
|||
/// 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,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
if !fn_abi.ret.is_ignore() {
|
||||
classify_ret(cx, &mut fn_abi.ret);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::abi::call::{ArgAttribute, FnAbi, PassMode, Reg, RegKind};
|
||||
use crate::abi::{self, HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods};
|
||||
use crate::abi::{self, HasDataLayout, TyAbiInterface, TyAndLayout};
|
||||
use crate::spec::HasTargetSpec;
|
||||
|
||||
#[derive(PartialEq)]
|
||||
|
@ -10,8 +10,8 @@ pub enum Flavor {
|
|||
|
||||
fn is_single_fp_element<'a, Ty, C>(cx: &C, layout: TyAndLayout<'a, Ty>) -> bool
|
||||
where
|
||||
Ty: TyAndLayoutMethods<'a, C> + Copy,
|
||||
C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
match layout.abi {
|
||||
abi::Abi::Scalar(ref scalar) => scalar.value.is_float(),
|
||||
|
@ -28,8 +28,8 @@ where
|
|||
|
||||
pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>, flavor: Flavor)
|
||||
where
|
||||
Ty: TyAndLayoutMethods<'a, C> + Copy,
|
||||
C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout + HasTargetSpec,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout + HasTargetSpec,
|
||||
{
|
||||
if !fn_abi.ret.is_ignore() {
|
||||
if fn_abi.ret.layout.is_aggregate() {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// https://github.com/jckarter/clay/blob/master/compiler/src/externals.cpp
|
||||
|
||||
use crate::abi::call::{ArgAbi, CastTarget, FnAbi, Reg, RegKind};
|
||||
use crate::abi::{self, Abi, HasDataLayout, LayoutOf, Size, TyAndLayout, TyAndLayoutMethods};
|
||||
use crate::abi::{self, Abi, HasDataLayout, Size, TyAbiInterface, TyAndLayout};
|
||||
|
||||
/// Classification of "eightbyte" components.
|
||||
// N.B., the order of the variants is from general to specific,
|
||||
|
@ -26,8 +26,8 @@ fn classify_arg<'a, Ty, C>(
|
|||
arg: &ArgAbi<'a, Ty>,
|
||||
) -> Result<[Option<Class>; MAX_EIGHTBYTES], Memory>
|
||||
where
|
||||
Ty: TyAndLayoutMethods<'a, C> + Copy,
|
||||
C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
fn classify<'a, Ty, C>(
|
||||
cx: &C,
|
||||
|
@ -36,8 +36,8 @@ where
|
|||
off: Size,
|
||||
) -> Result<(), Memory>
|
||||
where
|
||||
Ty: TyAndLayoutMethods<'a, C> + Copy,
|
||||
C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
if !off.is_aligned(layout.align.abi) {
|
||||
if !layout.is_zst() {
|
||||
|
@ -172,8 +172,8 @@ const MAX_SSE_REGS: usize = 8; // XMM0-7
|
|||
|
||||
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,
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
let mut int_regs = MAX_INT_REGS;
|
||||
let mut sse_regs = MAX_SSE_REGS;
|
||||
|
|
|
@ -1174,9 +1174,9 @@ impl<'a, Ty> Deref for TyAndLayout<'a, Ty> {
|
|||
}
|
||||
|
||||
/// Trait for context types that can compute layouts of things.
|
||||
pub trait LayoutOf {
|
||||
type Ty;
|
||||
type TyAndLayout;
|
||||
pub trait LayoutOf<'a>: Sized {
|
||||
type Ty: TyAbiInterface<'a, Self>;
|
||||
type TyAndLayout: MaybeResult<TyAndLayout<'a, Self::Ty>>;
|
||||
|
||||
fn layout_of(&self, ty: Self::Ty) -> Self::TyAndLayout;
|
||||
fn spanned_layout_of(&self, ty: Self::Ty, _span: Span) -> Self::TyAndLayout {
|
||||
|
@ -1184,9 +1184,6 @@ pub trait LayoutOf {
|
|||
}
|
||||
}
|
||||
|
||||
/// The `TyAndLayout` above will always be a `MaybeResult<TyAndLayout<'_, Self>>`.
|
||||
/// We can't add the bound due to the lifetime, but this trait is still useful when
|
||||
/// writing code that's generic over the `LayoutOf` impl.
|
||||
pub trait MaybeResult<T> {
|
||||
type Error;
|
||||
|
||||
|
@ -1239,41 +1236,42 @@ pub struct PointeeInfo {
|
|||
pub address_space: AddressSpace,
|
||||
}
|
||||
|
||||
pub trait TyAndLayoutMethods<'a, C: LayoutOf<Ty = Self>>: Sized {
|
||||
fn for_variant(
|
||||
/// Trait that needs to be implemented by the higher-level type representation
|
||||
/// (e.g. `rustc_middle::ty::Ty`), to provide `rustc_target::abi` functionality.
|
||||
pub trait TyAbiInterface<'a, C>: Sized {
|
||||
fn ty_and_layout_for_variant(
|
||||
this: TyAndLayout<'a, Self>,
|
||||
cx: &C,
|
||||
variant_index: VariantIdx,
|
||||
) -> TyAndLayout<'a, Self>;
|
||||
fn field(this: TyAndLayout<'a, Self>, cx: &C, i: usize) -> C::TyAndLayout;
|
||||
fn pointee_info_at(this: TyAndLayout<'a, Self>, cx: &C, offset: Size) -> Option<PointeeInfo>;
|
||||
fn ty_and_layout_field(this: TyAndLayout<'a, Self>, cx: &C, i: usize) -> TyAndLayout<'a, Self>;
|
||||
fn ty_and_layout_pointee_info_at(
|
||||
this: TyAndLayout<'a, Self>,
|
||||
cx: &C,
|
||||
offset: Size,
|
||||
) -> Option<PointeeInfo>;
|
||||
}
|
||||
|
||||
impl<'a, Ty> TyAndLayout<'a, Ty> {
|
||||
pub fn for_variant<C>(self, cx: &C, variant_index: VariantIdx) -> Self
|
||||
where
|
||||
Ty: TyAndLayoutMethods<'a, C>,
|
||||
C: LayoutOf<Ty = Ty>,
|
||||
Ty: TyAbiInterface<'a, C>,
|
||||
{
|
||||
Ty::for_variant(self, cx, variant_index)
|
||||
Ty::ty_and_layout_for_variant(self, cx, variant_index)
|
||||
}
|
||||
|
||||
/// Callers might want to use `C: LayoutOf<Ty=Ty, TyAndLayout: MaybeResult<Self>>`
|
||||
/// to allow recursion (see `might_permit_zero_init` below for an example).
|
||||
pub fn field<C>(self, cx: &C, i: usize) -> C::TyAndLayout
|
||||
pub fn field<C>(self, cx: &C, i: usize) -> Self
|
||||
where
|
||||
Ty: TyAndLayoutMethods<'a, C>,
|
||||
C: LayoutOf<Ty = Ty>,
|
||||
Ty: TyAbiInterface<'a, C>,
|
||||
{
|
||||
Ty::field(self, cx, i)
|
||||
Ty::ty_and_layout_field(self, cx, i)
|
||||
}
|
||||
|
||||
pub fn pointee_info_at<C>(self, cx: &C, offset: Size) -> Option<PointeeInfo>
|
||||
where
|
||||
Ty: TyAndLayoutMethods<'a, C>,
|
||||
C: LayoutOf<Ty = Ty>,
|
||||
Ty: TyAbiInterface<'a, C>,
|
||||
{
|
||||
Ty::pointee_info_at(self, cx, offset)
|
||||
Ty::ty_and_layout_pointee_info_at(self, cx, offset)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1301,11 +1299,11 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
|
|||
/// FIXME: Once we removed all the conservatism, we could alternatively
|
||||
/// create an all-0/all-undef constant and run the const value validator to see if
|
||||
/// this is a valid value for the given type.
|
||||
pub fn might_permit_raw_init<C, E>(self, cx: &C, zero: bool) -> Result<bool, E>
|
||||
pub fn might_permit_raw_init<C>(self, cx: &C, zero: bool) -> bool
|
||||
where
|
||||
Self: Copy,
|
||||
Ty: TyAndLayoutMethods<'a, C>,
|
||||
C: LayoutOf<Ty = Ty, TyAndLayout: MaybeResult<Self, Error = E>> + HasDataLayout,
|
||||
Ty: TyAbiInterface<'a, C>,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
let scalar_allows_raw_init = move |s: &Scalar| -> bool {
|
||||
if zero {
|
||||
|
@ -1330,7 +1328,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
|
|||
};
|
||||
if !valid {
|
||||
// This is definitely not okay.
|
||||
return Ok(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we have not found an error yet, we need to recursively descend into fields.
|
||||
|
@ -1341,16 +1339,15 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
|
|||
}
|
||||
FieldsShape::Arbitrary { offsets, .. } => {
|
||||
for idx in 0..offsets.len() {
|
||||
let field = self.field(cx, idx).to_result()?;
|
||||
if !field.might_permit_raw_init(cx, zero)? {
|
||||
if !self.field(cx, idx).might_permit_raw_init(cx, zero) {
|
||||
// We found a field that is unhappy with this kind of initialization.
|
||||
return Ok(false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(#66151): For now, we are conservative and do not check `self.variants`.
|
||||
Ok(true)
|
||||
true
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue