ty::layout: intern FnAbis as &'tcx.

This commit is contained in:
Eduard-Mihai Burtescu 2021-08-26 21:58:34 +03:00
parent 0c02e3f550
commit 344df76fed
7 changed files with 29 additions and 23 deletions

View file

@ -239,7 +239,7 @@ pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> {
pub(crate) instance: Instance<'tcx>, pub(crate) instance: Instance<'tcx>,
pub(crate) symbol_name: SymbolName<'tcx>, pub(crate) symbol_name: SymbolName<'tcx>,
pub(crate) mir: &'tcx Body<'tcx>, pub(crate) mir: &'tcx Body<'tcx>,
pub(crate) fn_abi: Option<FnAbi<'tcx, Ty<'tcx>>>, pub(crate) fn_abi: Option<&'tcx FnAbi<'tcx, Ty<'tcx>>>,
pub(crate) bcx: FunctionBuilder<'clif>, pub(crate) bcx: FunctionBuilder<'clif>,
pub(crate) block_map: IndexVec<BasicBlock, Block>, pub(crate) block_map: IndexVec<BasicBlock, Block>,

View file

@ -124,7 +124,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
&self, &self,
fx: &mut FunctionCx<'a, 'tcx, Bx>, fx: &mut FunctionCx<'a, 'tcx, Bx>,
bx: &mut Bx, bx: &mut Bx,
fn_abi: FnAbi<'tcx, Ty<'tcx>>, fn_abi: &'tcx FnAbi<'tcx, Ty<'tcx>>,
fn_ptr: Bx::Value, fn_ptr: Bx::Value,
llargs: &[Bx::Value], llargs: &[Bx::Value],
destination: Option<(ReturnDest<'tcx, Bx::Value>, mir::BasicBlock)>, destination: Option<(ReturnDest<'tcx, Bx::Value>, mir::BasicBlock)>,

View file

@ -29,7 +29,7 @@ pub struct FunctionCx<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> {
cx: &'a Bx::CodegenCx, cx: &'a Bx::CodegenCx,
fn_abi: FnAbi<'tcx, Ty<'tcx>>, fn_abi: &'tcx FnAbi<'tcx, Ty<'tcx>>,
/// When unwinding is initiated, we have to store this personality /// When unwinding is initiated, we have to store this personality
/// value somewhere so that we can load it and re-use it in the /// value somewhere so that we can load it and re-use it in the

View file

@ -11,7 +11,8 @@
macro_rules! arena_types { macro_rules! arena_types {
($macro:path, $tcx:lifetime) => ( ($macro:path, $tcx:lifetime) => (
$macro!([ $macro!([
[] layouts: rustc_target::abi::Layout, [] layout: rustc_target::abi::Layout,
[] fn_abi: rustc_target::abi::call::FnAbi<$tcx, rustc_middle::ty::Ty<$tcx>>,
// AdtDef are interned and compared by address // AdtDef are interned and compared by address
[] adt_def: rustc_middle::ty::AdtDef, [] adt_def: rustc_middle::ty::AdtDef,
[] steal_thir: rustc_data_structures::steal::Steal<rustc_middle::thir::Thir<$tcx>>, [] steal_thir: rustc_data_structures::steal::Steal<rustc_middle::thir::Thir<$tcx>>,

View file

@ -55,6 +55,7 @@ use rustc_span::def_id::{DefPathHash, StableCrateId};
use rustc_span::source_map::{MultiSpan, SourceMap}; use rustc_span::source_map::{MultiSpan, SourceMap};
use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{Span, DUMMY_SP}; use rustc_span::{Span, DUMMY_SP};
use rustc_target::abi::call::FnAbi;
use rustc_target::abi::{Layout, TargetDataLayout, VariantIdx}; use rustc_target::abi::{Layout, TargetDataLayout, VariantIdx};
use rustc_target::spec::abi; use rustc_target::spec::abi;
@ -135,6 +136,7 @@ pub struct CtxtInterners<'tcx> {
const_allocation: InternedSet<'tcx, Allocation>, const_allocation: InternedSet<'tcx, Allocation>,
bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>, bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>,
layout: InternedSet<'tcx, Layout>, layout: InternedSet<'tcx, Layout>,
fn_abi: InternedSet<'tcx, FnAbi<'tcx, Ty<'tcx>>>,
} }
impl<'tcx> CtxtInterners<'tcx> { impl<'tcx> CtxtInterners<'tcx> {
@ -155,6 +157,7 @@ impl<'tcx> CtxtInterners<'tcx> {
const_allocation: Default::default(), const_allocation: Default::default(),
bound_variable_kinds: Default::default(), bound_variable_kinds: Default::default(),
layout: Default::default(), layout: Default::default(),
fn_abi: Default::default(),
} }
} }
@ -1959,6 +1962,7 @@ impl<'tcx> TyCtxt<'tcx> {
self.0.interners.const_allocation.len() self.0.interners.const_allocation.len()
)?; )?;
writeln!(fmt, "Layout interner: #{}", self.0.interners.layout.len())?; writeln!(fmt, "Layout interner: #{}", self.0.interners.layout.len())?;
writeln!(fmt, "FnAbi interner: #{}", self.0.interners.fn_abi.len())?;
Ok(()) Ok(())
} }
@ -2083,6 +2087,7 @@ direct_interners! {
const_: mk_const(Const<'tcx>), const_: mk_const(Const<'tcx>),
const_allocation: intern_const_alloc(Allocation), const_allocation: intern_const_alloc(Allocation),
layout: intern_layout(Layout), layout: intern_layout(Layout),
fn_abi: intern_fn_abi(FnAbi<'tcx, Ty<'tcx>>),
} }
macro_rules! slice_interners { macro_rules! slice_interners {

View file

@ -2838,21 +2838,21 @@ where
/// ///
/// NB: this doesn't handle virtual calls - those should use `FnAbi::of_instance` /// NB: this doesn't handle virtual calls - those should use `FnAbi::of_instance`
/// instead, where the instance is an `InstanceDef::Virtual`. /// instead, where the instance is an `InstanceDef::Virtual`.
fn of_fn_ptr(cx: &C, sig: ty::PolyFnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self; fn of_fn_ptr(cx: &C, sig: ty::PolyFnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> &'tcx Self;
/// Compute a `FnAbi` suitable for declaring/defining an `fn` instance, and for /// Compute a `FnAbi` suitable for declaring/defining an `fn` instance, and for
/// direct calls to an `fn`. /// direct calls to an `fn`.
/// ///
/// NB: that includes virtual calls, which are represented by "direct calls" /// NB: that includes virtual calls, which are represented by "direct calls"
/// to an `InstanceDef::Virtual` instance (of `<dyn Trait as Trait>::fn`). /// to an `InstanceDef::Virtual` instance (of `<dyn Trait as Trait>::fn`).
fn of_instance(cx: &C, instance: ty::Instance<'tcx>, extra_args: &[Ty<'tcx>]) -> Self; fn of_instance(cx: &C, instance: ty::Instance<'tcx>, extra_args: &[Ty<'tcx>]) -> &'tcx Self;
} }
impl<'tcx, C> FnAbiExt<'tcx, C> for call::FnAbi<'tcx, Ty<'tcx>> impl<'tcx, C> FnAbiExt<'tcx, C> for call::FnAbi<'tcx, Ty<'tcx>>
where where
C: HasTyCtxt<'tcx> + HasParamEnv<'tcx>, C: HasTyCtxt<'tcx> + HasParamEnv<'tcx>,
{ {
fn of_fn_ptr(cx: &C, sig: ty::PolyFnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self { fn of_fn_ptr(cx: &C, sig: ty::PolyFnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> &'tcx Self {
call::FnAbi::new_internal( call::FnAbi::new_internal(
&LayoutCx { tcx: cx.tcx(), param_env: cx.param_env() }, &LayoutCx { tcx: cx.tcx(), param_env: cx.param_env() },
sig, sig,
@ -2872,7 +2872,7 @@ where
}) })
} }
fn of_instance(cx: &C, instance: ty::Instance<'tcx>, extra_args: &[Ty<'tcx>]) -> Self { fn of_instance(cx: &C, instance: ty::Instance<'tcx>, extra_args: &[Ty<'tcx>]) -> &'tcx Self {
let sig = instance.fn_sig_for_fn_abi(cx.tcx()); let sig = instance.fn_sig_for_fn_abi(cx.tcx());
let caller_location = if instance.def.requires_caller_location(cx.tcx()) { let caller_location = if instance.def.requires_caller_location(cx.tcx()) {
@ -2912,7 +2912,7 @@ where
/// Implementation detail of computing `FnAbi`s, shouldn't be exported. /// Implementation detail of computing `FnAbi`s, shouldn't be exported.
// FIXME(eddyb) move this off of being generic on `C: LayoutOf`, and // FIXME(eddyb) move this off of being generic on `C: LayoutOf`, and
// explicitly take `LayoutCx` *or* `TyCtxt` and `ParamEnvAnd<...>`. // explicitly take `LayoutCx` *or* `TyCtxt` and `ParamEnvAnd<...>`.
trait FnAbiInternalExt<'tcx, C>: Sized trait FnAbiInternalExt<'tcx, C>
where where
C: LayoutOf<'tcx, LayoutOfResult = Result<TyAndLayout<'tcx>, LayoutError<'tcx>>> C: LayoutOf<'tcx, LayoutOfResult = Result<TyAndLayout<'tcx>, LayoutError<'tcx>>>
+ HasTargetSpec, + HasTargetSpec,
@ -2927,7 +2927,7 @@ where
codegen_fn_attr_flags: CodegenFnAttrFlags, codegen_fn_attr_flags: CodegenFnAttrFlags,
// FIXME(eddyb) replace this with something typed, like an `enum`. // FIXME(eddyb) replace this with something typed, like an `enum`.
make_self_ptr_thin: bool, make_self_ptr_thin: bool,
) -> Result<Self, FnAbiError<'tcx>>; ) -> Result<&'tcx Self, FnAbiError<'tcx>>;
fn adjust_for_abi(&mut self, cx: &C, abi: SpecAbi) -> Result<(), FnAbiError<'tcx>>; fn adjust_for_abi(&mut self, cx: &C, abi: SpecAbi) -> Result<(), FnAbiError<'tcx>>;
} }
@ -2943,7 +2943,7 @@ where
caller_location: Option<Ty<'tcx>>, caller_location: Option<Ty<'tcx>>,
codegen_fn_attr_flags: CodegenFnAttrFlags, codegen_fn_attr_flags: CodegenFnAttrFlags,
force_thin_self_ptr: bool, force_thin_self_ptr: bool,
) -> Result<Self, FnAbiError<'tcx>> { ) -> Result<&'tcx Self, FnAbiError<'tcx>> {
debug!("FnAbi::new_internal({:?}, {:?})", sig, extra_args); debug!("FnAbi::new_internal({:?}, {:?})", sig, extra_args);
let sig = cx.tcx().normalize_erasing_late_bound_regions(cx.param_env(), sig); let sig = cx.tcx().normalize_erasing_late_bound_regions(cx.param_env(), sig);
@ -3106,7 +3106,7 @@ where
}; };
fn_abi.adjust_for_abi(cx, sig.abi)?; fn_abi.adjust_for_abi(cx, sig.abi)?;
debug!("FnAbi::new_internal = {:?}", fn_abi); debug!("FnAbi::new_internal = {:?}", fn_abi);
Ok(fn_abi) Ok(cx.tcx().intern_fn_abi(fn_abi))
} }
fn adjust_for_abi(&mut self, cx: &C, abi: SpecAbi) -> Result<(), FnAbiError<'tcx>> { fn adjust_for_abi(&mut self, cx: &C, abi: SpecAbi) -> Result<(), FnAbiError<'tcx>> {

View file

@ -25,7 +25,7 @@ mod x86;
mod x86_64; mod x86_64;
mod x86_win64; mod x86_win64;
#[derive(Clone, Copy, PartialEq, Eq, Debug)] #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
pub enum PassMode { pub enum PassMode {
/// Ignore the argument. /// Ignore the argument.
/// ///
@ -60,7 +60,7 @@ pub use attr_impl::ArgAttribute;
mod attr_impl { mod attr_impl {
// The subset of llvm::Attribute needed for arguments, packed into a bitfield. // The subset of llvm::Attribute needed for arguments, packed into a bitfield.
bitflags::bitflags! { bitflags::bitflags! {
#[derive(Default)] #[derive(Default, HashStable_Generic)]
pub struct ArgAttribute: u16 { pub struct ArgAttribute: u16 {
const NoAlias = 1 << 1; const NoAlias = 1 << 1;
const NoCapture = 1 << 2; const NoCapture = 1 << 2;
@ -77,7 +77,7 @@ mod attr_impl {
/// Sometimes an ABI requires small integers to be extended to a full or partial register. This enum /// Sometimes an ABI requires small integers to be extended to a full or partial register. This enum
/// defines if this extension should be zero-extension or sign-extension when necessary. When it is /// defines if this extension should be zero-extension or sign-extension when necessary. When it is
/// not necessary to extend the argument, this enum is ignored. /// not necessary to extend the argument, this enum is ignored.
#[derive(Copy, Clone, PartialEq, Eq, Debug)] #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
pub enum ArgExtension { pub enum ArgExtension {
None, None,
Zext, Zext,
@ -86,7 +86,7 @@ pub enum ArgExtension {
/// A compact representation of LLVM attributes (at least those relevant for this module) /// A compact representation of LLVM attributes (at least those relevant for this module)
/// that can be manipulated without interacting with LLVM's Attribute machinery. /// that can be manipulated without interacting with LLVM's Attribute machinery.
#[derive(Copy, Clone, PartialEq, Eq, Debug)] #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
pub struct ArgAttributes { pub struct ArgAttributes {
pub regular: ArgAttribute, pub regular: ArgAttribute,
pub arg_ext: ArgExtension, pub arg_ext: ArgExtension,
@ -127,14 +127,14 @@ impl ArgAttributes {
} }
} }
#[derive(Copy, Clone, PartialEq, Eq, Debug)] #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
pub enum RegKind { pub enum RegKind {
Integer, Integer,
Float, Float,
Vector, Vector,
} }
#[derive(Copy, Clone, PartialEq, Eq, Debug)] #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
pub struct Reg { pub struct Reg {
pub kind: RegKind, pub kind: RegKind,
pub size: Size, pub size: Size,
@ -184,7 +184,7 @@ impl Reg {
/// An argument passed entirely registers with the /// An argument passed entirely registers with the
/// same kind (e.g., HFA / HVA on PPC64 and AArch64). /// same kind (e.g., HFA / HVA on PPC64 and AArch64).
#[derive(Clone, Copy, PartialEq, Eq, Debug)] #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
pub struct Uniform { pub struct Uniform {
pub unit: Reg, pub unit: Reg,
@ -209,7 +209,7 @@ impl Uniform {
} }
} }
#[derive(Clone, Copy, PartialEq, Eq, Debug)] #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
pub struct CastTarget { pub struct CastTarget {
pub prefix: [Option<RegKind>; 8], pub prefix: [Option<RegKind>; 8],
pub prefix_chunk_size: Size, pub prefix_chunk_size: Size,
@ -437,7 +437,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
/// Information about how to pass an argument to, /// Information about how to pass an argument to,
/// or return a value from, a function, under some ABI. /// or return a value from, a function, under some ABI.
#[derive(Debug)] #[derive(PartialEq, Eq, Hash, Debug, HashStable_Generic)]
pub struct ArgAbi<'a, Ty> { pub struct ArgAbi<'a, Ty> {
pub layout: TyAndLayout<'a, Ty>, pub layout: TyAndLayout<'a, Ty>,
@ -545,7 +545,7 @@ impl<'a, Ty> ArgAbi<'a, Ty> {
} }
} }
#[derive(Copy, Clone, PartialEq, Debug)] #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
pub enum Conv { pub enum Conv {
// General language calling conventions, for which every target // General language calling conventions, for which every target
// should have its own backend (e.g. LLVM) support. // should have its own backend (e.g. LLVM) support.
@ -579,7 +579,7 @@ pub enum Conv {
/// ///
/// I will do my best to describe this structure, but these /// I will do my best to describe this structure, but these
/// comments are reverse-engineered and may be inaccurate. -NDM /// comments are reverse-engineered and may be inaccurate. -NDM
#[derive(Debug)] #[derive(PartialEq, Eq, Hash, Debug, HashStable_Generic)]
pub struct FnAbi<'a, Ty> { pub struct FnAbi<'a, Ty> {
/// The LLVM types of each argument. /// The LLVM types of each argument.
pub args: Vec<ArgAbi<'a, Ty>>, pub args: Vec<ArgAbi<'a, Ty>>,