@@ -21,7 +21,7 @@ use crate::codegen_aeneas_llbc::LlbcCodegenBackend;
2121#[ cfg( feature = "cprover" ) ]
2222use crate :: codegen_cprover_gotoc:: GotocCodegenBackend ;
2323use crate :: kani_middle:: check_crate_items;
24- use crate :: kani_queries:: QueryDb ;
24+ use crate :: kani_queries:: QUERY_DB ;
2525use crate :: session:: init_session;
2626use clap:: Parser ;
2727use rustc_codegen_ssa:: traits:: CodegenBackend ;
@@ -30,7 +30,6 @@ use rustc_interface::Config;
3030use rustc_middle:: ty:: TyCtxt ;
3131use rustc_public:: rustc_internal;
3232use rustc_session:: config:: ErrorOutputType ;
33- use std:: sync:: { Arc , Mutex } ;
3433use tracing:: debug;
3534
3635/// Run the Kani flavour of the compiler.
@@ -42,54 +41,55 @@ pub fn run(args: Vec<String>) {
4241
4342/// Configure the LLBC backend (Aeneas's IR).
4443#[ allow( unused) ]
45- fn llbc_backend ( _queries : Arc < Mutex < QueryDb > > ) -> Box < dyn CodegenBackend > {
44+ fn llbc_backend ( args : Arguments ) -> Box < dyn CodegenBackend > {
4645 #[ cfg( feature = "llbc" ) ]
47- return Box :: new ( LlbcCodegenBackend :: new ( _queries) ) ;
46+ {
47+ QUERY_DB . with ( |db| db. borrow_mut ( ) . set_args ( args) ) ;
48+ return Box :: new ( LlbcCodegenBackend :: new ( ) ) ;
49+ }
4850 #[ cfg( not( feature = "llbc" ) ) ]
4951 unreachable ! ( )
5052}
5153
5254/// Configure the cprover backend that generates goto-programs.
5355#[ allow( unused) ]
54- fn cprover_backend ( _queries : Arc < Mutex < QueryDb > > ) -> Box < dyn CodegenBackend > {
56+ fn cprover_backend ( args : Arguments ) -> Box < dyn CodegenBackend > {
5557 #[ cfg( feature = "cprover" ) ]
56- return Box :: new ( GotocCodegenBackend :: new ( _queries) ) ;
58+ {
59+ QUERY_DB . with ( |db| db. borrow_mut ( ) . set_args ( args) ) ;
60+ return Box :: new ( GotocCodegenBackend :: new ( ) ) ;
61+ }
5762 #[ cfg( not( feature = "cprover" ) ) ]
5863 unreachable ! ( )
5964}
6065
6166#[ cfg( any( feature = "cprover" , feature = "llbc" ) ) ]
62- fn backend ( queries : Arc < Mutex < QueryDb > > ) -> Box < dyn CodegenBackend > {
63- let backend = queries . lock ( ) . unwrap ( ) . args ( ) . backend ;
67+ fn backend ( args : Arguments ) -> Box < dyn CodegenBackend > {
68+ let backend = args. backend ;
6469 match backend {
6570 #[ cfg( feature = "cprover" ) ]
66- BackendOption :: CProver => cprover_backend ( queries ) ,
71+ BackendOption :: CProver => cprover_backend ( args ) ,
6772 #[ cfg( feature = "llbc" ) ]
68- BackendOption :: Llbc => llbc_backend ( queries ) ,
73+ BackendOption :: Llbc => llbc_backend ( args ) ,
6974 }
7075}
7176
7277/// Fallback backend. It will trigger an error if no backend has been enabled.
7378#[ cfg( not( any( feature = "cprover" , feature = "llbc" ) ) ) ]
74- fn backend ( queries : Arc < Mutex < QueryDb > > ) -> Box < CodegenBackend > {
79+ fn backend ( args : Arguments ) -> Box < CodegenBackend > {
7580 compile_error ! ( "No backend is available. Use `cprover` or `llbc`." ) ;
7681}
7782
7883/// This object controls the compiler behavior.
7984///
8085/// It is responsible for initializing the query database, as well as controlling the compiler
8186/// state machine.
82- struct KaniCompiler {
83- /// Store the query database. The queries should be initialized as part of `config` when the
84- /// compiler state is Init.
85- /// Note that we need to share the queries with the backend before `config` is called.
86- pub queries : Arc < Mutex < QueryDb > > ,
87- }
87+ struct KaniCompiler { }
8888
8989impl KaniCompiler {
9090 /// Create a new [KaniCompiler] instance.
9191 pub fn new ( ) -> KaniCompiler {
92- KaniCompiler { queries : QueryDb :: new ( ) }
92+ KaniCompiler { }
9393 }
9494
9595 /// Compile the current crate with the given arguments.
@@ -107,19 +107,17 @@ impl Callbacks for KaniCompiler {
107107 /// Configure the [KaniCompiler] `self` object during the [CompilationStage::Init].
108108 fn config ( & mut self , config : & mut Config ) {
109109 let mut args = vec ! [ "kani-compiler" . to_string( ) ] ;
110- config. make_codegen_backend = Some ( Box :: new ( {
111- let queries = self . queries . clone ( ) ;
112- move |_cfg| backend ( queries)
113- } ) ) ;
114110 // `kani-driver` passes the `kani-compiler` specific arguments through llvm-args, so extract them here.
115111 args. extend ( config. opts . cg . llvm_args . iter ( ) . cloned ( ) ) ;
116112 let args = Arguments :: parse_from ( args) ;
117113 init_session ( & args, matches ! ( config. opts. error_format, ErrorOutputType :: Json { .. } ) ) ;
118114
119- // Configure queries.
120- let queries = & mut ( * self . queries . lock ( ) . unwrap ( ) ) ;
121- queries. set_args ( args) ;
122- debug ! ( ?queries, "config end" ) ;
115+ // Capture args in the closure so they're available when the backend is created
116+ // (potentially on a different thread).
117+ config. make_codegen_backend = Some ( Box :: new ( {
118+ let args = args. clone ( ) ;
119+ move |_cfg| backend ( args)
120+ } ) ) ;
123121 }
124122
125123 /// After analysis, we check the crate items for Kani API misuse or configuration issues.
@@ -129,7 +127,8 @@ impl Callbacks for KaniCompiler {
129127 tcx : TyCtxt < ' _ > ,
130128 ) -> Compilation {
131129 rustc_internal:: run ( tcx, || {
132- check_crate_items ( tcx, self . queries . lock ( ) . unwrap ( ) . args ( ) . ignore_global_asm ) ;
130+ let ignore_global_asm = QUERY_DB . with ( |db| db. borrow ( ) . args ( ) . ignore_global_asm ) ;
131+ check_crate_items ( tcx, ignore_global_asm) ;
133132 } )
134133 . unwrap ( ) ;
135134 Compilation :: Continue
0 commit comments