@@ -5,24 +5,50 @@ use rustc_index::vec::IndexVec;
5
5
use rustc_middle:: ty:: adjustment:: PointerCast ;
6
6
use rustc_middle:: ty:: layout:: FnAbiOf ;
7
7
use rustc_middle:: ty:: print:: with_no_trimmed_paths;
8
+ use rustc_middle:: ty:: SymbolName ;
8
9
9
10
use indexmap:: IndexSet ;
10
11
11
12
use crate :: constant:: ConstantCx ;
12
13
use crate :: prelude:: * ;
13
14
use crate :: pretty_clif:: CommentWriter ;
14
15
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 > (
16
27
cx : & mut crate :: CodegenCx < ' tcx > ,
28
+ cached_context : & mut Context ,
17
29
module : & mut dyn Module ,
18
30
instance : Instance < ' tcx > ,
19
31
) {
20
32
let tcx = cx. tcx ;
21
-
22
33
let _inst_guard =
23
34
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 > {
24
48
debug_assert ! ( !instance. substs. needs_infer( ) ) ;
25
49
50
+ let tcx = cx. tcx ;
51
+
26
52
let mir = tcx. instance_mir ( instance. def ) ;
27
53
let _mir_guard = crate :: PrintOnPanic ( || {
28
54
let mut buf = Vec :: new ( ) ;
@@ -38,11 +64,10 @@ pub(crate) fn codegen_fn<'tcx>(
38
64
let sig = get_function_sig ( tcx, module. isa ( ) . triple ( ) , instance) ;
39
65
let func_id = module. declare_function ( symbol_name. name , Linkage :: Local , & sig) . unwrap ( ) ;
40
66
41
- cx. cached_context . clear ( ) ;
42
-
43
67
// Make the FunctionBuilder
44
68
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 ( ) ;
46
71
func. name = ExternalName :: user ( 0 , func_id. as_u32 ( ) ) ;
47
72
func. signature = sig;
48
73
func. collect_debug_info ( ) ;
@@ -82,27 +107,7 @@ pub(crate) fn codegen_fn<'tcx>(
82
107
next_ssa_var : 0 ,
83
108
} ;
84
109
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) ) ;
106
111
107
112
// Recover all necessary data from fx, before accessing func will prevent future access to it.
108
113
let instance = fx. instance ;
@@ -124,36 +129,31 @@ pub(crate) fn codegen_fn<'tcx>(
124
129
// Verify function
125
130
verify_func ( tcx, & clif_comments, & func) ;
126
131
127
- compile_fn (
128
- cx,
129
- module,
132
+ CodegenedFunction {
130
133
instance,
131
- symbol_name. name ,
134
+ symbol_name,
132
135
func_id,
133
136
func,
134
137
clif_comments,
135
138
source_info_set,
136
139
local_map,
137
- ) ;
140
+ }
138
141
}
139
142
140
143
fn compile_fn < ' tcx > (
141
144
cx : & mut crate :: CodegenCx < ' tcx > ,
145
+ cached_context : & mut Context ,
142
146
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 > ,
150
148
) {
151
149
let tcx = cx. tcx ;
152
150
151
+ let mut clif_comments = codegened_func. clif_comments ;
152
+
153
153
// Store function in context
154
- let context = & mut cx . cached_context ;
154
+ let context = cached_context;
155
155
context. clear ( ) ;
156
- context. func = func;
156
+ context. func = codegened_func . func ;
157
157
158
158
// If the return block is not reachable, then the SSA builder may have inserted an `iconst.i128`
159
159
// instruction, which doesn't have an encoding.
@@ -170,7 +170,7 @@ fn compile_fn<'tcx>(
170
170
crate :: optimize:: optimize_function (
171
171
tcx,
172
172
module. isa ( ) ,
173
- instance,
173
+ codegened_func . instance ,
174
174
context,
175
175
& mut clif_comments,
176
176
) ;
@@ -206,23 +206,23 @@ fn compile_fn<'tcx>(
206
206
// Define function
207
207
tcx. sess . time ( "define function" , || {
208
208
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 ( ) ;
210
210
} ) ;
211
211
212
212
// Write optimized function to file for debugging
213
213
crate :: pretty_clif:: write_clif_file (
214
214
tcx,
215
215
"opt" ,
216
216
module. isa ( ) ,
217
- instance,
217
+ codegened_func . instance ,
218
218
& context. func ,
219
219
& clif_comments,
220
220
) ;
221
221
222
222
if let Some ( disasm) = & context. mach_compile_result . as_ref ( ) . unwrap ( ) . disasm {
223
223
crate :: pretty_clif:: write_ir_file (
224
224
tcx,
225
- || format ! ( "{}.vcode" , tcx. symbol_name( instance) . name) ,
225
+ || format ! ( "{}.vcode" , tcx. symbol_name( codegened_func . instance) . name) ,
226
226
|file| file. write_all ( disasm. as_bytes ( ) ) ,
227
227
)
228
228
}
@@ -234,16 +234,16 @@ fn compile_fn<'tcx>(
234
234
tcx. sess . time ( "generate debug info" , || {
235
235
if let Some ( debug_context) = debug_context {
236
236
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 ,
240
240
isa,
241
241
context,
242
- & source_info_set,
243
- local_map,
242
+ & codegened_func . source_info_set ,
243
+ codegened_func . local_map ,
244
244
) ;
245
245
}
246
- unwind_context. add_function ( func_id, & context, isa) ;
246
+ unwind_context. add_function ( codegened_func . func_id , & context, isa) ;
247
247
} ) ;
248
248
}
249
249
@@ -269,7 +269,27 @@ pub(crate) fn verify_func(
269
269
} ) ;
270
270
}
271
271
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
+
273
293
for ( bb, bb_data) in fx. mir . basic_blocks ( ) . iter_enumerated ( ) {
274
294
let block = fx. get_block ( bb) ;
275
295
fx. bcx . switch_to_block ( block) ;
0 commit comments