Skip to content

Commit c29b906

Browse files
Share body cache between harnesses within a codegen unit (#4276)
Improves on #4259 by fully sharing the body cache between harnesses in the same codegen unit. This cache initially only stored bodies which had been modified by our transformations, with the goal being to avoid doing those transformations multiple times. It does this job well, having a hit rate of **~66% on queries for modified bodies**[^1]. However, I observed that even just querying to get the initial `Body` for a given `Instance` was a bottleneck, even if no passes needed to be applied. And, in this regard, the cache is much less effective, having a hit rate of **only 1.8% if you count non-modified bodies**[^1]. Thus, this PR also _adds all bodies to the cache, even those which were not modified_ by our passes. ### Results This change causes a further **7.7% reduction in the end to end compile time** of the standard library (@ commit [177d0fd](model-checking/verify-rust-std@177d0fd)). The body cache has an **average hit rate of 95.3%** on that workload and, on a hit, we (at most) have to do an inexpensive clone from the cache rather than querying `rustc_public`. As a caching solution, this comes with some memory overhead. Since we're sharing a cache and caching more bodies, the peak size of this cache has gone from **0.88 MB to 3.75 MB**. This may seem like a significant increase (and I'm definitely open to feedback on whether it's acceptable), but given the fact that Kani hovered around 2.5-3.5 GB of RAM for that same run, this bigger cache would make up just 0.11%-0.15% of our total memory use. [^1]: when verifying the standard library (@ commit [177d0fd](model-checking/verify-rust-std@177d0fd)) By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses.
1 parent 2b05737 commit c29b906

File tree

25 files changed

+91
-101
lines changed

25 files changed

+91
-101
lines changed

kani-compiler/src/codegen_cprover_gotoc/codegen/assert.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ impl PropertyClass {
107107
}
108108
}
109109

110-
impl GotocCtx<'_> {
110+
impl GotocCtx<'_, '_> {
111111
/// Generates a CBMC assertion. Note: Does _NOT_ assume.
112112
pub fn codegen_assert(
113113
&self,

kani-compiler/src/codegen_cprover_gotoc/codegen/block.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ pub fn bb_label(bb: BasicBlockIdx) -> String {
1010
format!("bb{bb}")
1111
}
1212

13-
impl GotocCtx<'_> {
13+
impl GotocCtx<'_, '_> {
1414
/// Generates Goto-C for a basic block.
1515
///
1616
/// A MIR basic block consists of 0 or more statements followed by a terminator.

kani-compiler/src/codegen_cprover_gotoc/codegen/contract.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rustc_public::mir::{Local, VarDebugInfoContents};
1212
use rustc_public::rustc_internal;
1313
use rustc_public::ty::{FnDef, RigidTy, TyKind};
1414

15-
impl GotocCtx<'_> {
15+
impl GotocCtx<'_, '_> {
1616
/// Given the `proof_for_contract` target `function_under_contract` and the reachable `items`,
1717
/// find or create the `AssignsContract` that needs to be enforced and attach it to the symbol
1818
/// for which it needs to be enforced.
@@ -91,7 +91,7 @@ impl GotocCtx<'_> {
9191
let contract_attrs =
9292
KaniAttributes::for_instance(self.tcx, instance).contract_attributes()?;
9393
let mut find_closure = |inside: Instance, name: &str| {
94-
let body = self.transformer.body(self.tcx, inside);
94+
let body = self.transformer.body_ref(self.tcx, inside);
9595
body.var_debug_info.iter().find_map(|var_info| {
9696
if var_info.name.as_str() == name {
9797
let ty = match &var_info.value {

kani-compiler/src/codegen_cprover_gotoc/codegen/foreign_function.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ lazy_static! {
4040
};
4141
}
4242

43-
impl GotocCtx<'_> {
43+
impl GotocCtx<'_, '_> {
4444
/// Generate the symbol and symbol table entry for foreign items.
4545
///
4646
/// CBMC built-in functions that are supported by Kani are always added to the symbol table, and

kani-compiler/src/codegen_cprover_gotoc/codegen/function.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use std::collections::BTreeMap;
1616
use tracing::{debug, debug_span};
1717

1818
/// Codegen MIR functions into gotoc
19-
impl GotocCtx<'_> {
19+
impl GotocCtx<'_, '_> {
2020
/// Declare variables according to their index.
2121
/// - Index 0 represents the return value.
2222
/// - Indices [1, N] represent the function parameters where N is the number of parameters.

kani-compiler/src/codegen_cprover_gotoc/codegen/intrinsic.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ enum VTableInfo {
2626
Align,
2727
}
2828

29-
impl GotocCtx<'_> {
29+
impl GotocCtx<'_, '_> {
3030
fn binop<F: FnOnce(Expr, Expr) -> Expr>(
3131
&mut self,
3232
place: &Place,

kani-compiler/src/codegen_cprover_gotoc/codegen/operand.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ enum AllocData<'a> {
2727
Expr(Expr),
2828
}
2929

30-
impl<'tcx> GotocCtx<'tcx> {
30+
impl<'tcx, 'r> GotocCtx<'tcx, 'r> {
3131
/// Generate a goto expression from a MIR operand.
3232
///
3333
/// A MIR operand is either a constant (literal or `const` declaration) or a place

kani-compiler/src/codegen_cprover_gotoc/codegen/place.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ impl TypeOrVariant {
217217
}
218218
}
219219

220-
impl GotocCtx<'_> {
220+
impl GotocCtx<'_, '_> {
221221
/// Codegen field access for types that allow direct field projection.
222222
///
223223
/// I.e.: Algebraic data types, closures, and coroutines.

kani-compiler/src/codegen_cprover_gotoc/codegen/rvalue.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use rustc_public::ty::{
3333
use std::collections::BTreeMap;
3434
use tracing::{debug, trace, warn};
3535

36-
impl GotocCtx<'_> {
36+
impl GotocCtx<'_, '_> {
3737
fn codegen_comparison(&mut self, op: &BinOp, e1: &Operand, e2: &Operand) -> Expr {
3838
let left_op = self.codegen_operand_stable(e1);
3939
let right_op = self.codegen_operand_stable(e2);

kani-compiler/src/codegen_cprover_gotoc/codegen/span.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ lazy_static! {
3131
("pointer-primitive", "disable:pointer-primitive-check")].iter().copied().collect();
3232
}
3333

34-
impl GotocCtx<'_> {
34+
impl GotocCtx<'_, '_> {
3535
pub fn codegen_span(&self, sp: &Span) -> Location {
3636
self.codegen_span_stable(rustc_internal::stable(sp))
3737
}

0 commit comments

Comments
 (0)