@@ -80,15 +80,15 @@ impl EnumClone for AtomicOrdering {
80
80
81
81
pub struct Builder < ' a : ' gcc , ' gcc , ' tcx > {
82
82
pub cx : & ' a CodegenCx < ' gcc , ' tcx > ,
83
- pub block : Option < Block < ' gcc > > ,
83
+ pub block : Block < ' gcc > ,
84
84
stack_var_count : Cell < usize > ,
85
85
}
86
86
87
87
impl < ' a , ' gcc , ' tcx > Builder < ' a , ' gcc , ' tcx > {
88
- fn with_cx ( cx : & ' a CodegenCx < ' gcc , ' tcx > ) -> Self {
88
+ fn with_cx ( cx : & ' a CodegenCx < ' gcc , ' tcx > , block : Block < ' gcc > ) -> Self {
89
89
Builder {
90
90
cx,
91
- block : None ,
91
+ block,
92
92
stack_var_count : Cell :: new ( 0 ) ,
93
93
}
94
94
}
@@ -114,10 +114,9 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
114
114
let after_block = func. new_block ( "after_while" ) ;
115
115
self . llbb ( ) . end_with_jump ( None , while_block) ;
116
116
117
- // NOTE: since jumps were added and compare_exchange doesn't expect this, the current blocks in the
117
+ // NOTE: since jumps were added and compare_exchange doesn't expect this, the current block in the
118
118
// state need to be updated.
119
- self . block = Some ( while_block) ;
120
- * self . cx . current_block . borrow_mut ( ) = Some ( while_block) ;
119
+ self . switch_to_block ( while_block) ;
121
120
122
121
let comparison_operator =
123
122
match operation {
@@ -132,10 +131,9 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
132
131
133
132
while_block. end_with_conditional ( None , cond, while_block, after_block) ;
134
133
135
- // NOTE: since jumps were added in a place rustc does not expect, the current blocks in the
134
+ // NOTE: since jumps were added in a place rustc does not expect, the current block in the
136
135
// state need to be updated.
137
- self . block = Some ( after_block) ;
138
- * self . cx . current_block . borrow_mut ( ) = Some ( after_block) ;
136
+ self . switch_to_block ( after_block) ;
139
137
140
138
return_value. to_rvalue ( )
141
139
}
@@ -245,7 +243,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
245
243
}
246
244
247
245
pub fn current_func ( & self ) -> Function < ' gcc > {
248
- self . block . expect ( "block" ) . get_function ( )
246
+ self . block . get_function ( )
249
247
}
250
248
251
249
fn function_call ( & mut self , func : RValue < ' gcc > , args : & [ RValue < ' gcc > ] , _funclet : Option < & Funclet > ) -> RValue < ' gcc > {
@@ -256,17 +254,16 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
256
254
// gccjit requires to use the result of functions, even when it's not used.
257
255
// That's why we assign the result to a local or call add_eval().
258
256
let return_type = func. get_return_type ( ) ;
259
- let current_block = self . current_block . borrow ( ) . expect ( "block" ) ;
260
257
let void_type = self . context . new_type :: < ( ) > ( ) ;
261
- let current_func = current_block . get_function ( ) ;
258
+ let current_func = self . block . get_function ( ) ;
262
259
if return_type != void_type {
263
260
unsafe { RETURN_VALUE_COUNT += 1 } ;
264
261
let result = current_func. new_local ( None , return_type, & format ! ( "returnValue{}" , unsafe { RETURN_VALUE_COUNT } ) ) ;
265
- current_block . add_assignment ( None , result, self . cx . context . new_call ( None , func, & args) ) ;
262
+ self . block . add_assignment ( None , result, self . cx . context . new_call ( None , func, & args) ) ;
266
263
result. to_rvalue ( )
267
264
}
268
265
else {
269
- current_block . add_eval ( None , self . cx . context . new_call ( None , func, & args) ) ;
266
+ self . block . add_eval ( None , self . cx . context . new_call ( None , func, & args) ) ;
270
267
// Return dummy value when not having return value.
271
268
self . context . new_rvalue_from_long ( self . isize_type , 0 )
272
269
}
@@ -279,9 +276,8 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
279
276
// That's why we assign the result to a local or call add_eval().
280
277
let gcc_func = func_ptr. get_type ( ) . dyncast_function_ptr_type ( ) . expect ( "function ptr" ) ;
281
278
let mut return_type = gcc_func. get_return_type ( ) ;
282
- let current_block = self . current_block . borrow ( ) . expect ( "block" ) ;
283
279
let void_type = self . context . new_type :: < ( ) > ( ) ;
284
- let current_func = current_block . get_function ( ) ;
280
+ let current_func = self . block . get_function ( ) ;
285
281
286
282
// FIXME(antoyo): As a temporary workaround for unsupported LLVM intrinsics.
287
283
if gcc_func. get_param_count ( ) == 0 && format ! ( "{:?}" , func_ptr) == "__builtin_ia32_pmovmskb128" {
@@ -291,20 +287,20 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
291
287
if return_type != void_type {
292
288
unsafe { RETURN_VALUE_COUNT += 1 } ;
293
289
let result = current_func. new_local ( None , return_type, & format ! ( "ptrReturnValue{}" , unsafe { RETURN_VALUE_COUNT } ) ) ;
294
- current_block . add_assignment ( None , result, self . cx . context . new_call_through_ptr ( None , func_ptr, & args) ) ;
290
+ self . block . add_assignment ( None , result, self . cx . context . new_call_through_ptr ( None , func_ptr, & args) ) ;
295
291
result. to_rvalue ( )
296
292
}
297
293
else {
298
294
if gcc_func. get_param_count ( ) == 0 {
299
295
// FIXME(antoyo): As a temporary workaround for unsupported LLVM intrinsics.
300
- current_block . add_eval ( None , self . cx . context . new_call_through_ptr ( None , func_ptr, & [ ] ) ) ;
296
+ self . block . add_eval ( None , self . cx . context . new_call_through_ptr ( None , func_ptr, & [ ] ) ) ;
301
297
}
302
298
else {
303
- current_block . add_eval ( None , self . cx . context . new_call_through_ptr ( None , func_ptr, & args) ) ;
299
+ self . block . add_eval ( None , self . cx . context . new_call_through_ptr ( None , func_ptr, & args) ) ;
304
300
}
305
301
// Return dummy value when not having return value.
306
302
let result = current_func. new_local ( None , self . isize_type , "dummyValueThatShouldNeverBeUsed" ) ;
307
- current_block . add_assignment ( None , result, self . context . new_rvalue_from_long ( self . isize_type , 0 ) ) ;
303
+ self . block . add_assignment ( None , result, self . context . new_rvalue_from_long ( self . isize_type , 0 ) ) ;
308
304
result. to_rvalue ( )
309
305
}
310
306
}
@@ -313,12 +309,11 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
313
309
// gccjit requires to use the result of functions, even when it's not used.
314
310
// That's why we assign the result to a local.
315
311
let return_type = self . context . new_type :: < bool > ( ) ;
316
- let current_block = self . current_block . borrow ( ) . expect ( "block" ) ;
317
- let current_func = current_block. get_function ( ) ;
312
+ let current_func = self . block . get_function ( ) ;
318
313
// TODO(antoyo): return the new_call() directly? Since the overflow function has no side-effects.
319
314
unsafe { RETURN_VALUE_COUNT += 1 } ;
320
315
let result = current_func. new_local ( None , return_type, & format ! ( "overflowReturnValue{}" , unsafe { RETURN_VALUE_COUNT } ) ) ;
321
- current_block . add_assignment ( None , result, self . cx . context . new_call ( None , func, & args) ) ;
316
+ self . block . add_assignment ( None , result, self . cx . context . new_call ( None , func, & args) ) ;
322
317
result. to_rvalue ( )
323
318
}
324
319
}
@@ -384,14 +379,11 @@ impl<'gcc, 'tcx> BackendTypes for Builder<'_, 'gcc, 'tcx> {
384
379
385
380
impl < ' a , ' gcc , ' tcx > BuilderMethods < ' a , ' tcx > for Builder < ' a , ' gcc , ' tcx > {
386
381
fn build ( cx : & ' a CodegenCx < ' gcc , ' tcx > , block : Block < ' gcc > ) -> Self {
387
- let mut bx = Builder :: with_cx ( cx) ;
388
- * cx. current_block . borrow_mut ( ) = Some ( block) ;
389
- bx. block = Some ( block) ;
390
- bx
382
+ Builder :: with_cx ( cx, block)
391
383
}
392
384
393
385
fn llbb ( & self ) -> Block < ' gcc > {
394
- self . block . expect ( "block" )
386
+ self . block
395
387
}
396
388
397
389
fn append_block ( cx : & ' a CodegenCx < ' gcc , ' tcx > , func : RValue < ' gcc > , name : & str ) -> Block < ' gcc > {
@@ -405,8 +397,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
405
397
}
406
398
407
399
fn switch_to_block ( & mut self , block : Self :: BasicBlock ) {
408
- * self . cx . current_block . borrow_mut ( ) = Some ( block) ;
409
- self . block = Some ( block) ;
400
+ self . block = block;
410
401
}
411
402
412
403
fn ret_void ( & mut self ) {
@@ -441,7 +432,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
441
432
let on_val = self . const_uint_big ( typ, on_val) ;
442
433
gcc_cases. push ( self . context . new_case ( on_val, on_val, dest) ) ;
443
434
}
444
- self . block . expect ( "block" ) . end_with_switch ( None , value, default_block, & gcc_cases) ;
435
+ self . block . end_with_switch ( None , value, default_block, & gcc_cases) ;
445
436
}
446
437
447
438
fn invoke ( & mut self , _typ : Type < ' gcc > , _func : RValue < ' gcc > , _args : & [ RValue < ' gcc > ] , then : Block < ' gcc > , catch : Block < ' gcc > , _funclet : Option < & Funclet > ) -> RValue < ' gcc > {
@@ -454,17 +445,16 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
454
445
455
446
fn unreachable ( & mut self ) {
456
447
let func = self . context . get_builtin_function ( "__builtin_unreachable" ) ;
457
- let block = self . block . expect ( "block" ) ;
458
- block. add_eval ( None , self . context . new_call ( None , func, & [ ] ) ) ;
459
- let return_type = block. get_function ( ) . get_return_type ( ) ;
448
+ self . block . add_eval ( None , self . context . new_call ( None , func, & [ ] ) ) ;
449
+ let return_type = self . block . get_function ( ) . get_return_type ( ) ;
460
450
let void_type = self . context . new_type :: < ( ) > ( ) ;
461
451
if return_type == void_type {
462
- block. end_with_void_return ( None )
452
+ self . block . end_with_void_return ( None )
463
453
}
464
454
else {
465
455
let return_value = self . current_func ( )
466
456
. new_local ( None , return_type, "unreachableReturn" ) ;
467
- block. end_with_return ( None , return_value)
457
+ self . block . end_with_return ( None , return_value)
468
458
}
469
459
}
470
460
@@ -911,11 +901,13 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
911
901
}
912
902
913
903
fn ptrtoint ( & mut self , value : RValue < ' gcc > , dest_ty : Type < ' gcc > ) -> RValue < ' gcc > {
914
- self . cx . ptrtoint ( self . block . expect ( "block" ) , value, dest_ty)
904
+ let usize_value = self . cx . const_bitcast ( value, self . cx . type_isize ( ) ) ;
905
+ self . intcast ( usize_value, dest_ty, false )
915
906
}
916
907
917
908
fn inttoptr ( & mut self , value : RValue < ' gcc > , dest_ty : Type < ' gcc > ) -> RValue < ' gcc > {
918
- self . cx . inttoptr ( self . block . expect ( "block" ) , value, dest_ty)
909
+ let usize_value = self . intcast ( value, self . cx . type_isize ( ) , false ) ;
910
+ self . cx . const_bitcast ( usize_value, dest_ty)
919
911
}
920
912
921
913
fn bitcast ( & mut self , value : RValue < ' gcc > , dest_ty : Type < ' gcc > ) -> RValue < ' gcc > {
@@ -967,9 +959,8 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
967
959
let dst = self . pointercast ( dst, self . type_i8p ( ) ) ;
968
960
let src = self . pointercast ( src, self . type_ptr_to ( self . type_void ( ) ) ) ;
969
961
let memcpy = self . context . get_builtin_function ( "memcpy" ) ;
970
- let block = self . block . expect ( "block" ) ;
971
962
// TODO(antoyo): handle aligns and is_volatile.
972
- block. add_eval ( None , self . context . new_call ( None , memcpy, & [ dst, src, size] ) ) ;
963
+ self . block . add_eval ( None , self . context . new_call ( None , memcpy, & [ dst, src, size] ) ) ;
973
964
}
974
965
975
966
fn memmove ( & mut self , dst : RValue < ' gcc > , dst_align : Align , src : RValue < ' gcc > , src_align : Align , size : RValue < ' gcc > , flags : MemFlags ) {
@@ -986,20 +977,18 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
986
977
let src = self . pointercast ( src, self . type_ptr_to ( self . type_void ( ) ) ) ;
987
978
988
979
let memmove = self . context . get_builtin_function ( "memmove" ) ;
989
- let block = self . block . expect ( "block" ) ;
990
980
// TODO(antoyo): handle is_volatile.
991
- block. add_eval ( None , self . context . new_call ( None , memmove, & [ dst, src, size] ) ) ;
981
+ self . block . add_eval ( None , self . context . new_call ( None , memmove, & [ dst, src, size] ) ) ;
992
982
}
993
983
994
984
fn memset ( & mut self , ptr : RValue < ' gcc > , fill_byte : RValue < ' gcc > , size : RValue < ' gcc > , _align : Align , flags : MemFlags ) {
995
985
let _is_volatile = flags. contains ( MemFlags :: VOLATILE ) ;
996
986
let ptr = self . pointercast ( ptr, self . type_i8p ( ) ) ;
997
987
let memset = self . context . get_builtin_function ( "memset" ) ;
998
- let block = self . block . expect ( "block" ) ;
999
988
// TODO(antoyo): handle align and is_volatile.
1000
989
let fill_byte = self . context . new_cast ( None , fill_byte, self . i32_type ) ;
1001
990
let size = self . intcast ( size, self . type_size_t ( ) , false ) ;
1002
- block. add_eval ( None , self . context . new_call ( None , memset, & [ ptr, fill_byte, size] ) ) ;
991
+ self . block . add_eval ( None , self . context . new_call ( None , memset, & [ ptr, fill_byte, size] ) ) ;
1003
992
}
1004
993
1005
994
fn select ( & mut self , cond : RValue < ' gcc > , then_val : RValue < ' gcc > , mut else_val : RValue < ' gcc > ) -> RValue < ' gcc > {
@@ -1019,10 +1008,9 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
1019
1008
else_block. add_assignment ( None , variable, else_val) ;
1020
1009
else_block. end_with_jump ( None , after_block) ;
1021
1010
1022
- // NOTE: since jumps were added in a place rustc does not expect, the current blocks in the
1011
+ // NOTE: since jumps were added in a place rustc does not expect, the current block in the
1023
1012
// state need to be updated.
1024
- self . block = Some ( after_block) ;
1025
- * self . cx . current_block . borrow_mut ( ) = Some ( after_block) ;
1013
+ self . switch_to_block ( after_block) ;
1026
1014
1027
1015
variable. to_rvalue ( )
1028
1016
}
0 commit comments