@@ -5,24 +5,50 @@ use rustc_index::vec::IndexVec;
55use rustc_middle:: ty:: adjustment:: PointerCast ;
66use rustc_middle:: ty:: layout:: FnAbiOf ;
77use rustc_middle:: ty:: print:: with_no_trimmed_paths;
8+ use rustc_middle:: ty:: SymbolName ;
89
910use indexmap:: IndexSet ;
1011
1112use crate :: constant:: ConstantCx ;
1213use crate :: prelude:: * ;
1314use crate :: pretty_clif:: CommentWriter ;
1415
15- pub ( crate ) fn codegen_fn < ' tcx > (
16+ struct CodegenedFunction < ' tcx > {
17+ instance : Instance < ' tcx > ,
18+ symbol_name : SymbolName < ' tcx > ,
19+ func_id : FuncId ,
20+ func : Function ,
21+ clif_comments : CommentWriter ,
22+ source_info_set : IndexSet < SourceInfo > ,
23+ local_map : IndexVec < mir:: Local , CPlace < ' tcx > > ,
24+ }
25+
26+ pub ( crate ) fn codegen_and_compile_fn < ' tcx > (
1627 cx : & mut crate :: CodegenCx < ' tcx > ,
28+ cached_context : & mut Context ,
1729 module : & mut dyn Module ,
1830 instance : Instance < ' tcx > ,
1931) {
2032 let tcx = cx. tcx ;
21-
2233 let _inst_guard =
2334 crate :: PrintOnPanic ( || format ! ( "{:?} {}" , instance, tcx. symbol_name( instance) . name) ) ;
35+
36+ let cached_func = std:: mem:: replace ( & mut cached_context. func , Function :: new ( ) ) ;
37+ let codegened_func = codegen_fn ( cx, cached_func, module, instance) ;
38+
39+ compile_fn ( cx, cached_context, module, codegened_func) ;
40+ }
41+
42+ fn codegen_fn < ' tcx > (
43+ cx : & mut crate :: CodegenCx < ' tcx > ,
44+ cached_func : Function ,
45+ module : & mut dyn Module ,
46+ instance : Instance < ' tcx > ,
47+ ) -> CodegenedFunction < ' tcx > {
2448 debug_assert ! ( !instance. substs. needs_infer( ) ) ;
2549
50+ let tcx = cx. tcx ;
51+
2652 let mir = tcx. instance_mir ( instance. def ) ;
2753 let _mir_guard = crate :: PrintOnPanic ( || {
2854 let mut buf = Vec :: new ( ) ;
@@ -38,11 +64,10 @@ pub(crate) fn codegen_fn<'tcx>(
3864 let sig = get_function_sig ( tcx, module. isa ( ) . triple ( ) , instance) ;
3965 let func_id = module. declare_function ( symbol_name. name , Linkage :: Local , & sig) . unwrap ( ) ;
4066
41- cx. cached_context . clear ( ) ;
42-
4367 // Make the FunctionBuilder
4468 let mut func_ctx = FunctionBuilderContext :: new ( ) ;
45- let mut func = std:: mem:: replace ( & mut cx. cached_context . func , Function :: new ( ) ) ;
69+ let mut func = cached_func;
70+ func. clear ( ) ;
4671 func. name = ExternalName :: user ( 0 , func_id. as_u32 ( ) ) ;
4772 func. signature = sig;
4873 func. collect_debug_info ( ) ;
@@ -82,27 +107,7 @@ pub(crate) fn codegen_fn<'tcx>(
82107 next_ssa_var : 0 ,
83108 } ;
84109
85- let arg_uninhabited = fx
86- . mir
87- . args_iter ( )
88- . any ( |arg| fx. layout_of ( fx. monomorphize ( fx. mir . local_decls [ arg] . ty ) ) . abi . is_uninhabited ( ) ) ;
89-
90- if !crate :: constant:: check_constants ( & mut fx) {
91- fx. bcx . append_block_params_for_function_params ( fx. block_map [ START_BLOCK ] ) ;
92- fx. bcx . switch_to_block ( fx. block_map [ START_BLOCK ] ) ;
93- // compilation should have been aborted
94- fx. bcx . ins ( ) . trap ( TrapCode :: UnreachableCodeReached ) ;
95- } else if arg_uninhabited {
96- fx. bcx . append_block_params_for_function_params ( fx. block_map [ START_BLOCK ] ) ;
97- fx. bcx . switch_to_block ( fx. block_map [ START_BLOCK ] ) ;
98- fx. bcx . ins ( ) . trap ( TrapCode :: UnreachableCodeReached ) ;
99- } else {
100- tcx. sess . time ( "codegen clif ir" , || {
101- tcx. sess
102- . time ( "codegen prelude" , || crate :: abi:: codegen_fn_prelude ( & mut fx, start_block) ) ;
103- codegen_fn_content ( & mut fx) ;
104- } ) ;
105- }
110+ tcx. sess . time ( "codegen clif ir" , || codegen_fn_body ( & mut fx, start_block) ) ;
106111
107112 // Recover all necessary data from fx, before accessing func will prevent future access to it.
108113 let instance = fx. instance ;
@@ -124,36 +129,31 @@ pub(crate) fn codegen_fn<'tcx>(
124129 // Verify function
125130 verify_func ( tcx, & clif_comments, & func) ;
126131
127- compile_fn (
128- cx,
129- module,
132+ CodegenedFunction {
130133 instance,
131- symbol_name. name ,
134+ symbol_name,
132135 func_id,
133136 func,
134137 clif_comments,
135138 source_info_set,
136139 local_map,
137- ) ;
140+ }
138141}
139142
140143fn compile_fn < ' tcx > (
141144 cx : & mut crate :: CodegenCx < ' tcx > ,
145+ cached_context : & mut Context ,
142146 module : & mut dyn Module ,
143- instance : Instance < ' tcx > ,
144- symbol_name : & str ,
145- func_id : FuncId ,
146- func : Function ,
147- mut clif_comments : CommentWriter ,
148- source_info_set : IndexSet < SourceInfo > ,
149- local_map : IndexVec < mir:: Local , CPlace < ' tcx > > ,
147+ codegened_func : CodegenedFunction < ' tcx > ,
150148) {
151149 let tcx = cx. tcx ;
152150
151+ let mut clif_comments = codegened_func. clif_comments ;
152+
153153 // Store function in context
154- let context = & mut cx . cached_context ;
154+ let context = cached_context;
155155 context. clear ( ) ;
156- context. func = func;
156+ context. func = codegened_func . func ;
157157
158158 // If the return block is not reachable, then the SSA builder may have inserted an `iconst.i128`
159159 // instruction, which doesn't have an encoding.
@@ -170,7 +170,7 @@ fn compile_fn<'tcx>(
170170 crate :: optimize:: optimize_function (
171171 tcx,
172172 module. isa ( ) ,
173- instance,
173+ codegened_func . instance ,
174174 context,
175175 & mut clif_comments,
176176 ) ;
@@ -206,23 +206,23 @@ fn compile_fn<'tcx>(
206206 // Define function
207207 tcx. sess . time ( "define function" , || {
208208 context. want_disasm = crate :: pretty_clif:: should_write_ir ( tcx) ;
209- module. define_function ( func_id, context) . unwrap ( ) ;
209+ module. define_function ( codegened_func . func_id , context) . unwrap ( ) ;
210210 } ) ;
211211
212212 // Write optimized function to file for debugging
213213 crate :: pretty_clif:: write_clif_file (
214214 tcx,
215215 "opt" ,
216216 module. isa ( ) ,
217- instance,
217+ codegened_func . instance ,
218218 & context. func ,
219219 & clif_comments,
220220 ) ;
221221
222222 if let Some ( disasm) = & context. mach_compile_result . as_ref ( ) . unwrap ( ) . disasm {
223223 crate :: pretty_clif:: write_ir_file (
224224 tcx,
225- || format ! ( "{}.vcode" , tcx. symbol_name( instance) . name) ,
225+ || format ! ( "{}.vcode" , tcx. symbol_name( codegened_func . instance) . name) ,
226226 |file| file. write_all ( disasm. as_bytes ( ) ) ,
227227 )
228228 }
@@ -234,16 +234,16 @@ fn compile_fn<'tcx>(
234234 tcx. sess . time ( "generate debug info" , || {
235235 if let Some ( debug_context) = debug_context {
236236 debug_context. define_function (
237- instance,
238- func_id,
239- symbol_name,
237+ codegened_func . instance ,
238+ codegened_func . func_id ,
239+ codegened_func . symbol_name . name ,
240240 isa,
241241 context,
242- & source_info_set,
243- local_map,
242+ & codegened_func . source_info_set ,
243+ codegened_func . local_map ,
244244 ) ;
245245 }
246- unwind_context. add_function ( func_id, & context, isa) ;
246+ unwind_context. add_function ( codegened_func . func_id , & context, isa) ;
247247 } ) ;
248248}
249249
@@ -269,7 +269,27 @@ pub(crate) fn verify_func(
269269 } ) ;
270270}
271271
272- fn codegen_fn_content ( fx : & mut FunctionCx < ' _ , ' _ , ' _ > ) {
272+ fn codegen_fn_body ( fx : & mut FunctionCx < ' _ , ' _ , ' _ > , start_block : Block ) {
273+ if !crate :: constant:: check_constants ( fx) {
274+ fx. bcx . append_block_params_for_function_params ( fx. block_map [ START_BLOCK ] ) ;
275+ fx. bcx . switch_to_block ( fx. block_map [ START_BLOCK ] ) ;
276+ // compilation should have been aborted
277+ fx. bcx . ins ( ) . trap ( TrapCode :: UnreachableCodeReached ) ;
278+ return ;
279+ }
280+
281+ let arg_uninhabited = fx
282+ . mir
283+ . args_iter ( )
284+ . any ( |arg| fx. layout_of ( fx. monomorphize ( fx. mir . local_decls [ arg] . ty ) ) . abi . is_uninhabited ( ) ) ;
285+ if arg_uninhabited {
286+ fx. bcx . append_block_params_for_function_params ( fx. block_map [ START_BLOCK ] ) ;
287+ fx. bcx . switch_to_block ( fx. block_map [ START_BLOCK ] ) ;
288+ fx. bcx . ins ( ) . trap ( TrapCode :: UnreachableCodeReached ) ;
289+ return ;
290+ }
291+ fx. tcx . sess . time ( "codegen prelude" , || crate :: abi:: codegen_fn_prelude ( fx, start_block) ) ;
292+
273293 for ( bb, bb_data) in fx. mir . basic_blocks ( ) . iter_enumerated ( ) {
274294 let block = fx. get_block ( bb) ;
275295 fx. bcx . switch_to_block ( block) ;
0 commit comments