@@ -11,7 +11,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
11
11
12
12
use crate :: prelude:: * ;
13
13
14
- use crate :: backend:: { Emit , WriteDebugInfo } ;
14
+ use crate :: backend:: { AddConstructor , Emit , WriteDebugInfo } ;
15
15
16
16
fn new_module ( tcx : TyCtxt < ' _ > , name : String ) -> Module < crate :: backend:: Backend > {
17
17
let module = crate :: backend:: make_module ( tcx. sess , name) ;
@@ -35,8 +35,9 @@ fn emit_module<B: Backend>(
35
35
mut module : Module < B > ,
36
36
debug : Option < DebugContext < ' _ > > ,
37
37
unwind_context : UnwindContext < ' _ > ,
38
+ map_product : impl FnOnce ( B :: Product ) -> B :: Product ,
38
39
) -> ModuleCodegenResult
39
- where B :: Product : Emit + WriteDebugInfo ,
40
+ where B :: Product : AddConstructor + Emit + WriteDebugInfo ,
40
41
{
41
42
module. finalize_definitions ( ) ;
42
43
let mut product = module. finish ( ) ;
@@ -47,6 +48,8 @@ fn emit_module<B: Backend>(
47
48
48
49
unwind_context. emit ( & mut product) ;
49
50
51
+ let product = map_product ( product) ;
52
+
50
53
let tmp_file = tcx
51
54
. output_filenames ( LOCAL_CRATE )
52
55
. temp_path ( OutputType :: Object , Some ( & name) ) ;
@@ -110,7 +113,23 @@ fn module_codegen(tcx: TyCtxt<'_>, cgu_name: rustc_span::Symbol) -> ModuleCodege
110
113
let cgu = tcx. codegen_unit ( cgu_name) ;
111
114
let mono_items = cgu. items_in_deterministic_order ( tcx) ;
112
115
113
- let module = new_module ( tcx, cgu_name. as_str ( ) . to_string ( ) ) ;
116
+ let mut module = new_module ( tcx, cgu_name. as_str ( ) . to_string ( ) ) ;
117
+
118
+ // Initialize the global atomic mutex using a constructor for proc-macros.
119
+ // FIXME implement atomic instructions in Cranelift.
120
+ let mut init_atomics_mutex_from_constructor = None ;
121
+ if tcx. sess . crate_types ( ) . contains ( & rustc_session:: config:: CrateType :: ProcMacro ) {
122
+ if mono_items. iter ( ) . any ( |( mono_item, _) | {
123
+ match mono_item {
124
+ rustc_middle:: mir:: mono:: MonoItem :: Static ( def_id) => {
125
+ tcx. symbol_name ( Instance :: mono ( tcx, * def_id) ) . name . as_str ( ) . contains ( "__rustc_proc_macro_decls_" )
126
+ }
127
+ _ => false ,
128
+ }
129
+ } ) {
130
+ init_atomics_mutex_from_constructor = Some ( crate :: atomic_shim:: init_global_lock_constructor ( & mut module, & format ! ( "{}_init_atomics_mutex" , cgu_name. as_str( ) ) ) ) ;
131
+ }
132
+ }
114
133
115
134
let mut cx = crate :: CodegenCx :: new ( tcx, module, tcx. sess . opts . debuginfo != DebugInfo :: None ) ;
116
135
super :: codegen_mono_items ( & mut cx, mono_items) ;
@@ -124,6 +143,13 @@ fn module_codegen(tcx: TyCtxt<'_>, cgu_name: rustc_span::Symbol) -> ModuleCodege
124
143
module,
125
144
debug,
126
145
unwind_context,
146
+ |mut product| {
147
+ if let Some ( func_id) = init_atomics_mutex_from_constructor {
148
+ product. add_constructor ( func_id) ;
149
+ }
150
+
151
+ product
152
+ }
127
153
) ;
128
154
129
155
codegen_global_asm ( tcx, & cgu. name ( ) . as_str ( ) , & global_asm) ;
@@ -196,6 +222,7 @@ pub(super) fn run_aot(
196
222
allocator_module,
197
223
None ,
198
224
allocator_unwind_context,
225
+ |product| product,
199
226
) ;
200
227
if let Some ( ( id, product) ) = work_product {
201
228
work_products. insert ( id, product) ;
0 commit comments