Skip to content

Commit 7dfac5a

Browse files
also clone GlobalPasses template
1 parent 42e056e commit 7dfac5a

4 files changed

Lines changed: 52 additions & 30 deletions

File tree

kani-compiler/src/codegen_cprover_gotoc/compiler_interface.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,15 @@ impl GotocCodegenBackend {
7272
/// Generate code that is reachable from the given starting points.
7373
///
7474
/// Invariant: iff `check_contract.is_some()` then `return.2.is_some()`
75+
#[allow(clippy::too_many_arguments)]
7576
fn codegen_items<'tcx>(
7677
&self,
7778
tcx: TyCtxt<'tcx>,
7879
starting_items: &[MonoItem],
7980
symtab_goto: &Path,
8081
machine_model: &MachineModel,
8182
check_contract: Option<InternalDefId>,
83+
mut global_passes: GlobalPasses,
8284
mut transformer: BodyTransformation,
8385
) -> (GotocCtx<'tcx>, Vec<MonoItem>, Option<AssignsContract>) {
8486
// This runs reachability analysis before global passes are applied.
@@ -107,7 +109,6 @@ impl GotocCodegenBackend {
107109
.collect();
108110

109111
// Apply all transformation passes, including global passes.
110-
let mut global_passes = GlobalPasses::new(&self.queries.lock().unwrap(), tcx);
111112
let any_pass_modified = global_passes.run_global_passes(
112113
&mut transformer,
113114
tcx,
@@ -334,6 +335,8 @@ impl CodegenBackend for GotocCodegenBackend {
334335
let mut units = CodegenUnits::new(&queries, tcx);
335336
let mut modifies_instances = vec![];
336337
let mut loop_contracts_instances = vec![];
338+
339+
let template_passes = GlobalPasses::new(&queries, tcx);
337340
// Cross-crate collecting of all items that are reachable from the crate harnesses.
338341
for unit in units.iter() {
339342
// We reset the body cache for now because each codegen unit has different
@@ -343,7 +346,6 @@ impl CodegenBackend for GotocCodegenBackend {
343346
// (They all share the same options.)
344347
let template_transformer = BodyTransformation::new(&queries, tcx, unit);
345348
for harness in &unit.harnesses {
346-
let transformer = template_transformer.clone_empty();
347349
let model_path = units.harness_model_path(*harness).unwrap();
348350
let is_automatic_harness = units.is_automatic_harness(harness);
349351
let contract_metadata =
@@ -355,7 +357,8 @@ impl CodegenBackend for GotocCodegenBackend {
355357
&results.machine_model,
356358
contract_metadata
357359
.map(|def| rustc_internal::internal(tcx, def.def_id())),
358-
transformer,
360+
template_passes.clone(),
361+
template_transformer.clone_empty(),
359362
);
360363
if gcx.has_loop_contracts {
361364
loop_contracts_instances.push(*harness);
@@ -390,6 +393,7 @@ impl CodegenBackend for GotocCodegenBackend {
390393
&model_path,
391394
&results.machine_model,
392395
Default::default(),
396+
GlobalPasses::new(&queries, tcx),
393397
transformer,
394398
);
395399
assert!(contract_info.is_none());

kani-compiler/src/kani_middle/transform/check_uninit/delayed_ub/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use rustc_session::config::OutputType;
3131
mod initial_target_visitor;
3232
mod instrumentation_visitor;
3333

34-
#[derive(Debug)]
34+
#[derive(Debug, Clone)]
3535
pub struct DelayedUbPass {
3636
pub safety_check_type: CheckType,
3737
pub unsupported_check_type: CheckType,

kani-compiler/src/kani_middle/transform/dump_mir_pass.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use std::io::Write;
1717
use super::BodyTransformation;
1818

1919
/// Dump all MIR bodies.
20-
#[derive(Debug)]
20+
#[derive(Debug, Clone)]
2121
pub struct DumpMirPass {
2222
enabled: bool,
2323
}

kani-compiler/src/kani_middle/transform/mod.rs

Lines changed: 43 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use crate::kani_middle::reachability::CallGraph;
2121
use crate::kani_middle::transform::body::CheckType;
2222
use crate::kani_middle::transform::check_uninit::{DelayedUbPass, UninitPass};
2323
use crate::kani_middle::transform::check_values::ValidValuePass;
24-
use crate::kani_middle::transform::clone::ClonableTransformPass;
24+
use crate::kani_middle::transform::clone::{ClonableGlobalPass, ClonableTransformPass};
2525
use crate::kani_middle::transform::contracts::{AnyModifiesPass, FunctionWithContractPass};
2626
use crate::kani_middle::transform::kani_intrinsics::IntrinsicGeneratorPass;
2727
use crate::kani_middle::transform::loop_contracts::LoopContractPass;
@@ -211,10 +211,11 @@ enum TransformationResult {
211211
NotModified,
212212
}
213213

214+
#[derive(Clone)]
214215
pub struct GlobalPasses {
215216
/// The passes that operate on the whole codegen unit, they run after all previous passes are
216217
/// done.
217-
global_passes: Vec<Box<dyn GlobalPass>>,
218+
global_passes: Vec<Box<dyn ClonableGlobalPass>>,
218219
}
219220

220221
impl GlobalPasses {
@@ -232,7 +233,7 @@ impl GlobalPasses {
232233
global_passes
233234
}
234235

235-
fn add_global_pass<P: GlobalPass + 'static>(&mut self, query_db: &QueryDb, pass: P) {
236+
fn add_global_pass<P: ClonableGlobalPass + 'static>(&mut self, query_db: &QueryDb, pass: P) {
236237
if pass.is_enabled(query_db) {
237238
self.global_passes.push(Box::new(pass))
238239
}
@@ -269,32 +270,49 @@ mod clone {
269270
//! we set both up to have blanket implementations for all `T: TransformPass + Clone`, the compiler pieces them together properly
270271
//! and we can implement `Clone` directly using the pair!
271272
272-
use crate::kani_middle::transform::TransformPass;
273+
/// Builds a new dyn compatible wrapper trait that's essentially equivalent to extending
274+
/// `$extends` with `Clone`. Requires an ident for an intermediate trait for avoiding cycles
275+
/// in the implementation.
276+
macro_rules! implement_clone {
277+
($new_trait_name: ident, $intermediate_trait_name: ident, $extends: path) => {
278+
#[allow(private_interfaces)]
279+
pub(crate) trait $new_trait_name: $extends {
280+
fn clone_there(&self) -> Box<dyn $intermediate_trait_name>;
281+
}
273282

274-
/// A wrapper trait essentially equivalent to `TransformPass + Clone`
275-
pub(crate) trait ClonableTransformPass: TransformPass {
276-
fn clone_there(&self) -> Box<dyn CloneBackIntoPass>;
277-
}
283+
impl Clone for Box<dyn $new_trait_name> {
284+
fn clone(&self) -> Self {
285+
self.clone_there().clone_back()
286+
}
287+
}
278288

279-
impl Clone for Box<dyn ClonableTransformPass> {
280-
fn clone(&self) -> Self {
281-
self.clone_there().clone_back()
282-
}
283-
}
289+
#[allow(private_interfaces)]
290+
impl<T: $extends + Clone + 'static> $new_trait_name for T {
291+
fn clone_there(&self) -> Box<dyn $intermediate_trait_name> {
292+
Box::new(self.clone())
293+
}
294+
}
284295

285-
impl<T: TransformPass + Clone + 'static> ClonableTransformPass for T {
286-
fn clone_there(&self) -> Box<dyn CloneBackIntoPass> {
287-
Box::new(self.clone())
288-
}
289-
}
296+
trait $intermediate_trait_name {
297+
fn clone_back(&self) -> Box<dyn $new_trait_name>;
298+
}
290299

291-
pub(crate) trait CloneBackIntoPass {
292-
fn clone_back(&self) -> Box<dyn ClonableTransformPass>;
300+
impl<T: $extends + Clone + 'static> $intermediate_trait_name for T {
301+
fn clone_back(&self) -> Box<dyn $new_trait_name> {
302+
Box::new(self.clone())
303+
}
304+
}
305+
};
293306
}
294307

295-
impl<T: TransformPass + Clone + 'static> CloneBackIntoPass for T {
296-
fn clone_back(&self) -> Box<dyn ClonableTransformPass> {
297-
Box::new(self.clone())
298-
}
299-
}
308+
implement_clone!(
309+
ClonableTransformPass,
310+
ClonableTransformPassMid,
311+
crate::kani_middle::transform::TransformPass
312+
);
313+
implement_clone!(
314+
ClonableGlobalPass,
315+
ClonableGlobalPassMid,
316+
crate::kani_middle::transform::GlobalPass
317+
);
300318
}

0 commit comments

Comments
 (0)