@@ -80,15 +80,15 @@ impl EnumClone for AtomicOrdering {
8080
8181pub struct Builder < ' a : ' gcc , ' gcc , ' tcx > {
8282 pub cx : & ' a CodegenCx < ' gcc , ' tcx > ,
83- pub block : Option < Block < ' gcc > > ,
83+ pub block : Block < ' gcc > ,
8484 stack_var_count : Cell < usize > ,
8585}
8686
8787impl < ' 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 {
8989 Builder {
9090 cx,
91- block : None ,
91+ block,
9292 stack_var_count : Cell :: new ( 0 ) ,
9393 }
9494 }
@@ -114,10 +114,9 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
114114 let after_block = func. new_block ( "after_while" ) ;
115115 self . llbb ( ) . end_with_jump ( None , while_block) ;
116116
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
118118 // 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) ;
121120
122121 let comparison_operator =
123122 match operation {
@@ -132,10 +131,9 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
132131
133132 while_block. end_with_conditional ( None , cond, while_block, after_block) ;
134133
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
136135 // 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) ;
139137
140138 return_value. to_rvalue ( )
141139 }
@@ -245,7 +243,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
245243 }
246244
247245 pub fn current_func ( & self ) -> Function < ' gcc > {
248- self . block . expect ( "block" ) . get_function ( )
246+ self . block . get_function ( )
249247 }
250248
251249 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> {
256254 // gccjit requires to use the result of functions, even when it's not used.
257255 // That's why we assign the result to a local or call add_eval().
258256 let return_type = func. get_return_type ( ) ;
259- let current_block = self . current_block . borrow ( ) . expect ( "block" ) ;
260257 let void_type = self . context . new_type :: < ( ) > ( ) ;
261- let current_func = current_block . get_function ( ) ;
258+ let current_func = self . block . get_function ( ) ;
262259 if return_type != void_type {
263260 unsafe { RETURN_VALUE_COUNT += 1 } ;
264261 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) ) ;
266263 result. to_rvalue ( )
267264 }
268265 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) ) ;
270267 // Return dummy value when not having return value.
271268 self . context . new_rvalue_from_long ( self . isize_type , 0 )
272269 }
@@ -279,9 +276,8 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
279276 // That's why we assign the result to a local or call add_eval().
280277 let gcc_func = func_ptr. get_type ( ) . dyncast_function_ptr_type ( ) . expect ( "function ptr" ) ;
281278 let mut return_type = gcc_func. get_return_type ( ) ;
282- let current_block = self . current_block . borrow ( ) . expect ( "block" ) ;
283279 let void_type = self . context . new_type :: < ( ) > ( ) ;
284- let current_func = current_block . get_function ( ) ;
280+ let current_func = self . block . get_function ( ) ;
285281
286282 // FIXME(antoyo): As a temporary workaround for unsupported LLVM intrinsics.
287283 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> {
291287 if return_type != void_type {
292288 unsafe { RETURN_VALUE_COUNT += 1 } ;
293289 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) ) ;
295291 result. to_rvalue ( )
296292 }
297293 else {
298294 if gcc_func. get_param_count ( ) == 0 {
299295 // 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, & [ ] ) ) ;
301297 }
302298 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) ) ;
304300 }
305301 // Return dummy value when not having return value.
306302 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 ) ) ;
308304 result. to_rvalue ( )
309305 }
310306 }
@@ -313,12 +309,11 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
313309 // gccjit requires to use the result of functions, even when it's not used.
314310 // That's why we assign the result to a local.
315311 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 ( ) ;
318313 // TODO(antoyo): return the new_call() directly? Since the overflow function has no side-effects.
319314 unsafe { RETURN_VALUE_COUNT += 1 } ;
320315 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) ) ;
322317 result. to_rvalue ( )
323318 }
324319}
@@ -384,14 +379,11 @@ impl<'gcc, 'tcx> BackendTypes for Builder<'_, 'gcc, 'tcx> {
384379
385380impl < ' a , ' gcc , ' tcx > BuilderMethods < ' a , ' tcx > for Builder < ' a , ' gcc , ' tcx > {
386381 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)
391383 }
392384
393385 fn llbb ( & self ) -> Block < ' gcc > {
394- self . block . expect ( "block" )
386+ self . block
395387 }
396388
397389 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> {
405397 }
406398
407399 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;
410401 }
411402
412403 fn ret_void ( & mut self ) {
@@ -441,7 +432,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
441432 let on_val = self . const_uint_big ( typ, on_val) ;
442433 gcc_cases. push ( self . context . new_case ( on_val, on_val, dest) ) ;
443434 }
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) ;
445436 }
446437
447438 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> {
454445
455446 fn unreachable ( & mut self ) {
456447 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 ( ) ;
460450 let void_type = self . context . new_type :: < ( ) > ( ) ;
461451 if return_type == void_type {
462- block. end_with_void_return ( None )
452+ self . block . end_with_void_return ( None )
463453 }
464454 else {
465455 let return_value = self . current_func ( )
466456 . new_local ( None , return_type, "unreachableReturn" ) ;
467- block. end_with_return ( None , return_value)
457+ self . block . end_with_return ( None , return_value)
468458 }
469459 }
470460
@@ -911,11 +901,13 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
911901 }
912902
913903 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 )
915906 }
916907
917908 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)
919911 }
920912
921913 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> {
967959 let dst = self . pointercast ( dst, self . type_i8p ( ) ) ;
968960 let src = self . pointercast ( src, self . type_ptr_to ( self . type_void ( ) ) ) ;
969961 let memcpy = self . context . get_builtin_function ( "memcpy" ) ;
970- let block = self . block . expect ( "block" ) ;
971962 // 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] ) ) ;
973964 }
974965
975966 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> {
986977 let src = self . pointercast ( src, self . type_ptr_to ( self . type_void ( ) ) ) ;
987978
988979 let memmove = self . context . get_builtin_function ( "memmove" ) ;
989- let block = self . block . expect ( "block" ) ;
990980 // 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] ) ) ;
992982 }
993983
994984 fn memset ( & mut self , ptr : RValue < ' gcc > , fill_byte : RValue < ' gcc > , size : RValue < ' gcc > , _align : Align , flags : MemFlags ) {
995985 let _is_volatile = flags. contains ( MemFlags :: VOLATILE ) ;
996986 let ptr = self . pointercast ( ptr, self . type_i8p ( ) ) ;
997987 let memset = self . context . get_builtin_function ( "memset" ) ;
998- let block = self . block . expect ( "block" ) ;
999988 // TODO(antoyo): handle align and is_volatile.
1000989 let fill_byte = self . context . new_cast ( None , fill_byte, self . i32_type ) ;
1001990 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] ) ) ;
1003992 }
1004993
1005994 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> {
10191008 else_block. add_assignment ( None , variable, else_val) ;
10201009 else_block. end_with_jump ( None , after_block) ;
10211010
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
10231012 // 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) ;
10261014
10271015 variable. to_rvalue ( )
10281016 }
0 commit comments