Skip to content

Commit

Permalink
Add size_of annotation to help CBMC's allocator
Browse files Browse the repository at this point in the history
CBMC's heap allocator will produce objects that aren't just a byte array
when a prior call to `size_of` was involved in computing the number of
bytes to be allocated via malloc/calloc/realloc. This, in turn, permits
type-safe member accesses to heap-allocated objects. This should speed
up copying as well as all other operations on the resulting object
(which will then not have to go through byte extract/byte update
operations).

It also seems that there no longer is a "size_of" intrinsic.
  • Loading branch information
tautschnig committed Apr 20, 2023
1 parent 588baf0 commit ee80124
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 6 deletions.
14 changes: 13 additions & 1 deletion cprover_bindings/src/goto_program/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ pub struct Expr {
value: Box<ExprValue>,
typ: Type,
location: Location,
size_of_annotation: Option<Type>,
}

/// The different kinds of values an expression can have.
Expand Down Expand Up @@ -293,6 +294,10 @@ impl Expr {
&self.value
}

pub fn size_of_annotation(&self) -> &Option<Type> {
&self.size_of_annotation
}

/// If the expression is an Int constant type, return its value
pub fn int_constant_value(&self) -> Option<BigInt> {
match &*self.value {
Expand Down Expand Up @@ -404,12 +409,19 @@ impl Expr {
}
}

impl Expr {
pub fn with_size_of_annotation(mut self, ty: Type) -> Self {
self.size_of_annotation = Some(ty);
self
}
}

/// Private constructor. Making this a macro allows multiple reference to self in the same call.
macro_rules! expr {
( $value:expr, $typ:expr) => {{
let typ = $typ;
let value = Box::new($value);
Expr { value, typ, location: Location::none() }
Expr { value, typ, location: Location::none(), size_of_annotation: None }
}};
}

Expand Down
4 changes: 4 additions & 0 deletions cprover_bindings/src/irep/to_irep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,10 @@ impl ToIrep for Expr {
} else {
self.value().to_irep(mm).with_location(self.location(), mm).with_type(self.typ(), mm)
}
.with_named_sub_option(
IrepId::CCSizeofType,
self.size_of_annotation().clone().map(|ty| ty.to_irep(mm)),
)
}
}

Expand Down
8 changes: 4 additions & 4 deletions kani-compiler/src/codegen_cprover_gotoc/codegen/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ impl<'tcx> GotocCtx<'tcx> {
}};
}

// Intrinsics which encode a value known during compilation (e.g., `size_of`)
// Intrinsics which encode a value known during compilation
macro_rules! codegen_intrinsic_const {
() => {{
let value = self
Expand Down Expand Up @@ -611,7 +611,6 @@ impl<'tcx> GotocCtx<'tcx> {
loc,
),
"simd_xor" => codegen_intrinsic_binop!(bitxor),
"size_of" => codegen_intrinsic_const!(),
"size_of_val" => codegen_size_align!(size),
"sqrtf32" => unstable_codegen!(codegen_simple_intrinsic!(Sqrtf)),
"sqrtf64" => unstable_codegen!(codegen_simple_intrinsic!(Sqrt)),
Expand Down Expand Up @@ -1267,11 +1266,12 @@ impl<'tcx> GotocCtx<'tcx> {
/// This function computes the size and alignment of a dynamically-sized type.
/// The implementations follows closely the SSA implementation found in
/// `rustc_codegen_ssa::glue::size_and_align_of_dst`.
fn size_and_align_of_dst(&self, t: Ty<'tcx>, arg: Expr) -> SizeAlign {
fn size_and_align_of_dst(&mut self, t: Ty<'tcx>, arg: Expr) -> SizeAlign {
let layout = self.layout_of(t);
let usizet = Type::size_t();
if !layout.is_unsized() {
let size = Expr::int_constant(layout.size.bytes_usize(), Type::size_t());
let size = Expr::int_constant(layout.size.bytes_usize(), Type::size_t())
.with_size_of_annotation(self.codegen_ty(t));
let align = Expr::int_constant(layout.align.abi.bytes(), usizet);
return SizeAlign { size, align };
}
Expand Down
3 changes: 2 additions & 1 deletion kani-compiler/src/codegen_cprover_gotoc/codegen/rvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,8 @@ impl<'tcx> GotocCtx<'tcx> {
let t = self.monomorphize(*t);
let layout = self.layout_of(t);
match k {
NullOp::SizeOf => Expr::int_constant(layout.size.bytes_usize(), Type::size_t()),
NullOp::SizeOf => Expr::int_constant(layout.size.bytes_usize(), Type::size_t())
.with_size_of_annotation(self.codegen_ty(t)),
NullOp::AlignOf => Expr::int_constant(layout.align.abi.bytes(), Type::size_t()),
}
}
Expand Down

0 comments on commit ee80124

Please sign in to comment.