@@ -6,6 +6,7 @@ use rustc_middle::bug;
6
6
use rustc_middle:: ty:: layout:: { FnAbiOf , LayoutOf , TyAndLayout } ;
7
7
use rustc_middle:: ty:: print:: { with_no_trimmed_paths, with_no_visible_paths} ;
8
8
use rustc_middle:: ty:: { self , Ty , TypeVisitableExt } ;
9
+ use rustc_target:: abi:: HasDataLayout ;
9
10
use rustc_target:: abi:: { Abi , Align , FieldsShape } ;
10
11
use rustc_target:: abi:: { Int , Pointer , F32 , F64 } ;
11
12
use rustc_target:: abi:: { PointeeInfo , Scalar , Size , TyAbiInterface , Variants } ;
@@ -192,6 +193,7 @@ pub trait LayoutLlvmExt<'tcx> {
192
193
) -> & ' a Type ;
193
194
fn llvm_field_index < ' a > ( & self , cx : & CodegenCx < ' a , ' tcx > , index : usize ) -> u64 ;
194
195
fn pointee_info_at < ' a > ( & self , cx : & CodegenCx < ' a , ' tcx > , offset : Size ) -> Option < PointeeInfo > ;
196
+ fn scalar_copy_llvm_type < ' a > ( & self , cx : & CodegenCx < ' a , ' tcx > ) -> Option < & ' a Type > ;
195
197
}
196
198
197
199
impl < ' tcx > LayoutLlvmExt < ' tcx > for TyAndLayout < ' tcx > {
@@ -414,4 +416,35 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
414
416
cx. pointee_infos . borrow_mut ( ) . insert ( ( self . ty , offset) , result) ;
415
417
result
416
418
}
419
+
420
+ fn scalar_copy_llvm_type < ' a > ( & self , cx : & CodegenCx < ' a , ' tcx > ) -> Option < & ' a Type > {
421
+ debug_assert ! ( self . is_sized( ) ) ;
422
+
423
+ // FIXME: this is a fairly arbitrary choice, but 128 bits on WASM
424
+ // (matching the 128-bit SIMD types proposal) and 256 bits on x64
425
+ // (like AVX2 registers) seems at least like a tolerable starting point.
426
+ let threshold = cx. data_layout ( ) . pointer_size * 4 ;
427
+ if self . layout . size ( ) > threshold {
428
+ return None ;
429
+ }
430
+
431
+ // Vectors, even for non-power-of-two sizes, have the same layout as
432
+ // arrays but don't count as aggregate types
433
+ if let FieldsShape :: Array { count, .. } = self . layout . fields ( )
434
+ && let element = self . field ( cx, 0 )
435
+ && element. ty . is_integral ( )
436
+ {
437
+ // `cx.type_ix(bits)` is tempting here, but while that works great
438
+ // for things that *stay* as memory-to-memory copies, it also ends
439
+ // up suppressing vectorization as it introduces shifts when it
440
+ // extracts all the individual values.
441
+
442
+ let ety = element. llvm_type ( cx) ;
443
+ return Some ( cx. type_vector ( ety, * count) ) ;
444
+ }
445
+
446
+ // FIXME: The above only handled integer arrays; surely more things
447
+ // would also be possible. Be careful about provenance, though!
448
+ None
449
+ }
417
450
}
0 commit comments