1
Fork 0

Rollup merge of #118694 - celinval:smir-alloc-methods, r=ouz-a

Add instance evaluation and methods to read an allocation in StableMIR

The instance evaluation is needed to handle intrinsics such as `type_id` and `type_name`.

Since we now use Allocation to represent all evaluated constants, provide a few methods to help process the data inside an allocation.

I've also started to add a structured way to get information about the compilation target machine. For now, I've only added information needed to process an allocation.

r? ``````@ouz-a``````
This commit is contained in:
Matthias Krüger 2023-12-08 23:15:12 +01:00 committed by GitHub
commit 1889e5a00b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 458 additions and 29 deletions

View file

@ -2,6 +2,7 @@ use rustc_middle::mir::{
interpret::{alloc_range, AllocRange, Pointer},
ConstValue,
};
use stable_mir::Error;
use crate::rustc_smir::{Stable, Tables};
use stable_mir::mir::Mutability;
@ -26,23 +27,35 @@ pub fn new_allocation<'tcx>(
const_value: ConstValue<'tcx>,
tables: &mut Tables<'tcx>,
) -> Allocation {
match const_value {
try_new_allocation(ty, const_value, tables).unwrap()
}
#[allow(rustc::usage_of_qualified_ty)]
pub fn try_new_allocation<'tcx>(
ty: rustc_middle::ty::Ty<'tcx>,
const_value: ConstValue<'tcx>,
tables: &mut Tables<'tcx>,
) -> Result<Allocation, Error> {
Ok(match const_value {
ConstValue::Scalar(scalar) => {
let size = scalar.size();
let align = tables
.tcx
.layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(ty))
.unwrap()
.map_err(|e| e.stable(tables))?
.align;
let mut allocation = rustc_middle::mir::interpret::Allocation::uninit(size, align.abi);
allocation
.write_scalar(&tables.tcx, alloc_range(rustc_target::abi::Size::ZERO, size), scalar)
.unwrap();
.map_err(|e| e.stable(tables))?;
allocation.stable(tables)
}
ConstValue::ZeroSized => {
let align =
tables.tcx.layout_of(rustc_middle::ty::ParamEnv::empty().and(ty)).unwrap().align;
let align = tables
.tcx
.layout_of(rustc_middle::ty::ParamEnv::empty().and(ty))
.map_err(|e| e.stable(tables))?
.align;
new_empty_allocation(align.abi)
}
ConstValue::Slice { data, meta } => {
@ -51,8 +64,10 @@ pub fn new_allocation<'tcx>(
let scalar_ptr = rustc_middle::mir::interpret::Scalar::from_pointer(ptr, &tables.tcx);
let scalar_meta =
rustc_middle::mir::interpret::Scalar::from_target_usize(meta, &tables.tcx);
let layout =
tables.tcx.layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(ty)).unwrap();
let layout = tables
.tcx
.layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(ty))
.map_err(|e| e.stable(tables))?;
let mut allocation =
rustc_middle::mir::interpret::Allocation::uninit(layout.size, layout.align.abi);
allocation
@ -61,14 +76,14 @@ pub fn new_allocation<'tcx>(
alloc_range(rustc_target::abi::Size::ZERO, tables.tcx.data_layout.pointer_size),
scalar_ptr,
)
.unwrap();
.map_err(|e| e.stable(tables))?;
allocation
.write_scalar(
&tables.tcx,
alloc_range(tables.tcx.data_layout.pointer_size, scalar_meta.size()),
scalar_meta,
)
.unwrap();
.map_err(|e| e.stable(tables))?;
allocation.stable(tables)
}
ConstValue::Indirect { alloc_id, offset } => {
@ -76,11 +91,11 @@ pub fn new_allocation<'tcx>(
let ty_size = tables
.tcx
.layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(ty))
.unwrap()
.map_err(|e| e.stable(tables))?
.size;
allocation_filter(&alloc.0, alloc_range(offset, ty_size), tables)
}
}
})
}
/// Creates an `Allocation` only from information within the `AllocRange`.

