Skip to content

Commit 4c04c8e

Browse files
celinvaladpaco-aws
andauthored
Migrate hooks and place modules to use mostly StableMIR APIs (#2910)
The main changes needed to make this migration besides a few method call tweaks were: 1. Adapt `FunctionCtx` to cache information about the StableMIR version of instance and its body. - I also cleaned up how we were handling basic blocks which were unnecessary. 2. Created a new ty_stable module that provide stable versions to retrieve type information from StableMIR. - I decided to keep these separate so it is cleaner for now. I foresee that the type module will still rely on internal APIs for the next little while, so separating them here made sense to me. 3. Since `Place` when retrieved from StableMIR body already comes monomorphized, I modified the existing `codegen_place` to preemptively monomorphize Place before converting it to a Stable version and invoking `codegen_place_stable`. ### Call-outs Leaving this as a draft for now since this still depends on the following PRs to be merged into the Rust compiler: - rust-lang/rust#118524 - rust-lang/rust#118516 --------- Co-authored-by: Adrian Palacios <[email protected]>
1 parent 2475dc6 commit 4c04c8e

File tree

15 files changed

+522
-396
lines changed

15 files changed

+522
-396
lines changed

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

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use crate::codegen_cprover_gotoc::GotocCtx;
2222
use cbmc::goto_program::{Expr, Location, Stmt, Type};
2323
use cbmc::InternedString;
2424
use rustc_span::Span;
25+
use stable_mir::ty::Span as SpanStable;
2526
use std::convert::AsRef;
2627
use strum_macros::{AsRefStr, EnumString};
2728
use tracing::debug;
@@ -138,8 +139,8 @@ impl<'tcx> GotocCtx<'tcx> {
138139
}
139140

140141
/// Generate code to cover the given condition at the current location
141-
pub fn codegen_cover(&self, cond: Expr, msg: &str, span: Option<Span>) -> Stmt {
142-
let loc = self.codegen_caller_span(&span);
142+
pub fn codegen_cover(&self, cond: Expr, msg: &str, span: SpanStable) -> Stmt {
143+
let loc = self.codegen_caller_span_stable(span);
143144
// Should use Stmt::cover, but currently this doesn't work with CBMC
144145
// unless it is run with '--cover cover' (see
145146
// https://github.com/diffblue/cbmc/issues/6613). So for now use
@@ -172,12 +173,8 @@ impl<'tcx> GotocCtx<'tcx> {
172173
/// reachability check.
173174
/// If reachability checks are disabled, the function returns the message
174175
/// unmodified and an empty (skip) statement.
175-
pub fn codegen_reachability_check(
176-
&mut self,
177-
msg: String,
178-
span: Option<Span>,
179-
) -> (String, Stmt) {
180-
let loc = self.codegen_caller_span(&span);
176+
pub fn codegen_reachability_check(&mut self, msg: String, span: SpanStable) -> (String, Stmt) {
177+
let loc = self.codegen_caller_span_stable(span);
181178
if self.queries.args().check_assertion_reachability {
182179
// Generate a unique ID for the assert
183180
let assert_id = self.next_check_id();
@@ -224,15 +221,16 @@ impl<'tcx> GotocCtx<'tcx> {
224221
}
225222

226223
/// Kani hooks function calls to `panic` and calls this intead.
227-
pub fn codegen_panic(&self, span: Option<Span>, fargs: Vec<Expr>) -> Stmt {
224+
pub fn codegen_panic(&self, span: SpanStable, fargs: Vec<Expr>) -> Stmt {
228225
// CBMC requires that the argument to the assertion must be a string constant.
229226
// If there is one in the MIR, use it; otherwise, explain that we can't.
230227
assert!(!fargs.is_empty(), "Panic requires a string message");
231228
let msg = self.extract_const_message(&fargs[0]).unwrap_or(String::from(
232229
"This is a placeholder message; Kani doesn't support message formatted at runtime",
233230
));
234231

235-
self.codegen_fatal_error(PropertyClass::Assertion, &msg, span)
232+
let loc = self.codegen_caller_span_stable(span);
233+
self.codegen_assert_assume_false(PropertyClass::Assertion, &msg, loc)
236234
}
237235

238236
/// Kani does not currently support all MIR constructs.

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,13 @@
33

44
use crate::codegen_cprover_gotoc::GotocCtx;
55
use rustc_middle::mir::{BasicBlock, BasicBlockData};
6+
use stable_mir::mir::BasicBlockIdx;
67
use tracing::debug;
78

9+
pub fn bb_label(bb: BasicBlockIdx) -> String {
10+
format!("bb{bb}")
11+
}
12+
813
impl<'tcx> GotocCtx<'tcx> {
914
/// Generates Goto-C for a basic block.
1015
///
@@ -14,7 +19,6 @@ impl<'tcx> GotocCtx<'tcx> {
1419
/// `self.current_fn_mut().push_onto_block(...)`
1520
pub fn codegen_block(&mut self, bb: BasicBlock, bbd: &BasicBlockData<'tcx>) {
1621
debug!(?bb, "Codegen basicblock");
17-
self.current_fn_mut().set_current_bb(bb);
1822
let label: String = self.current_fn().find_label(&bb);
1923
let check_coverage = self.queries.args().check_coverage;
2024
// the first statement should be labelled. if there is no statements, then the
@@ -67,6 +71,5 @@ impl<'tcx> GotocCtx<'tcx> {
6771
self.current_fn_mut().push_onto_block(tcode);
6872
}
6973
}
70-
self.current_fn_mut().reset_current_bb();
7174
}
7275
}

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ impl<'tcx> GotocCtx<'tcx> {
2828
/// - Indices [1, N] represent the function parameters where N is the number of parameters.
2929
/// - Indices that are greater than N represent local variables.
3030
fn codegen_declare_variables(&mut self) {
31-
let mir = self.current_fn().mir();
31+
let mir = self.current_fn().body_internal();
3232
let ldecls = mir.local_decls();
3333
let num_args = self.get_params_size();
3434
ldecls.indices().enumerate().for_each(|(idx, lc)| {
@@ -76,7 +76,7 @@ impl<'tcx> GotocCtx<'tcx> {
7676
debug!("Double codegen of {:?}", old_sym);
7777
} else {
7878
assert!(old_sym.is_function());
79-
let mir = self.current_fn().mir();
79+
let mir = self.current_fn().body_internal();
8080
self.print_instance(instance, mir);
8181
self.codegen_function_prelude();
8282
self.codegen_declare_variables();
@@ -94,7 +94,7 @@ impl<'tcx> GotocCtx<'tcx> {
9494
/// Codegen changes required due to the function ABI.
9595
/// We currently untuple arguments for RustCall ABI where the `spread_arg` is set.
9696
fn codegen_function_prelude(&mut self) {
97-
let mir = self.current_fn().mir();
97+
let mir = self.current_fn().body_internal();
9898
if let Some(spread_arg) = mir.spread_arg {
9999
self.codegen_spread_arg(mir, spread_arg);
100100
}
@@ -228,7 +228,7 @@ impl<'tcx> GotocCtx<'tcx> {
228228
debug!(krate = self.current_fn().krate().as_str());
229229
debug!(is_std = self.current_fn().is_std());
230230
self.ensure(&self.current_fn().name(), |ctx, fname| {
231-
let mir = ctx.current_fn().mir();
231+
let mir = ctx.current_fn().body_internal();
232232
Symbol::function(
233233
fname,
234234
ctx.fn_typ(),

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ mod statement;
1717
mod static_var;
1818

1919
// Visible for all codegen module.
20+
mod ty_stable;
2021
pub(super) mod typ;
2122

2223
pub use assert::PropertyClass;
24+
pub use block::bb_label;
2325
pub use typ::TypeExt;

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,13 @@ use rustc_middle::mir::interpret::{read_target_uint, AllocId, Allocation, Global
1010
use rustc_middle::mir::{Const as mirConst, ConstOperand, ConstValue, Operand, UnevaluatedConst};
1111
use rustc_middle::ty::layout::LayoutOf;
1212
use rustc_middle::ty::{self, Const, ConstKind, FloatTy, Instance, IntTy, Ty, Uint, UintTy};
13+
use rustc_smir::rustc_internal;
1314
use rustc_span::def_id::DefId;
1415
use rustc_span::Span;
1516
use rustc_target::abi::{Size, TagEncoding, Variants};
17+
use stable_mir::mir::mono::Instance as InstanceStable;
18+
use stable_mir::ty::{FnDef, GenericArgs, Span as SpanStable};
19+
use stable_mir::CrateDef;
1620
use tracing::{debug, trace};
1721

1822
enum AllocData<'a> {
@@ -702,6 +706,20 @@ impl<'tcx> GotocCtx<'tcx> {
702706
self.codegen_fn_item(instance, span)
703707
}
704708

709+
pub fn codegen_fndef_stable(
710+
&mut self,
711+
def: FnDef,
712+
args: &GenericArgs,
713+
span: Option<SpanStable>,
714+
) -> Expr {
715+
let instance = InstanceStable::resolve(def, args)
716+
.expect(&format!("Failed to instantiate `{}` with `{args:?}`", def.name()));
717+
self.codegen_fn_item(
718+
rustc_internal::internal(instance),
719+
rustc_internal::internal(span).as_ref(),
720+
)
721+
}
722+
705723
/// Ensure that the given instance is in the symbol table, returning the symbol.
706724
///
707725
/// FIXME: The function should not have to return the type of the function symbol as well
@@ -735,6 +753,12 @@ impl<'tcx> GotocCtx<'tcx> {
735753
.with_location(self.codegen_span_option(span.cloned()))
736754
}
737755

756+
pub fn codegen_func_expr_stable(&mut self, instance: InstanceStable, span: SpanStable) -> Expr {
757+
let (func_symbol, func_typ) = self.codegen_func_symbol(rustc_internal::internal(instance));
758+
Expr::symbol_expression(func_symbol.name, func_typ)
759+
.with_location(self.codegen_span_stable(span))
760+
}
761+
738762
/// Generate a goto expression referencing the singleton value for a MIR "function item".
739763
///
740764
/// For a given function instance, generate a ZST struct and return a singleton reference to that.

0 commit comments

Comments
 (0)