@@ -73,6 +73,7 @@ mod type_of;
7373
7474use std:: any:: Any ;
7575use std:: sync:: Arc ;
76+ use std:: sync:: Mutex ;
7677#[ cfg( not( feature="master" ) ) ]
7778use std:: sync:: atomic:: AtomicBool ;
7879#[ cfg( not( feature="master" ) ) ]
@@ -135,9 +136,24 @@ impl TargetInfo {
135136 }
136137}
137138
139+ #[ derive( Clone , Debug ) ]
140+ pub struct LockedTargetInfo {
141+ info : Arc < Mutex < TargetInfo > > ,
142+ }
143+
144+ impl LockedTargetInfo {
145+ fn cpu_supports ( & self , feature : & str ) -> bool {
146+ self . info . lock ( ) . expect ( "lock" ) . cpu_supports ( feature)
147+ }
148+
149+ fn supports_128bit_int ( & self ) -> bool {
150+ self . info . lock ( ) . expect ( "lock" ) . supports_128bit_int ( )
151+ }
152+ }
153+
138154#[ derive( Clone ) ]
139155pub struct GccCodegenBackend {
140- target_info : Arc < TargetInfo > ,
156+ target_info : LockedTargetInfo ,
141157}
142158
143159impl CodegenBackend for GccCodegenBackend {
@@ -146,6 +162,19 @@ impl CodegenBackend for GccCodegenBackend {
146162 }
147163
148164 fn init ( & self , sess : & Session ) {
165+ #[ cfg( feature="master" ) ]
166+ {
167+ let target_cpu = target_cpu ( sess) ;
168+
169+ // Get the second TargetInfo with the correct CPU features by setting the arch.
170+ let context = Context :: default ( ) ;
171+ if target_cpu != "generic" {
172+ context. add_command_line_option ( & format ! ( "-march={}" , target_cpu) ) ;
173+ }
174+
175+ * self . target_info . info . lock ( ) . expect ( "lock" ) = context. get_target_info ( ) ;
176+ }
177+
149178 #[ cfg( feature="master" ) ]
150179 gccjit:: set_global_personality_function_name ( b"rust_eh_personality\0 " ) ;
151180 if sess. lto ( ) == Lto :: Thin {
@@ -161,7 +190,7 @@ impl CodegenBackend for GccCodegenBackend {
161190 let _int128_ty = check_context. new_c_type ( CType :: UInt128t ) ;
162191 // NOTE: we cannot just call compile() as this would require other files than libgccjit.so.
163192 check_context. compile_to_file ( gccjit:: OutputKind :: Assembler , temp_file. to_str ( ) . expect ( "path to str" ) ) ;
164- self . target_info . supports_128bit_integers . store ( check_context. get_last_error ( ) == Ok ( None ) , Ordering :: SeqCst ) ;
193+ self . target_info . info . lock ( ) . expect ( "lock" ) . supports_128bit_integers . store ( check_context. get_last_error ( ) == Ok ( None ) , Ordering :: SeqCst ) ;
165194 }
166195 }
167196
@@ -217,7 +246,7 @@ impl ExtraBackendMethods for GccCodegenBackend {
217246 }
218247
219248 fn compile_codegen_unit ( & self , tcx : TyCtxt < ' _ > , cgu_name : Symbol ) -> ( ModuleCodegen < Self :: Module > , u64 ) {
220- base:: compile_codegen_unit ( tcx, cgu_name, Arc :: clone ( & self . target_info ) )
249+ base:: compile_codegen_unit ( tcx, cgu_name, self . target_info . clone ( ) )
221250 }
222251
223252 fn target_machine_factory ( & self , _sess : & Session , _opt_level : OptLevel , _features : & [ String ] ) -> TargetMachineFactoryFn < Self > {
@@ -306,23 +335,18 @@ impl WriteBackendMethods for GccCodegenBackend {
306335#[ no_mangle]
307336pub fn __rustc_codegen_backend ( ) -> Box < dyn CodegenBackend > {
308337 #[ cfg( feature="master" ) ]
309- let target_info = {
310- // Get the native arch and check whether the target supports 128-bit integers.
311- let context = Context :: default ( ) ;
312- let arch = context. get_target_info ( ) . arch ( ) . unwrap ( ) ;
313-
314- // Get the second TargetInfo with the correct CPU features by setting the arch.
338+ let info = {
339+ // Check whether the target supports 128-bit integers.
315340 let context = Context :: default ( ) ;
316- context. add_command_line_option ( & format ! ( "-march={}" , arch. to_str( ) . unwrap( ) ) ) ;
317- Arc :: new ( context. get_target_info ( ) )
341+ Arc :: new ( Mutex :: new ( context. get_target_info ( ) ) )
318342 } ;
319343 #[ cfg( not( feature="master" ) ) ]
320- let target_info = Arc :: new ( TargetInfo {
344+ let info = Arc :: new ( Mutex :: new ( TargetInfo {
321345 supports_128bit_integers : AtomicBool :: new ( false ) ,
322- } ) ;
346+ } ) ) ;
323347
324348 Box :: new ( GccCodegenBackend {
325- target_info,
349+ target_info : LockedTargetInfo { info } ,
326350 } )
327351}
328352
@@ -356,7 +380,7 @@ pub fn target_cpu(sess: &Session) -> &str {
356380 }
357381}
358382
359- pub fn target_features ( sess : & Session , allow_unstable : bool , target_info : & Arc < TargetInfo > ) -> Vec < Symbol > {
383+ pub fn target_features ( sess : & Session , allow_unstable : bool , target_info : & LockedTargetInfo ) -> Vec < Symbol > {
360384 supported_target_features ( sess)
361385 . iter ( )
362386 . filter_map (
0 commit comments