void irgen::applyLayoutAttributes(IRGenModule &IGM, CanType ASTTy, bool IsFixedLayout, Alignment &MinimumAlign) { assert(ASTTy && "shouldn't call applyLayoutAttributes without a type"); auto &Diags = IGM.Context.Diags; auto decl = ASTTy->getAnyNominal(); if (!decl) return; if (auto alignment = decl->getAttrs().getAttribute<AlignmentAttr>()) { auto value = alignment->getValue(); assert(value != 0 && ((value - 1) & value) == 0 && "alignment not a power of two!"); if (!IsFixedLayout) Diags.diagnose(alignment->getLocation(), diag::alignment_dynamic_type_layout_unsupported); else if (value < MinimumAlign.getValue()) Diags.diagnose(alignment->getLocation(), diag::alignment_less_than_natural, MinimumAlign.getValue()); else MinimumAlign = Alignment(value); } }
DebugTypeInfo DebugTypeInfo::getGlobal(SILGlobalVariable *GV, llvm::Type *StorageTy, Size size, Alignment align) { // Prefer the original, potentially sugared version of the type if // the type hasn't been mucked with by an optimization pass. DeclContext *DC = nullptr; GenericEnvironment *GE = nullptr; auto LowTy = GV->getLoweredType().getSwiftRValueType(); auto *Type = LowTy.getPointer(); if (auto *Decl = GV->getDecl()) { DC = Decl->getDeclContext(); GE = DC->getGenericEnvironmentOfContext(); auto DeclType = (Decl->hasType() ? Decl->getType() : DC->mapTypeIntoContext(Decl->getInterfaceType())); if (DeclType->isEqual(LowTy)) Type = DeclType.getPointer(); } DebugTypeInfo DbgTy(DC, GE, Type, StorageTy, size, align); assert(StorageTy && "StorageType is a nullptr"); assert(!DbgTy.isArchetype() && "type of a global var cannot contain an archetype"); assert(align.getValue() != 0); return DbgTy; }
DebugTypeInfo::DebugTypeInfo(DeclContext *DC, swift::Type Ty, llvm::Type *StorageTy, Size size, Alignment align) : DeclCtx(DC), Type(Ty.getPointer()), StorageType(StorageTy), size(size), align(align) { assert((!isArchetype() || (isArchetype() && DC)) && "archetype without a declcontext"); assert(StorageType && "StorageType is a nullptr"); assert(align.getValue() != 0); }
DebugTypeInfo::DebugTypeInfo(DeclContext *DC, GenericEnvironment *GE, swift::Type Ty, llvm::Type *StorageTy, Size size, Alignment align, bool HasDefaultAlignment) : DeclCtx(DC), GenericEnv(GE), Type(Ty.getPointer()), StorageType(StorageTy), size(size), align(align), DefaultAlignment(HasDefaultAlignment) { assert(StorageType && "StorageType is a nullptr"); assert(align.getValue() != 0); }
void irgen::applyLayoutAttributes(IRGenModule &IGM, NominalTypeDecl *decl, bool IsFixedLayout, Alignment &MinimumAlign) { auto &Diags = IGM.Context.Diags; if (auto alignment = decl->getAttrs().getAttribute<AlignmentAttr>()) { auto value = alignment->getValue(); assert(value != 0 && ((value - 1) & value) == 0 && "alignment not a power of two!"); if (!IsFixedLayout) Diags.diagnose(alignment->getLocation(), diag::alignment_dynamic_type_layout_unsupported); else if (value < MinimumAlign.getValue()) Diags.diagnose(alignment->getLocation(), diag::alignment_less_than_natural, MinimumAlign.getValue()); else MinimumAlign = Alignment(value); } }
void StructLayoutBuilder::addFixedSizeElement(ElementLayout &elt) { auto &eltTI = cast<FixedTypeInfo>(elt.getTypeForLayout()); // Note that, even in the presence of elements with non-fixed // size, we continue to compute the minimum size and alignment // requirements of the overall aggregate as if all the // non-fixed-size elements were empty. This gives us minimum // bounds on the size and alignment of the aggregate. // The struct alignment is the max of the alignment of the fields. CurAlignment = std::max(CurAlignment, eltTI.getFixedAlignment()); // If the current tuple size isn't a multiple of the field's // required alignment, we need to pad out. Alignment eltAlignment = eltTI.getFixedAlignment(); if (Size offsetFromAlignment = CurSize % eltAlignment) { unsigned paddingRequired = eltAlignment.getValue() - offsetFromAlignment.getValue(); assert(paddingRequired != 0); // Regardless, the storage size goes up. CurSize += Size(paddingRequired); // Add the padding to the fixed layout. if (isFixedLayout()) { auto paddingTy = llvm::ArrayType::get(IGM.Int8Ty, paddingRequired); StructFields.push_back(paddingTy); // The padding can be used as spare bits by enum layout. CurSpareBits.appendSetBits(Size(paddingRequired).getValueInBits()); } } // If the overall structure so far has a fixed layout, then add // this as a field to the layout. if (isFixedLayout()) { addElementAtFixedOffset(elt); // Otherwise, just remember the next non-fixed offset index. } else { addElementAtNonFixedOffset(elt); } CurSize += eltTI.getFixedSize(); }
void IRGenFunction::emitMemCpy(llvm::Value *dest, llvm::Value *src, llvm::Value *size, Alignment align) { Builder.CreateMemCpy(dest, src, size, align.getValue(), false); }