11//! The AOT driver uses [`cranelift_object`] to write object files suitable for linking into a
22//! standalone executable.
33
4+ use std:: path:: PathBuf ;
45use std:: sync:: Arc ;
56
67use rustc_codegen_ssa:: back:: metadata:: create_compressed_metadata_file;
@@ -19,7 +20,11 @@ use cranelift_object::{ObjectBuilder, ObjectModule};
1920use crate :: global_asm:: GlobalAsmConfig ;
2021use crate :: { prelude:: * , BackendConfig } ;
2122
22- struct ModuleCodegenResult ( CompiledModule , Option < ( WorkProductId , WorkProduct ) > ) ;
23+ struct ModuleCodegenResult (
24+ CompiledModule ,
25+ Option < CompiledModule > ,
26+ Option < ( WorkProductId , WorkProduct ) > ,
27+ ) ;
2328
2429impl < HCX > HashStable < HCX > for ModuleCodegenResult {
2530 fn hash_stable ( & self , _: & mut HCX , _: & mut StableHasher ) {
@@ -42,11 +47,15 @@ impl OngoingCodegen {
4247 let mut modules = vec ! [ ] ;
4348
4449 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;
4652 if let Some ( ( work_product_id, work_product) ) = work_product {
4753 work_products. insert ( work_product_id, work_product) ;
4854 }
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+ }
5059 }
5160
5261 (
@@ -80,6 +89,7 @@ fn emit_module(
8089 module : ObjectModule ,
8190 debug : Option < DebugContext < ' _ > > ,
8291 unwind_context : UnwindContext ,
92+ global_asm_object_file : Option < PathBuf > ,
8393) -> ModuleCodegenResult {
8494 let mut product = module. finish ( ) ;
8595
@@ -100,6 +110,12 @@ fn emit_module(
100110
101111 let work_product = if backend_config. disable_incr_cache {
102112 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+ )
103119 } else {
104120 rustc_incremental:: copy_cgu_workproduct_to_incr_comp_cache_dir (
105121 tcx. sess ,
@@ -109,35 +125,78 @@ fn emit_module(
109125 } ;
110126
111127 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+ } ) ,
113142 work_product,
114143 )
115144}
116145
117146fn reuse_workproduct_for_cgu ( tcx : TyCtxt < ' _ > , cgu : & CodegenUnit < ' _ > ) -> ModuleCodegenResult {
118147 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 (
121151 & tcx. sess ,
122152 & work_product. saved_files . get ( "o" ) . expect ( "no saved object file in work product" ) ,
123153 ) ;
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) {
125156 tcx. sess . err ( & format ! (
126157 "unable to copy {} to {}: {}" ,
127- source_file . display( ) ,
128- obj_out . display( ) ,
158+ source_file_regular . display( ) ,
159+ obj_out_regular . display( ) ,
129160 err
130161 ) ) ;
131162 }
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+ } ;
132180
133181 ModuleCodegenResult (
134182 CompiledModule {
135183 name : cgu. name ( ) . to_string ( ) ,
136184 kind : ModuleKind :: Regular ,
137- object : Some ( obj_out ) ,
185+ object : Some ( obj_out_regular ) ,
138186 dwarf_object : None ,
139187 bytecode : None ,
140188 } ,
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+ } ,
141200 Some ( ( cgu. work_product_id ( ) , work_product) ) ,
142201 )
143202}
@@ -191,6 +250,15 @@ fn module_codegen(
191250 cgu. is_primary ( ) ,
192251 ) ;
193252
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+
194262 let debug_context = cx. debug_context ;
195263 let unwind_context = cx. unwind_context ;
196264 let codegen_result = tcx. sess . time ( "write object file" , || {
@@ -202,18 +270,10 @@ fn module_codegen(
202270 module,
203271 debug_context,
204272 unwind_context,
273+ global_asm_object_file,
205274 )
206275 } ) ;
207276
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-
217277 codegen_result
218278}
219279
@@ -281,15 +341,17 @@ pub(crate) fn run_aot(
281341 crate :: allocator:: codegen ( tcx, & mut allocator_module, & mut allocator_unwind_context) ;
282342
283343 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 (
285345 tcx,
286346 & backend_config,
287347 "allocator_shim" . to_string ( ) ,
288348 ModuleKind :: Allocator ,
289349 allocator_module,
290350 None ,
291351 allocator_unwind_context,
352+ None ,
292353 ) ;
354+ assert ! ( module_global_asm. is_none( ) ) ;
293355 if let Some ( ( id, product) ) = work_product {
294356 work_products. insert ( id, product) ;
295357 }
0 commit comments