Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate rvalue and coercion module to use StableMIR #2938

Merged
merged 6 commits into from
Dec 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,11 @@ impl<'tcx> GotocCtx<'tcx> {
"cttz_nonzero" => codegen_count_intrinsic!(cttz, false),
"discriminant_value" => {
let ty = instance.args.type_at(0);
let e = self.codegen_get_discriminant(fargs.remove(0).dereference(), ty, ret_ty);
let e = self.codegen_get_discriminant(
fargs.remove(0).dereference(),
rustc_internal::stable(ty),
rustc_internal::stable(ret_ty),
);
self.codegen_expr_to_place(p, e)
}
"exact_div" => self.codegen_exact_div(fargs, p, loc),
Expand Down
9 changes: 4 additions & 5 deletions kani-compiler/src/codegen_cprover_gotoc/codegen/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use cbmc::goto_program::{DatatypeComponent, Expr, ExprValue, Location, Stmt, Sym
use rustc_middle::mir::Operand as OperandInternal;
use rustc_middle::ty::{Const as ConstInternal, Instance as InstanceInternal};
use rustc_smir::rustc_internal;
use rustc_span::def_id::DefId;
use rustc_span::Span as SpanInternal;
use stable_mir::mir::alloc::{AllocId, GlobalAlloc};
use stable_mir::mir::mono::{Instance, StaticDef};
Expand All @@ -17,7 +16,7 @@ use stable_mir::ty::{
Allocation, Const, ConstantKind, FloatTy, FnDef, GenericArgs, IntTy, RigidTy, Size, Span, Ty,
TyKind, UintTy,
};
use stable_mir::CrateDef;
use stable_mir::{CrateDef, CrateItem};
use tracing::{debug, trace};

#[derive(Clone, Debug)]
Expand Down Expand Up @@ -80,7 +79,7 @@ impl<'tcx> GotocCtx<'tcx> {
/// generate code for it as simple literals or constants if possible. Otherwise, we create
/// a memory allocation for them and access them indirectly.
/// - ZeroSized: These are ZST constants and they just need to match the right type.
fn codegen_const(&mut self, constant: &Const, span: Option<Span>) -> Expr {
pub fn codegen_const(&mut self, constant: &Const, span: Option<Span>) -> Expr {
trace!(?constant, "codegen_constant");
match constant.kind() {
ConstantKind::Allocated(alloc) => self.codegen_allocation(alloc, constant.ty(), span),
Expand Down Expand Up @@ -379,8 +378,8 @@ impl<'tcx> GotocCtx<'tcx> {
/// Generate a goto expression for a pointer to a thread-local variable.
///
/// These are not initialized here, see `codegen_static`.
pub fn codegen_thread_local_pointer(&mut self, def_id: DefId) -> Expr {
let instance = rustc_internal::stable(InstanceInternal::mono(self.tcx, def_id));
pub fn codegen_thread_local_pointer(&mut self, def: CrateItem) -> Expr {
let instance = Instance::try_from(def).unwrap();
adpaco-aws marked this conversation as resolved.
Show resolved Hide resolved
self.codegen_instance_pointer(instance, true)
}

Expand Down
47 changes: 19 additions & 28 deletions kani-compiler/src/codegen_cprover_gotoc/codegen/place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,13 @@

use super::typ::TypeExt;
use crate::codegen_cprover_gotoc::codegen::ty_stable::{pointee_type, StableConverter};
use crate::codegen_cprover_gotoc::codegen::typ::{
pointee_type as pointee_type_internal, std_pointee_type,
};
use crate::codegen_cprover_gotoc::codegen::typ::std_pointee_type;
use crate::codegen_cprover_gotoc::utils::{dynamic_fat_ptr, slice_fat_ptr};
use crate::codegen_cprover_gotoc::GotocCtx;
use crate::unwrap_or_return_codegen_unimplemented;
use cbmc::goto_program::{Expr, Location, Type};
use rustc_middle::mir::{Local as LocalInternal, Place as PlaceInternal};
use rustc_middle::ty::layout::LayoutOf;
use rustc_middle::{
mir::{Local as LocalInternal, Place as PlaceInternal},
ty::Ty as TyInternal,
};
use rustc_smir::rustc_internal;
use rustc_target::abi::{TagEncoding, Variants};
use stable_mir::mir::{FieldIdx, Local, Mutability, Place, ProjectionElem};
Expand Down Expand Up @@ -152,13 +147,12 @@ impl ProjectedPlace {
}
}

pub fn try_new_internal<'tcx>(
pub fn try_from_ty(
goto_expr: Expr,
ty: TyInternal<'tcx>,
ctx: &mut GotocCtx<'tcx>,
ty: Ty,
ctx: &mut GotocCtx,
) -> Result<Self, UnimplementedData> {
let ty = ctx.monomorphize(ty);
Self::try_new(goto_expr, TypeOrVariant::Type(rustc_internal::stable(ty)), None, None, ctx)
Self::try_new(goto_expr, TypeOrVariant::Type(ty), None, None, ctx)
}

pub fn try_new(
Expand Down Expand Up @@ -415,7 +409,7 @@ impl<'tcx> GotocCtx<'tcx> {
match proj {
ProjectionElem::Deref => {
let base_type = before.mir_typ();
let inner_goto_expr = if is_box(base_type) {
let inner_goto_expr = if base_type.kind().is_box() {
self.deref_box(before.goto_expr)
} else {
before.goto_expr
Expand Down Expand Up @@ -605,7 +599,7 @@ impl<'tcx> GotocCtx<'tcx> {
Variants::Single { .. } => before.goto_expr,
Variants::Multiple { tag_encoding, .. } => match tag_encoding {
TagEncoding::Direct => {
let cases = if is_coroutine(ty_kind) {
let cases = if ty_kind.is_coroutine() {
before.goto_expr
} else {
before.goto_expr.member("cases", &self.symbol_table)
Expand Down Expand Up @@ -644,21 +638,26 @@ impl<'tcx> GotocCtx<'tcx> {
/// - For `*(Wrapper<T>)` where `T: Unsized`, the projection's `goto_expr` returns an object,
/// and we need to take it's address and build the fat pointer.
pub fn codegen_place_ref(&mut self, place: &PlaceInternal<'tcx>) -> Expr {
let place_ty = self.place_ty(place);
let projection = unwrap_or_return_codegen_unimplemented!(self, self.codegen_place(place));
if self.use_thin_pointer(place_ty) {
self.codegen_place_ref_stable(&StableConverter::convert_place(self, *place))
}

pub fn codegen_place_ref_stable(&mut self, place: &Place) -> Expr {
let place_ty = self.place_ty_stable(place);
let projection =
unwrap_or_return_codegen_unimplemented!(self, self.codegen_place_stable(place));
if self.use_thin_pointer_stable(place_ty) {
// Just return the address of the place dereferenced.
projection.goto_expr.address_of()
} else if place_ty == pointee_type_internal(self.local_ty(place.local)).unwrap() {
} else if place_ty == pointee_type(self.local_ty_stable(place.local)).unwrap() {
// Just return the fat pointer if this is a simple &(*local).
projection.fat_ptr_goto_expr.unwrap()
} else {
// Build a new fat pointer to the place dereferenced with the metadata from the
// original fat pointer.
let data = projection_data_ptr(&projection);
let fat_ptr = projection.fat_ptr_goto_expr.unwrap();
let place_type = self.codegen_ty_ref(place_ty);
if self.use_vtable_fat_pointer(place_ty) {
let place_type = self.codegen_ty_ref_stable(place_ty);
if self.use_vtable_fat_pointer_stable(place_ty) {
let vtable = fat_ptr.member("vtable", &self.symbol_table);
dynamic_fat_ptr(place_type, data, vtable, &self.symbol_table)
} else {
Expand Down Expand Up @@ -781,14 +780,6 @@ impl<'tcx> GotocCtx<'tcx> {
}
}

fn is_box(ty: Ty) -> bool {
matches!(ty.kind(), TyKind::RigidTy(RigidTy::Adt(def, _)) if def.is_box())
}

fn is_coroutine(ty_kind: TyKind) -> bool {
matches!(ty_kind, TyKind::RigidTy(RigidTy::Coroutine(..)))
}

/// Extract the data pointer from a projection.
/// The return type of the projection is not consistent today, so we need to specialize the
/// behavior in order to get a consistent expression that represents a pointer to the projected
Expand Down
Loading