1010
1111// The rustc crates we need
1212extern crate rustc_abi;
13+ extern crate rustc_codegen_ssa;
1314extern crate rustc_data_structures;
1415extern crate rustc_driver;
1516extern crate rustc_hir;
@@ -19,6 +20,7 @@ extern crate rustc_log;
1920extern crate rustc_middle;
2021extern crate rustc_session;
2122extern crate rustc_span;
23+ extern crate rustc_target;
2224
2325/// See docs in https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc/src/main.rs
2426/// and https://github.com/rust-lang/rust/pull/146627 for why we need this.
@@ -36,19 +38,22 @@ use std::num::{NonZero, NonZeroI32};
3638use std:: ops:: Range ;
3739use std:: rc:: Rc ;
3840use std:: str:: FromStr ;
41+ use std:: sync:: Once ;
3942use std:: sync:: atomic:: { AtomicU32 , Ordering } ;
4043
4144use miri:: {
4245 BacktraceStyle , BorrowTrackerMethod , GenmcConfig , GenmcCtx , MiriConfig , MiriEntryFnType ,
4346 ProvenanceMode , TreeBorrowsParams , ValidationMode , run_genmc_mode,
4447} ;
4548use rustc_abi:: ExternAbi ;
49+ use rustc_codegen_ssa:: traits:: CodegenBackend ;
4650use rustc_data_structures:: sync:: { self , DynSync } ;
4751use rustc_driver:: Compilation ;
4852use rustc_hir:: def_id:: LOCAL_CRATE ;
4953use rustc_hir:: { self as hir, Node } ;
5054use rustc_hir_analysis:: check:: check_function_signature;
5155use rustc_interface:: interface:: Config ;
56+ use rustc_interface:: util:: DummyCodegenBackend ;
5257use rustc_log:: tracing:: debug;
5358use rustc_middle:: middle:: codegen_fn_attrs:: CodegenFnAttrFlags ;
5459use rustc_middle:: middle:: exported_symbols:: {
@@ -58,8 +63,9 @@ use rustc_middle::query::LocalCrate;
5863use rustc_middle:: traits:: { ObligationCause , ObligationCauseCode } ;
5964use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
6065use rustc_session:: EarlyDiagCtxt ;
61- use rustc_session:: config:: { CrateType , ErrorOutputType , OptLevel } ;
66+ use rustc_session:: config:: { CrateType , ErrorOutputType , OptLevel , Options } ;
6267use rustc_span:: def_id:: DefId ;
68+ use rustc_target:: spec:: Target ;
6369
6470use crate :: log:: setup:: { deinit_loggers, init_early_loggers, init_late_loggers} ;
6571
@@ -161,7 +167,31 @@ fn run_many_seeds(
161167 }
162168}
163169
170+ /// Generates the codegen backend for code that Miri will interpret: we basically
171+ /// use the dummy backend, except that we put the LLVM backend in charge of
172+ /// target features.
173+ fn make_miri_codegen_backend ( opts : & Options , target : & Target ) -> Box < dyn CodegenBackend > {
174+ let early_dcx = EarlyDiagCtxt :: new ( opts. error_format ) ;
175+
176+ // Use the target_config method of the default codegen backend (eg LLVM) to ensure the
177+ // calculated target features match said backend by respecting eg -Ctarget-cpu.
178+ let target_config_backend =
179+ rustc_interface:: util:: get_codegen_backend ( & early_dcx, & opts. sysroot , None , & target) ;
180+ let target_config_backend_init = Once :: new ( ) ;
181+
182+ Box :: new ( DummyCodegenBackend {
183+ target_config_override : Some ( Box :: new ( move |sess| {
184+ target_config_backend_init. call_once ( || target_config_backend. init ( sess) ) ;
185+ target_config_backend. target_config ( sess)
186+ } ) ) ,
187+ } )
188+ }
189+
164190impl rustc_driver:: Callbacks for MiriCompilerCalls {
191+ fn config ( & mut self , config : & mut rustc_interface:: interface:: Config ) {
192+ config. make_codegen_backend = Some ( Box :: new ( make_miri_codegen_backend) ) ;
193+ }
194+
165195 fn after_analysis < ' tcx > (
166196 & mut self ,
167197 _: & rustc_interface:: interface:: Compiler ,
@@ -244,6 +274,10 @@ struct MiriBeRustCompilerCalls {
244274impl rustc_driver:: Callbacks for MiriBeRustCompilerCalls {
245275 #[ allow( rustc:: potential_query_instability) ] // rustc_codegen_ssa (where this code is copied from) also allows this lint
246276 fn config ( & mut self , config : & mut Config ) {
277+ if self . target_crate {
278+ config. make_codegen_backend = Some ( Box :: new ( make_miri_codegen_backend) ) ;
279+ }
280+
247281 if config. opts . prints . is_empty ( ) && self . target_crate {
248282 #[ allow( rustc:: bad_opt_access) ] // tcx does not exist yet
249283 {
0 commit comments