@@ -2,9 +2,11 @@ use crate::abi::{FnType, FnTypeExt};
22use crate :: common:: * ;
33use crate :: type_:: Type ;
44use rustc:: hir;
5+ use abi:: { FnType , FnTypeExt } ;
6+ use common:: * ;
57use rustc:: ty:: { self , Ty , TypeFoldable } ;
6- use rustc:: ty:: layout:: { self , Align , LayoutOf , Size , TyLayout } ;
7- use rustc_target:: abi:: FloatTy ;
8+ use rustc:: ty:: layout:: { self , Align , LayoutOf , PointeeInfo , Size , TyLayout } ;
9+ use rustc_target:: abi:: { FloatTy , TyLayoutMethods } ;
810use rustc_mir:: monomorphize:: item:: DefPathBasedNames ;
911use rustc_codegen_ssa:: traits:: * ;
1012
@@ -174,28 +176,6 @@ impl<'a, 'tcx> CodegenCx<'a, 'tcx> {
174176 }
175177}
176178
177- #[ derive( Copy , Clone , PartialEq , Eq ) ]
178- pub enum PointerKind {
179- /// Most general case, we know no restrictions to tell LLVM.
180- Shared ,
181-
182- /// `&T` where `T` contains no `UnsafeCell`, is `noalias` and `readonly`.
183- Frozen ,
184-
185- /// `&mut T`, when we know `noalias` is safe for LLVM.
186- UniqueBorrowed ,
187-
188- /// `Box<T>`, unlike `UniqueBorrowed`, it also has `noalias` on returns.
189- UniqueOwned
190- }
191-
192- #[ derive( Copy , Clone ) ]
193- pub struct PointeeInfo {
194- pub size : Size ,
195- pub align : Align ,
196- pub safe : Option < PointerKind > ,
197- }
198-
199179pub trait LayoutLlvmExt < ' tcx > {
200180 fn is_llvm_immediate ( & self ) -> bool ;
201181 fn is_llvm_scalar_pair < ' a > ( & self ) -> bool ;
@@ -406,112 +386,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
406386 return pointee;
407387 }
408388
409- let mut result = None ;
410- match self . ty . sty {
411- ty:: RawPtr ( mt) if offset. bytes ( ) == 0 => {
412- let ( size, align) = cx. size_and_align_of ( mt. ty ) ;
413- result = Some ( PointeeInfo {
414- size,
415- align,
416- safe : None
417- } ) ;
418- }
419-
420- ty:: Ref ( _, ty, mt) if offset. bytes ( ) == 0 => {
421- let ( size, align) = cx. size_and_align_of ( ty) ;
422-
423- let kind = match mt {
424- hir:: MutImmutable => if cx. type_is_freeze ( ty) {
425- PointerKind :: Frozen
426- } else {
427- PointerKind :: Shared
428- } ,
429- hir:: MutMutable => {
430- // Previously we would only emit noalias annotations for LLVM >= 6 or in
431- // panic=abort mode. That was deemed right, as prior versions had many bugs
432- // in conjunction with unwinding, but later versions didn’t seem to have
433- // said issues. See issue #31681.
434- //
435- // Alas, later on we encountered a case where noalias would generate wrong
436- // code altogether even with recent versions of LLVM in *safe* code with no
437- // unwinding involved. See #54462.
438- //
439- // For now, do not enable mutable_noalias by default at all, while the
440- // issue is being figured out.
441- let mutable_noalias = cx. tcx . sess . opts . debugging_opts . mutable_noalias
442- . unwrap_or ( false ) ;
443- if mutable_noalias {
444- PointerKind :: UniqueBorrowed
445- } else {
446- PointerKind :: Shared
447- }
448- }
449- } ;
450-
451- result = Some ( PointeeInfo {
452- size,
453- align,
454- safe : Some ( kind)
455- } ) ;
456- }
457-
458- _ => {
459- let mut data_variant = match self . variants {
460- // Within the discriminant field, only the niche itself is
461- // always initialized, so we only check for a pointer at its
462- // offset.
463- //
464- // If the niche is a pointer, it's either valid (according
465- // to its type), or null (which the niche field's scalar
466- // validity range encodes). This allows using
467- // `dereferenceable_or_null` for e.g., `Option<&T>`, and
468- // this will continue to work as long as we don't start
469- // using more niches than just null (e.g., the first page of
470- // the address space, or unaligned pointers).
471- layout:: Variants :: Multiple {
472- discr_kind : layout:: DiscriminantKind :: Niche {
473- dataful_variant,
474- ..
475- } ,
476- discr_index,
477- ..
478- } if self . fields . offset ( discr_index) == offset =>
479- Some ( self . for_variant ( cx, dataful_variant) ) ,
480- _ => Some ( * self ) ,
481- } ;
482-
483- if let Some ( variant) = data_variant {
484- // We're not interested in any unions.
485- if let layout:: FieldPlacement :: Union ( _) = variant. fields {
486- data_variant = None ;
487- }
488- }
489-
490- if let Some ( variant) = data_variant {
491- let ptr_end = offset + layout:: Pointer . size ( cx) ;
492- for i in 0 ..variant. fields . count ( ) {
493- let field_start = variant. fields . offset ( i) ;
494- if field_start <= offset {
495- let field = variant. field ( cx, i) ;
496- if ptr_end <= field_start + field. size {
497- // We found the right field, look inside it.
498- result = field. pointee_info_at ( cx, offset - field_start) ;
499- break ;
500- }
501- }
502- }
503- }
504-
505- // FIXME(eddyb) This should be for `ptr::Unique<T>`, not `Box<T>`.
506- if let Some ( ref mut pointee) = result {
507- if let ty:: Adt ( def, _) = self . ty . sty {
508- if def. is_box ( ) && offset. bytes ( ) == 0 {
509- pointee. safe = Some ( PointerKind :: UniqueOwned ) ;
510- }
511- }
512- }
513- }
514- }
389+ let result = Ty :: pointee_info_at ( * self , cx, offset) ;
515390
516391 cx. pointee_infos . borrow_mut ( ) . insert ( ( self . ty , offset) , result) ;
517392 result
0 commit comments