@@ -183,6 +183,14 @@ pub fn get_dataptr(bcx: Block, fat_ptr: ValueRef) -> ValueRef {
183
183
StructGEP ( bcx, fat_ptr, abi:: FAT_PTR_ADDR )
184
184
}
185
185
186
+ pub fn get_meta_builder ( b : & Builder , fat_ptr : ValueRef ) -> ValueRef {
187
+ b. struct_gep ( fat_ptr, abi:: FAT_PTR_EXTRA )
188
+ }
189
+
190
+ pub fn get_dataptr_builder ( b : & Builder , fat_ptr : ValueRef ) -> ValueRef {
191
+ b. struct_gep ( fat_ptr, abi:: FAT_PTR_ADDR )
192
+ }
193
+
186
194
fn require_alloc_fn < ' blk , ' tcx > ( bcx : Block < ' blk , ' tcx > , info_ty : Ty < ' tcx > , it : LangItem ) -> DefId {
187
195
match bcx. tcx ( ) . lang_items . require ( it) {
188
196
Ok ( id) => id,
@@ -247,124 +255,6 @@ pub fn bin_op_to_fcmp_predicate(op: hir::BinOp_) -> llvm::RealPredicate {
247
255
}
248
256
}
249
257
250
- pub fn compare_fat_ptrs < ' blk , ' tcx > ( bcx : Block < ' blk , ' tcx > ,
251
- lhs_addr : ValueRef ,
252
- lhs_extra : ValueRef ,
253
- rhs_addr : ValueRef ,
254
- rhs_extra : ValueRef ,
255
- _t : Ty < ' tcx > ,
256
- op : hir:: BinOp_ ,
257
- debug_loc : DebugLoc )
258
- -> ValueRef {
259
- match op {
260
- hir:: BiEq => {
261
- let addr_eq = ICmp ( bcx, llvm:: IntEQ , lhs_addr, rhs_addr, debug_loc) ;
262
- let extra_eq = ICmp ( bcx, llvm:: IntEQ , lhs_extra, rhs_extra, debug_loc) ;
263
- And ( bcx, addr_eq, extra_eq, debug_loc)
264
- }
265
- hir:: BiNe => {
266
- let addr_eq = ICmp ( bcx, llvm:: IntNE , lhs_addr, rhs_addr, debug_loc) ;
267
- let extra_eq = ICmp ( bcx, llvm:: IntNE , lhs_extra, rhs_extra, debug_loc) ;
268
- Or ( bcx, addr_eq, extra_eq, debug_loc)
269
- }
270
- hir:: BiLe | hir:: BiLt | hir:: BiGe | hir:: BiGt => {
271
- // a OP b ~ a.0 STRICT(OP) b.0 | (a.0 == b.0 && a.1 OP a.1)
272
- let ( op, strict_op) = match op {
273
- hir:: BiLt => ( llvm:: IntULT , llvm:: IntULT ) ,
274
- hir:: BiLe => ( llvm:: IntULE , llvm:: IntULT ) ,
275
- hir:: BiGt => ( llvm:: IntUGT , llvm:: IntUGT ) ,
276
- hir:: BiGe => ( llvm:: IntUGE , llvm:: IntUGT ) ,
277
- _ => bug ! ( ) ,
278
- } ;
279
-
280
- let addr_eq = ICmp ( bcx, llvm:: IntEQ , lhs_addr, rhs_addr, debug_loc) ;
281
- let extra_op = ICmp ( bcx, op, lhs_extra, rhs_extra, debug_loc) ;
282
- let addr_eq_extra_op = And ( bcx, addr_eq, extra_op, debug_loc) ;
283
-
284
- let addr_strict = ICmp ( bcx, strict_op, lhs_addr, rhs_addr, debug_loc) ;
285
- Or ( bcx, addr_strict, addr_eq_extra_op, debug_loc)
286
- }
287
- _ => {
288
- bug ! ( "unexpected fat ptr binop" ) ;
289
- }
290
- }
291
- }
292
-
293
- pub fn compare_scalar_types < ' blk , ' tcx > ( bcx : Block < ' blk , ' tcx > ,
294
- lhs : ValueRef ,
295
- rhs : ValueRef ,
296
- t : Ty < ' tcx > ,
297
- op : hir:: BinOp_ ,
298
- debug_loc : DebugLoc )
299
- -> ValueRef {
300
- match t. sty {
301
- ty:: TyTuple ( ref tys) if tys. is_empty ( ) => {
302
- // We don't need to do actual comparisons for nil.
303
- // () == () holds but () < () does not.
304
- match op {
305
- hir:: BiEq | hir:: BiLe | hir:: BiGe => return C_bool ( bcx. ccx ( ) , true ) ,
306
- hir:: BiNe | hir:: BiLt | hir:: BiGt => return C_bool ( bcx. ccx ( ) , false ) ,
307
- // refinements would be nice
308
- _ => bug ! ( "compare_scalar_types: must be a comparison operator" ) ,
309
- }
310
- }
311
- ty:: TyBool => {
312
- // FIXME(#36856) -- using `from_immediate` forces these booleans into `i8`,
313
- // which works around some LLVM bugs
314
- ICmp ( bcx,
315
- bin_op_to_icmp_predicate ( op, false ) ,
316
- from_immediate ( bcx, lhs) ,
317
- from_immediate ( bcx, rhs) ,
318
- debug_loc)
319
- }
320
- ty:: TyFnDef ( ..) | ty:: TyFnPtr ( _) | ty:: TyUint ( _) | ty:: TyChar => {
321
- ICmp ( bcx,
322
- bin_op_to_icmp_predicate ( op, false ) ,
323
- lhs,
324
- rhs,
325
- debug_loc)
326
- }
327
- ty:: TyRawPtr ( mt) if common:: type_is_sized ( bcx. tcx ( ) , mt. ty ) => {
328
- ICmp ( bcx,
329
- bin_op_to_icmp_predicate ( op, false ) ,
330
- lhs,
331
- rhs,
332
- debug_loc)
333
- }
334
- ty:: TyRawPtr ( _) => {
335
- let lhs_addr = Load ( bcx, GEPi ( bcx, lhs, & [ 0 , abi:: FAT_PTR_ADDR ] ) ) ;
336
- let lhs_extra = Load ( bcx, GEPi ( bcx, lhs, & [ 0 , abi:: FAT_PTR_EXTRA ] ) ) ;
337
-
338
- let rhs_addr = Load ( bcx, GEPi ( bcx, rhs, & [ 0 , abi:: FAT_PTR_ADDR ] ) ) ;
339
- let rhs_extra = Load ( bcx, GEPi ( bcx, rhs, & [ 0 , abi:: FAT_PTR_EXTRA ] ) ) ;
340
- compare_fat_ptrs ( bcx,
341
- lhs_addr,
342
- lhs_extra,
343
- rhs_addr,
344
- rhs_extra,
345
- t,
346
- op,
347
- debug_loc)
348
- }
349
- ty:: TyInt ( _) => {
350
- ICmp ( bcx,
351
- bin_op_to_icmp_predicate ( op, true ) ,
352
- lhs,
353
- rhs,
354
- debug_loc)
355
- }
356
- ty:: TyFloat ( _) => {
357
- FCmp ( bcx,
358
- bin_op_to_fcmp_predicate ( op) ,
359
- lhs,
360
- rhs,
361
- debug_loc)
362
- }
363
- // Should never get here, because t is scalar.
364
- _ => bug ! ( "non-scalar type passed to compare_scalar_types" ) ,
365
- }
366
- }
367
-
368
258
pub fn compare_simd_types < ' blk , ' tcx > ( bcx : Block < ' blk , ' tcx > ,
369
259
lhs : ValueRef ,
370
260
rhs : ValueRef ,
@@ -632,6 +522,11 @@ pub fn need_invoke(bcx: Block) -> bool {
632
522
}
633
523
}
634
524
525
+ pub fn call_assume < ' a , ' tcx > ( b : & Builder < ' a , ' tcx > , val : ValueRef ) {
526
+ let assume_intrinsic = b. ccx . get_intrinsic ( "llvm.assume" ) ;
527
+ b. call ( assume_intrinsic, & [ val] , None ) ;
528
+ }
529
+
635
530
/// Helper for loading values from memory. Does the necessary conversion if the in-memory type
636
531
/// differs from the type used for SSA values. Also handles various special cases where the type
637
532
/// gives us better information about what we are loading.
@@ -685,12 +580,9 @@ pub fn store_ty<'blk, 'tcx>(cx: Block<'blk, 'tcx>, v: ValueRef, dst: ValueRef, t
685
580
debug ! ( "store_ty: {:?} : {:?} <- {:?}" , Value ( dst) , t, Value ( v) ) ;
686
581
687
582
if common:: type_is_fat_ptr ( cx. tcx ( ) , t) {
688
- Store ( cx,
689
- ExtractValue ( cx, v, abi:: FAT_PTR_ADDR ) ,
690
- get_dataptr ( cx, dst) ) ;
691
- Store ( cx,
692
- ExtractValue ( cx, v, abi:: FAT_PTR_EXTRA ) ,
693
- get_meta ( cx, dst) ) ;
583
+ let lladdr = ExtractValue ( cx, v, abi:: FAT_PTR_ADDR ) ;
584
+ let llextra = ExtractValue ( cx, v, abi:: FAT_PTR_EXTRA ) ;
585
+ store_fat_ptr ( cx, lladdr, llextra, dst, t) ;
694
586
} else {
695
587
Store ( cx, from_immediate ( cx, v) , dst) ;
696
588
}
@@ -708,11 +600,36 @@ pub fn store_fat_ptr<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
708
600
709
601
pub fn load_fat_ptr < ' blk , ' tcx > ( cx : Block < ' blk , ' tcx > ,
710
602
src : ValueRef ,
711
- _ty : Ty < ' tcx > )
712
- -> ( ValueRef , ValueRef ) {
713
- // FIXME: emit metadata
714
- ( Load ( cx, get_dataptr ( cx, src) ) ,
715
- Load ( cx, get_meta ( cx, src) ) )
603
+ ty : Ty < ' tcx > )
604
+ -> ( ValueRef , ValueRef )
605
+ {
606
+ if cx. unreachable . get ( ) {
607
+ // FIXME: remove me
608
+ return ( Load ( cx, get_dataptr ( cx, src) ) ,
609
+ Load ( cx, get_meta ( cx, src) ) ) ;
610
+ }
611
+
612
+ load_fat_ptr_builder ( & B ( cx) , src, ty)
613
+ }
614
+
615
+ pub fn load_fat_ptr_builder < ' a , ' tcx > (
616
+ b : & Builder < ' a , ' tcx > ,
617
+ src : ValueRef ,
618
+ t : Ty < ' tcx > )
619
+ -> ( ValueRef , ValueRef )
620
+ {
621
+
622
+ let ptr = get_dataptr_builder ( b, src) ;
623
+ let ptr = if t. is_region_ptr ( ) || t. is_unique ( ) {
624
+ b. load_nonnull ( ptr)
625
+ } else {
626
+ b. load ( ptr)
627
+ } ;
628
+
629
+ // FIXME: emit metadata on `meta`.
630
+ let meta = b. load ( get_meta_builder ( b, src) ) ;
631
+
632
+ ( ptr, meta)
716
633
}
717
634
718
635
pub fn from_immediate ( bcx : Block , val : ValueRef ) -> ValueRef {
0 commit comments