View file

@ -11,18 +11,29 @@ use stable_mir::compiler_interface::Context;
use stable_mir::mir::alloc::GlobalAlloc;
use stable_mir::mir::mono::{InstanceDef, StaticDef};
use stable_mir::mir::Body;
use stable_mir::target::{MachineInfo, MachineSize};
use stable_mir::ty::{
AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, FieldDef, FnDef, GenericArgs,
LineInfo, PolyFnSig, RigidTy, Span, TyKind, VariantDef,
LineInfo, PolyFnSig, RigidTy, Span, Ty, TyKind, VariantDef,
};
use stable_mir::{self, Crate, CrateItem, DefId, Error, Filename, ItemKind, Symbol};
use std::cell::RefCell;
use crate::rustc_internal::{internal, RustcInternal};
use crate::rustc_smir::builder::BodyBuilder;
use crate::rustc_smir::{new_item_kind, smir_crate, Stable, Tables};
use crate::rustc_smir::{alloc, new_item_kind, smir_crate, Stable, Tables};
impl<'tcx> Context for TablesWrapper<'tcx> {
fn target_info(&self) -> MachineInfo {
let mut tables = self.0.borrow_mut();
MachineInfo {
endian: tables.tcx.data_layout.endian.stable(&mut *tables),
pointer_width: MachineSize::from_bits(
tables.tcx.data_layout.pointer_size.bits().try_into().unwrap(),
),
}
}
fn entry_fn(&self) -> Option<stable_mir::CrateItem> {
let mut tables = self.0.borrow_mut();
let tcx = tables.tcx;
@ -382,6 +393,21 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
Instance::resolve_closure(tables.tcx, def_id, args_ref, closure_kind).stable(&mut *tables)
}
fn eval_instance(&self, def: InstanceDef, const_ty: Ty) -> Result<Allocation, Error> {
let mut tables = self.0.borrow_mut();
let instance = tables.instances[def];
let result = tables.tcx.const_eval_instance(
ParamEnv::reveal_all(),
instance,
Some(tables.tcx.def_span(instance.def_id())),
);
result
.map(|const_val| {
alloc::try_new_allocation(const_ty.internal(&mut *tables), const_val, &mut *tables)
})
.map_err(|e| e.stable(&mut *tables))?
}
fn eval_static_initializer(&self, def: StaticDef) -> Result<Allocation, Error> {
let mut tables = self.0.borrow_mut();
let def_id = def.0.internal(&mut *tables);

View file

@ -0,0 +1,22 @@
//! Handle the conversion of different internal errors into a stable version.
//!
//! Currently we encode everything as [stable_mir::Error], which is represented as a string.
use crate::rustc_smir::{Stable, Tables};
use rustc_middle::mir::interpret::AllocError;
use rustc_middle::ty::layout::LayoutError;
impl<'tcx> Stable<'tcx> for LayoutError<'tcx> {
type T = stable_mir::Error;
fn stable(&self, _tables: &mut Tables<'tcx>) -> Self::T {
stable_mir::Error::new(format!("{self:?}"))
}
}
impl<'tcx> Stable<'tcx> for AllocError {
type T = stable_mir::Error;
fn stable(&self, _tables: &mut Tables<'tcx>) -> Self::T {
stable_mir::Error::new(format!("{self:?}"))
}
}

View file

@ -5,6 +5,7 @@ use stable_mir::ty::{IndexedVal, VariantIdx};
use crate::rustc_smir::{Stable, Tables};
mod error;
mod mir;
mod ty;
@ -76,3 +77,14 @@ impl<'tcx> Stable<'tcx> for rustc_span::Span {
tables.create_span(*self)
}
}
impl<'tcx> Stable<'tcx> for rustc_abi::Endian {
type T = stable_mir::target::Endian;
fn stable(&self, _tables: &mut Tables<'tcx>) -> Self::T {
match self {
rustc_abi::Endian::Little => stable_mir::target::Endian::Little,
rustc_abi::Endian::Big => stable_mir::target::Endian::Big,
}
}
}