@@ -7,7 +7,8 @@ use crate::args::ReachabilityType;
7
7
use crate :: codegen_cprover_gotoc:: GotocCtx ;
8
8
use crate :: kani_middle:: analysis;
9
9
use crate :: kani_middle:: attributes:: { is_test_harness_description, KaniAttributes } ;
10
- use crate :: kani_middle:: metadata:: { canonical_mangled_name, gen_test_metadata} ;
10
+ use crate :: kani_middle:: codegen_units:: { CodegenUnit , CodegenUnits } ;
11
+ use crate :: kani_middle:: metadata:: gen_test_metadata;
11
12
use crate :: kani_middle:: provide;
12
13
use crate :: kani_middle:: reachability:: {
13
14
collect_reachable_items, filter_const_crate_items, filter_crate_items,
@@ -17,7 +18,7 @@ use crate::kani_middle::{check_reachable_items, dump_mir_items};
17
18
use crate :: kani_queries:: QueryDb ;
18
19
use cbmc:: goto_program:: Location ;
19
20
use cbmc:: irep:: goto_binary_serde:: write_goto_binary_file;
20
- use cbmc:: { InternString , RoundingMode } ;
21
+ use cbmc:: RoundingMode ;
21
22
use cbmc:: { InternedString , MachineModel } ;
22
23
use kani_metadata:: artifact:: convert_type;
23
24
use kani_metadata:: UnsupportedFeature ;
@@ -49,7 +50,6 @@ use stable_mir::mir::mono::{Instance, MonoItem};
49
50
use stable_mir:: { CrateDef , DefId } ;
50
51
use std:: any:: Any ;
51
52
use std:: collections:: BTreeMap ;
52
- use std:: collections:: HashSet ;
53
53
use std:: ffi:: OsString ;
54
54
use std:: fmt:: Write ;
55
55
use std:: fs:: File ;
@@ -231,43 +231,43 @@ impl CodegenBackend for GotocCodegenBackend {
231
231
let base_filepath = tcx. output_filenames ( ( ) ) . path ( OutputType :: Object ) ;
232
232
let base_filename = base_filepath. as_path ( ) ;
233
233
let reachability = queries. args ( ) . reachability_analysis ;
234
- let mut transformer = BodyTransformation :: new ( & queries, tcx) ;
235
234
let mut results = GotoCodegenResults :: new ( tcx, reachability) ;
236
235
match reachability {
237
236
ReachabilityType :: Harnesses => {
237
+ let mut units = CodegenUnits :: new ( & queries, tcx) ;
238
+ let mut modifies_instances = vec ! [ ] ;
238
239
// Cross-crate collecting of all items that are reachable from the crate harnesses.
239
- let harnesses = queries. target_harnesses ( ) ;
240
- let mut items: HashSet < _ > = HashSet :: with_capacity ( harnesses. len ( ) ) ;
241
- items. extend ( harnesses) ;
242
- let harnesses = filter_crate_items ( tcx, |_, instance| {
243
- items. contains ( & instance. mangled_name ( ) . intern ( ) )
244
- } ) ;
245
- for harness in harnesses {
246
- let model_path =
247
- queries. harness_model_path ( & harness. mangled_name ( ) ) . unwrap ( ) ;
248
- let contract_metadata =
249
- contract_metadata_for_harness ( tcx, harness. def . def_id ( ) ) . unwrap ( ) ;
250
- let ( gcx, items, contract_info) = self . codegen_items (
251
- tcx,
252
- & [ MonoItem :: Fn ( harness) ] ,
253
- model_path,
254
- & results. machine_model ,
255
- contract_metadata,
256
- transformer,
257
- ) ;
258
- transformer = results. extend ( gcx, items, None ) ;
259
- if let Some ( assigns_contract) = contract_info {
260
- self . queries . lock ( ) . unwrap ( ) . register_assigns_contract (
261
- canonical_mangled_name ( harness) . intern ( ) ,
262
- assigns_contract,
240
+ for unit in units. iter ( ) {
241
+ // We reset the body cache for now because each codegen unit has different
242
+ // configurations that affect how we transform the instance body.
243
+ let mut transformer = BodyTransformation :: new ( & queries, tcx, & unit) ;
244
+ for harness in & unit. harnesses {
245
+ let model_path = units. harness_model_path ( * harness) . unwrap ( ) ;
246
+ let contract_metadata =
247
+ contract_metadata_for_harness ( tcx, harness. def . def_id ( ) ) . unwrap ( ) ;
248
+ let ( gcx, items, contract_info) = self . codegen_items (
249
+ tcx,
250
+ & [ MonoItem :: Fn ( * harness) ] ,
251
+ model_path,
252
+ & results. machine_model ,
253
+ contract_metadata,
254
+ transformer,
263
255
) ;
256
+ transformer = results. extend ( gcx, items, None ) ;
257
+ if let Some ( assigns_contract) = contract_info {
258
+ modifies_instances. push ( ( * harness, assigns_contract) ) ;
259
+ }
264
260
}
265
261
}
262
+ units. store_modifies ( & modifies_instances) ;
263
+ units. write_metadata ( & queries, tcx) ;
266
264
}
267
265
ReachabilityType :: Tests => {
268
266
// We're iterating over crate items here, so what we have to codegen is the "test description" containing the
269
267
// test closure that we want to execute
270
268
// TODO: Refactor this code so we can guarantee that the pair (test_fn, test_desc) actually match.
269
+ let unit = CodegenUnit :: default ( ) ;
270
+ let mut transformer = BodyTransformation :: new ( & queries, tcx, & unit) ;
271
271
let mut descriptions = vec ! [ ] ;
272
272
let harnesses = filter_const_crate_items ( tcx, & mut transformer, |_, item| {
273
273
if is_test_harness_description ( tcx, item. def ) {
@@ -310,6 +310,8 @@ impl CodegenBackend for GotocCodegenBackend {
310
310
}
311
311
ReachabilityType :: None => { }
312
312
ReachabilityType :: PubFns => {
313
+ let unit = CodegenUnit :: default ( ) ;
314
+ let transformer = BodyTransformation :: new ( & queries, tcx, & unit) ;
313
315
let main_instance =
314
316
stable_mir:: entry_fn ( ) . map ( |main_fn| Instance :: try_from ( main_fn) . unwrap ( ) ) ;
315
317
let local_reachable = filter_crate_items ( tcx, |_, instance| {
0 commit comments