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:
commit
1889e5a00b
15 changed files with 458 additions and 29 deletions
|
@ -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`.
|
||||
|
|
|
@ -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);
|
||||
|
|
22
compiler/rustc_smir/src/rustc_smir/convert/error.rs
Normal file
22
compiler/rustc_smir/src/rustc_smir/convert/error.rs
Normal 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:?}"))
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue