@@ -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
}
@@ -243,7 +243,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
243
243
}
244
244
245
245
pub fn current_func ( & self ) -> Function < ' gcc > {
246
- self . block . expect ( "block" ) . get_function ( )
246
+ self . block . get_function ( )
247
247
}
248
248
249
249
fn function_call ( & mut self , func : RValue < ' gcc > , args : & [ RValue < ' gcc > ] , _funclet : Option < & Funclet > ) -> RValue < ' gcc > {
@@ -254,17 +254,16 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
254
254
// gccjit requires to use the result of functions, even when it's not used.
255
255
// That's why we assign the result to a local or call add_eval().
256
256
let return_type = func. get_return_type ( ) ;
257
- let current_block = self . current_block . borrow ( ) . expect ( "block" ) ;
258
257
let void_type = self . context . new_type :: < ( ) > ( ) ;
259
- let current_func = current_block . get_function ( ) ;
258
+ let current_func = self . block . get_function ( ) ;
260
259
if return_type != void_type {
261
260
unsafe { RETURN_VALUE_COUNT += 1 } ;
262
261
let result = current_func. new_local ( None , return_type, & format ! ( "returnValue{}" , unsafe { RETURN_VALUE_COUNT } ) ) ;
263
- 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) ) ;
264
263
result. to_rvalue ( )
265
264
}
266
265
else {
267
- 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) ) ;
268
267
// Return dummy value when not having return value.
269
268
self . context . new_rvalue_from_long ( self . isize_type , 0 )
270
269
}
@@ -277,9 +276,8 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
277
276
// That's why we assign the result to a local or call add_eval().
278
277
let gcc_func = func_ptr. get_type ( ) . dyncast_function_ptr_type ( ) . expect ( "function ptr" ) ;
279
278
let mut return_type = gcc_func. get_return_type ( ) ;
280
- let current_block = self . current_block . borrow ( ) . expect ( "block" ) ;
281
279
let void_type = self . context . new_type :: < ( ) > ( ) ;
282
- let current_func = current_block . get_function ( ) ;
280
+ let current_func = self . block . get_function ( ) ;
283
281
284
282
// FIXME(antoyo): As a temporary workaround for unsupported LLVM intrinsics.
285
283
if gcc_func. get_param_count ( ) == 0 && format ! ( "{:?}" , func_ptr) == "__builtin_ia32_pmovmskb128" {
@@ -289,20 +287,20 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
289
287
if return_type != void_type {
290
288
unsafe { RETURN_VALUE_COUNT += 1 } ;
291
289
let result = current_func. new_local ( None , return_type, & format ! ( "ptrReturnValue{}" , unsafe { RETURN_VALUE_COUNT } ) ) ;
292
- 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) ) ;
293
291
result. to_rvalue ( )
294
292
}
295
293
else {
296
294
if gcc_func. get_param_count ( ) == 0 {
297
295
// FIXME(antoyo): As a temporary workaround for unsupported LLVM intrinsics.
298
- 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, & [ ] ) ) ;
299
297
}
300
298
else {
301
- 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) ) ;
302
300
}
303
301
// Return dummy value when not having return value.
304
302
let result = current_func. new_local ( None , self . isize_type , "dummyValueThatShouldNeverBeUsed" ) ;
305
- 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 ) ) ;
306
304
result. to_rvalue ( )
307
305
}
308
306
}
@@ -311,12 +309,11 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
311
309
// gccjit requires to use the result of functions, even when it's not used.
312
310
// That's why we assign the result to a local.
313
311
let return_type = self . context . new_type :: < bool > ( ) ;
314
- let current_block = self . current_block . borrow ( ) . expect ( "block" ) ;
315
- let current_func = current_block. get_function ( ) ;
312
+ let current_func = self . block . get_function ( ) ;
316
313
// TODO(antoyo): return the new_call() directly? Since the overflow function has no side-effects.
317
314
unsafe { RETURN_VALUE_COUNT += 1 } ;
318
315
let result = current_func. new_local ( None , return_type, & format ! ( "overflowReturnValue{}" , unsafe { RETURN_VALUE_COUNT } ) ) ;
319
- 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) ) ;
320
317
result. to_rvalue ( )
321
318
}
322
319
}
@@ -382,14 +379,13 @@ impl<'gcc, 'tcx> BackendTypes for Builder<'_, 'gcc, 'tcx> {
382
379
383
380
impl < ' a , ' gcc , ' tcx > BuilderMethods < ' a , ' tcx > for Builder < ' a , ' gcc , ' tcx > {
384
381
fn build ( cx : & ' a CodegenCx < ' gcc , ' tcx > , block : Block < ' gcc > ) -> Self {
385
- let mut bx = Builder :: with_cx ( cx) ;
382
+ let bx = Builder :: with_cx ( cx, block ) ;
386
383
* cx. current_block . borrow_mut ( ) = Some ( block) ;
387
- bx. block = Some ( block) ;
388
384
bx
389
385
}
390
386
391
387
fn llbb ( & self ) -> Block < ' gcc > {
392
- self . block . expect ( "block" )
388
+ self . block
393
389
}
394
390
395
391
fn append_block ( cx : & ' a CodegenCx < ' gcc , ' tcx > , func : RValue < ' gcc > , name : & str ) -> Block < ' gcc > {
@@ -404,7 +400,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
404
400
405
401
fn switch_to_block ( & mut self , block : Self :: BasicBlock ) {
406
402
* self . cx . current_block . borrow_mut ( ) = Some ( block) ;
407
- self . block = Some ( block) ;
403
+ self . block = block;
408
404
}
409
405
410
406
fn ret_void ( & mut self ) {
@@ -439,7 +435,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
439
435
let on_val = self . const_uint_big ( typ, on_val) ;
440
436
gcc_cases. push ( self . context . new_case ( on_val, on_val, dest) ) ;
441
437
}
442
- self . block . expect ( "block" ) . end_with_switch ( None , value, default_block, & gcc_cases) ;
438
+ self . block . end_with_switch ( None , value, default_block, & gcc_cases) ;
443
439
}
444
440
445
441
fn invoke ( & mut self , _typ : Type < ' gcc > , _func : RValue < ' gcc > , _args : & [ RValue < ' gcc > ] , then : Block < ' gcc > , catch : Block < ' gcc > , _funclet : Option < & Funclet > ) -> RValue < ' gcc > {
@@ -452,17 +448,16 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
452
448
453
449
fn unreachable ( & mut self ) {
454
450
let func = self . context . get_builtin_function ( "__builtin_unreachable" ) ;
455
- let block = self . block . expect ( "block" ) ;
456
- block. add_eval ( None , self . context . new_call ( None , func, & [ ] ) ) ;
457
- let return_type = block. get_function ( ) . get_return_type ( ) ;
451
+ self . block . add_eval ( None , self . context . new_call ( None , func, & [ ] ) ) ;
452
+ let return_type = self . block . get_function ( ) . get_return_type ( ) ;
458
453
let void_type = self . context . new_type :: < ( ) > ( ) ;
459
454
if return_type == void_type {
460
- block. end_with_void_return ( None )
455
+ self . block . end_with_void_return ( None )
461
456
}
462
457
else {
463
458
let return_value = self . current_func ( )
464
459
. new_local ( None , return_type, "unreachableReturn" ) ;
465
- block. end_with_return ( None , return_value)
460
+ self . block . end_with_return ( None , return_value)
466
461
}
467
462
}
468
463
@@ -909,11 +904,11 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
909
904
}
910
905
911
906
fn ptrtoint ( & mut self , value : RValue < ' gcc > , dest_ty : Type < ' gcc > ) -> RValue < ' gcc > {
912
- self . cx . ptrtoint ( self . block . expect ( "block" ) , value, dest_ty)
907
+ self . cx . ptrtoint ( self . block , value, dest_ty)
913
908
}
914
909
915
910
fn inttoptr ( & mut self , value : RValue < ' gcc > , dest_ty : Type < ' gcc > ) -> RValue < ' gcc > {
916
- self . cx . inttoptr ( self . block . expect ( "block" ) , value, dest_ty)
911
+ self . cx . inttoptr ( self . block , value, dest_ty)
917
912
}
918
913
919
914
fn bitcast ( & mut self , value : RValue < ' gcc > , dest_ty : Type < ' gcc > ) -> RValue < ' gcc > {
@@ -965,9 +960,8 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
965
960
let dst = self . pointercast ( dst, self . type_i8p ( ) ) ;
966
961
let src = self . pointercast ( src, self . type_ptr_to ( self . type_void ( ) ) ) ;
967
962
let memcpy = self . context . get_builtin_function ( "memcpy" ) ;
968
- let block = self . block . expect ( "block" ) ;
969
963
// TODO(antoyo): handle aligns and is_volatile.
970
- block. add_eval ( None , self . context . new_call ( None , memcpy, & [ dst, src, size] ) ) ;
964
+ self . block . add_eval ( None , self . context . new_call ( None , memcpy, & [ dst, src, size] ) ) ;
971
965
}
972
966
973
967
fn memmove ( & mut self , dst : RValue < ' gcc > , dst_align : Align , src : RValue < ' gcc > , src_align : Align , size : RValue < ' gcc > , flags : MemFlags ) {
@@ -984,20 +978,18 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
984
978
let src = self . pointercast ( src, self . type_ptr_to ( self . type_void ( ) ) ) ;
985
979
986
980
let memmove = self . context . get_builtin_function ( "memmove" ) ;
987
- let block = self . block . expect ( "block" ) ;
988
981
// TODO(antoyo): handle is_volatile.
989
- block. add_eval ( None , self . context . new_call ( None , memmove, & [ dst, src, size] ) ) ;
982
+ self . block . add_eval ( None , self . context . new_call ( None , memmove, & [ dst, src, size] ) ) ;
990
983
}
991
984
992
985
fn memset ( & mut self , ptr : RValue < ' gcc > , fill_byte : RValue < ' gcc > , size : RValue < ' gcc > , _align : Align , flags : MemFlags ) {
993
986
let _is_volatile = flags. contains ( MemFlags :: VOLATILE ) ;
994
987
let ptr = self . pointercast ( ptr, self . type_i8p ( ) ) ;
995
988
let memset = self . context . get_builtin_function ( "memset" ) ;
996
- let block = self . block . expect ( "block" ) ;
997
989
// TODO(antoyo): handle align and is_volatile.
998
990
let fill_byte = self . context . new_cast ( None , fill_byte, self . i32_type ) ;
999
991
let size = self . intcast ( size, self . type_size_t ( ) , false ) ;
1000
- block. add_eval ( None , self . context . new_call ( None , memset, & [ ptr, fill_byte, size] ) ) ;
992
+ self . block . add_eval ( None , self . context . new_call ( None , memset, & [ ptr, fill_byte, size] ) ) ;
1001
993
}
1002
994
1003
995
fn select ( & mut self , cond : RValue < ' gcc > , then_val : RValue < ' gcc > , mut else_val : RValue < ' gcc > ) -> RValue < ' gcc > {
0 commit comments