1
1
//! The AOT driver uses [`cranelift_object`] to write object files suitable for linking into a
2
2
//! standalone executable.
3
3
4
+ use std:: path:: PathBuf ;
4
5
use std:: sync:: Arc ;
5
6
6
7
use rustc_codegen_ssa:: back:: metadata:: create_compressed_metadata_file;
@@ -19,7 +20,11 @@ use cranelift_object::{ObjectBuilder, ObjectModule};
19
20
use crate :: global_asm:: GlobalAsmConfig ;
20
21
use crate :: { prelude:: * , BackendConfig } ;
21
22
22
- struct ModuleCodegenResult ( CompiledModule , Option < ( WorkProductId , WorkProduct ) > ) ;
23
+ struct ModuleCodegenResult (
24
+ CompiledModule ,
25
+ Option < CompiledModule > ,
26
+ Option < ( WorkProductId , WorkProduct ) > ,
27
+ ) ;
23
28
24
29
impl < HCX > HashStable < HCX > for ModuleCodegenResult {
25
30
fn hash_stable ( & self , _: & mut HCX , _: & mut StableHasher ) {
@@ -42,11 +47,15 @@ impl OngoingCodegen {
42
47
let mut modules = vec ! [ ] ;
43
48
44
49
for module_codegen_result in self . modules {
45
- let ModuleCodegenResult ( module, work_product) = module_codegen_result;
50
+ let ModuleCodegenResult ( module_regular, module_global_asm, work_product) =
51
+ module_codegen_result;
46
52
if let Some ( ( work_product_id, work_product) ) = work_product {
47
53
work_products. insert ( work_product_id, work_product) ;
48
54
}
49
- modules. push ( module) ;
55
+ modules. push ( module_regular) ;
56
+ if let Some ( module_global_asm) = module_global_asm {
57
+ modules. push ( module_global_asm) ;
58
+ }
50
59
}
51
60
52
61
(
@@ -80,6 +89,7 @@ fn emit_module(
80
89
module : ObjectModule ,
81
90
debug : Option < DebugContext < ' _ > > ,
82
91
unwind_context : UnwindContext ,
92
+ global_asm_object_file : Option < PathBuf > ,
83
93
) -> ModuleCodegenResult {
84
94
let mut product = module. finish ( ) ;
85
95
@@ -100,6 +110,12 @@ fn emit_module(
100
110
101
111
let work_product = if backend_config. disable_incr_cache {
102
112
None
113
+ } else if let Some ( global_asm_object_file) = & global_asm_object_file {
114
+ rustc_incremental:: copy_cgu_workproduct_to_incr_comp_cache_dir (
115
+ tcx. sess ,
116
+ & name,
117
+ & [ ( "o" , & tmp_file) , ( "asm.o" , global_asm_object_file) ] ,
118
+ )
103
119
} else {
104
120
rustc_incremental:: copy_cgu_workproduct_to_incr_comp_cache_dir (
105
121
tcx. sess ,
@@ -109,35 +125,78 @@ fn emit_module(
109
125
} ;
110
126
111
127
ModuleCodegenResult (
112
- CompiledModule { name, kind, object : Some ( tmp_file) , dwarf_object : None , bytecode : None } ,
128
+ CompiledModule {
129
+ name : name. clone ( ) ,
130
+ kind,
131
+ object : Some ( tmp_file) ,
132
+ dwarf_object : None ,
133
+ bytecode : None ,
134
+ } ,
135
+ global_asm_object_file. map ( |global_asm_object_file| CompiledModule {
136
+ name : format ! ( "{name}.asm" ) ,
137
+ kind,
138
+ object : Some ( global_asm_object_file) ,
139
+ dwarf_object : None ,
140
+ bytecode : None ,
141
+ } ) ,
113
142
work_product,
114
143
)
115
144
}
116
145
117
146
fn reuse_workproduct_for_cgu ( tcx : TyCtxt < ' _ > , cgu : & CodegenUnit < ' _ > ) -> ModuleCodegenResult {
118
147
let work_product = cgu. previous_work_product ( tcx) ;
119
- let obj_out = tcx. output_filenames ( ( ) ) . temp_path ( OutputType :: Object , Some ( cgu. name ( ) . as_str ( ) ) ) ;
120
- let source_file = rustc_incremental:: in_incr_comp_dir_sess (
148
+ let obj_out_regular =
149
+ tcx. output_filenames ( ( ) ) . temp_path ( OutputType :: Object , Some ( cgu. name ( ) . as_str ( ) ) ) ;
150
+ let source_file_regular = rustc_incremental:: in_incr_comp_dir_sess (
121
151
& tcx. sess ,
122
152
& work_product. saved_files . get ( "o" ) . expect ( "no saved object file in work product" ) ,
123
153
) ;
124
- if let Err ( err) = rustc_fs_util:: link_or_copy ( & source_file, & obj_out) {
154
+
155
+ if let Err ( err) = rustc_fs_util:: link_or_copy ( & source_file_regular, & obj_out_regular) {
125
156
tcx. sess . err ( & format ! (
126
157
"unable to copy {} to {}: {}" ,
127
- source_file . display( ) ,
128
- obj_out . display( ) ,
158
+ source_file_regular . display( ) ,
159
+ obj_out_regular . display( ) ,
129
160
err
130
161
) ) ;
131
162
}
163
+ let obj_out_global_asm =
164
+ crate :: global_asm:: add_file_stem_postfix ( obj_out_regular. clone ( ) , ".asm" ) ;
165
+ let has_global_asm = if let Some ( asm_o) = work_product. saved_files . get ( "asm.o" ) {
166
+ let source_file_global_asm = rustc_incremental:: in_incr_comp_dir_sess ( & tcx. sess , asm_o) ;
167
+ if let Err ( err) = rustc_fs_util:: link_or_copy ( & source_file_global_asm, & obj_out_global_asm)
168
+ {
169
+ tcx. sess . err ( & format ! (
170
+ "unable to copy {} to {}: {}" ,
171
+ source_file_regular. display( ) ,
172
+ obj_out_regular. display( ) ,
173
+ err
174
+ ) ) ;
175
+ }
176
+ true
177
+ } else {
178
+ false
179
+ } ;
132
180
133
181
ModuleCodegenResult (
134
182
CompiledModule {
135
183
name : cgu. name ( ) . to_string ( ) ,
136
184
kind : ModuleKind :: Regular ,
137
- object : Some ( obj_out ) ,
185
+ object : Some ( obj_out_regular ) ,
138
186
dwarf_object : None ,
139
187
bytecode : None ,
140
188
} ,
189
+ if has_global_asm {
190
+ Some ( CompiledModule {
191
+ name : cgu. name ( ) . to_string ( ) ,
192
+ kind : ModuleKind :: Regular ,
193
+ object : Some ( obj_out_global_asm) ,
194
+ dwarf_object : None ,
195
+ bytecode : None ,
196
+ } )
197
+ } else {
198
+ None
199
+ } ,
141
200
Some ( ( cgu. work_product_id ( ) , work_product) ) ,
142
201
)
143
202
}
@@ -191,6 +250,15 @@ fn module_codegen(
191
250
cgu. is_primary ( ) ,
192
251
) ;
193
252
253
+ let global_asm_object_file = match crate :: global_asm:: compile_global_asm (
254
+ & global_asm_config,
255
+ cgu. name ( ) . as_str ( ) ,
256
+ & cx. global_asm ,
257
+ ) {
258
+ Ok ( global_asm_object_file) => global_asm_object_file,
259
+ Err ( err) => tcx. sess . fatal ( & err) ,
260
+ } ;
261
+
194
262
let debug_context = cx. debug_context ;
195
263
let unwind_context = cx. unwind_context ;
196
264
let codegen_result = tcx. sess . time ( "write object file" , || {
@@ -202,18 +270,10 @@ fn module_codegen(
202
270
module,
203
271
debug_context,
204
272
unwind_context,
273
+ global_asm_object_file,
205
274
)
206
275
} ) ;
207
276
208
- match crate :: global_asm:: compile_global_asm (
209
- & global_asm_config,
210
- cgu. name ( ) . as_str ( ) ,
211
- & cx. global_asm ,
212
- ) {
213
- Ok ( ( ) ) => { }
214
- Err ( err) => tcx. sess . fatal ( & err) ,
215
- }
216
-
217
277
codegen_result
218
278
}
219
279
@@ -281,15 +341,17 @@ pub(crate) fn run_aot(
281
341
crate :: allocator:: codegen ( tcx, & mut allocator_module, & mut allocator_unwind_context) ;
282
342
283
343
let allocator_module = if created_alloc_shim {
284
- let ModuleCodegenResult ( module, work_product) = emit_module (
344
+ let ModuleCodegenResult ( module, module_global_asm , work_product) = emit_module (
285
345
tcx,
286
346
& backend_config,
287
347
"allocator_shim" . to_string ( ) ,
288
348
ModuleKind :: Allocator ,
289
349
allocator_module,
290
350
None ,
291
351
allocator_unwind_context,
352
+ None ,
292
353
) ;
354
+ assert ! ( module_global_asm. is_none( ) ) ;
293
355
if let Some ( ( id, product) ) = work_product {
294
356
work_products. insert ( id, product) ;
295
357
}
0 commit comments