14967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar//===--- SwiftCallingConv.cpp - Lowering for the Swift calling convention -===// 24967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// 34967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// The LLVM Compiler Infrastructure 44967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// 54967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// This file is distributed under the University of Illinois Open Source 64967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// License. See LICENSE.TXT for details. 74967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// 84967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar//===----------------------------------------------------------------------===// 94967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// 104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// Implementation of the abstract lowering for the Swift calling convention. 114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// 124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar//===----------------------------------------------------------------------===// 134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "clang/CodeGen/SwiftCallingConv.h" 154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "clang/Basic/TargetInfo.h" 164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "CodeGenModule.h" 174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "TargetInfo.h" 184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarusing namespace clang; 204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarusing namespace CodeGen; 214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarusing namespace swiftcall; 224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstatic const SwiftABIInfo &getSwiftABIInfo(CodeGenModule &CGM) { 244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return cast<SwiftABIInfo>(CGM.getTargetCodeGenInfo().getABIInfo()); 254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstatic bool isPowerOf2(unsigned n) { 284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return n == (n & -n); 294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// Given two types with the same size, try to find a common type. 324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstatic llvm::Type *getCommonType(llvm::Type *first, llvm::Type *second) { 334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar assert(first != second); 344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Allow pointers to merge with integers, but prefer the integer type. 364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (first->isIntegerTy()) { 374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (second->isPointerTy()) return first; 384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } else if (first->isPointerTy()) { 394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (second->isIntegerTy()) return second; 404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (second->isPointerTy()) return first; 414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Allow two vectors to be merged (given that they have the same size). 434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // This assumes that we never have two different vector register sets. 444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } else if (auto firstVecTy = dyn_cast<llvm::VectorType>(first)) { 454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (auto secondVecTy = dyn_cast<llvm::VectorType>(second)) { 464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (auto commonTy = getCommonType(firstVecTy->getElementType(), 474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar secondVecTy->getElementType())) { 484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return (commonTy == firstVecTy->getElementType() ? first : second); 494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return nullptr; 544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstatic CharUnits getTypeStoreSize(CodeGenModule &CGM, llvm::Type *type) { 574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return CharUnits::fromQuantity(CGM.getDataLayout().getTypeStoreSize(type)); 584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid SwiftAggLowering::addTypedData(QualType type, CharUnits begin) { 614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Deal with various aggregate types as special cases: 624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Record types. 644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (auto recType = type->getAs<RecordType>()) { 654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar addTypedData(recType->getDecl(), begin); 664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Array types. 684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } else if (type->isArrayType()) { 694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Incomplete array types (flexible array members?) don't provide 704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // data to lay out, and the other cases shouldn't be possible. 714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto arrayType = CGM.getContext().getAsConstantArrayType(type); 724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (!arrayType) return; 734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar QualType eltType = arrayType->getElementType(); 754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto eltSize = CGM.getContext().getTypeSizeInChars(eltType); 764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar for (uint64_t i = 0, e = arrayType->getSize().getZExtValue(); i != e; ++i) { 774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar addTypedData(eltType, begin + i * eltSize); 784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Complex types. 814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } else if (auto complexType = type->getAs<ComplexType>()) { 824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto eltType = complexType->getElementType(); 834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto eltSize = CGM.getContext().getTypeSizeInChars(eltType); 844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto eltLLVMType = CGM.getTypes().ConvertType(eltType); 854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar addTypedData(eltLLVMType, begin, begin + eltSize); 864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar addTypedData(eltLLVMType, begin + eltSize, begin + 2 * eltSize); 874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Member pointer types. 894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } else if (type->getAs<MemberPointerType>()) { 904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Just add it all as opaque. 914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar addOpaqueData(begin, begin + CGM.getContext().getTypeSizeInChars(type)); 924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Everything else is scalar and should not convert as an LLVM aggregate. 944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } else { 954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // We intentionally convert as !ForMem because we want to preserve 964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // that a type was an i1. 974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto llvmType = CGM.getTypes().ConvertType(type); 984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar addTypedData(llvmType, begin); 994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 1004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 1014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 1024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid SwiftAggLowering::addTypedData(const RecordDecl *record, CharUnits begin) { 1034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar addTypedData(record, begin, CGM.getContext().getASTRecordLayout(record)); 1044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 1054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 1064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid SwiftAggLowering::addTypedData(const RecordDecl *record, CharUnits begin, 1074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar const ASTRecordLayout &layout) { 1084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Unions are a special case. 1094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (record->isUnion()) { 1104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar for (auto field : record->fields()) { 1114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (field->isBitField()) { 1124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar addBitFieldData(field, begin, 0); 1134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } else { 1144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar addTypedData(field->getType(), begin); 1154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 1164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 1174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return; 1184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 1194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 1204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Note that correctness does not rely on us adding things in 1214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // their actual order of layout; it's just somewhat more efficient 1224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // for the builder. 1234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 1244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // With that in mind, add "early" C++ data. 1254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto cxxRecord = dyn_cast<CXXRecordDecl>(record); 1264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (cxxRecord) { 1274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // - a v-table pointer, if the class adds its own 1284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (layout.hasOwnVFPtr()) { 1294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar addTypedData(CGM.Int8PtrTy, begin); 1304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 1314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 1324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // - non-virtual bases 1334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar for (auto &baseSpecifier : cxxRecord->bases()) { 1344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (baseSpecifier.isVirtual()) continue; 1354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 1364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto baseRecord = baseSpecifier.getType()->getAsCXXRecordDecl(); 1374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar addTypedData(baseRecord, begin + layout.getBaseClassOffset(baseRecord)); 1384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 1394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 1404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // - a vbptr if the class adds its own 1414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (layout.hasOwnVBPtr()) { 1424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar addTypedData(CGM.Int8PtrTy, begin + layout.getVBPtrOffset()); 1434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 1444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 1454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 1464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Add fields. 1474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar for (auto field : record->fields()) { 1484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto fieldOffsetInBits = layout.getFieldOffset(field->getFieldIndex()); 1494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (field->isBitField()) { 1504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar addBitFieldData(field, begin, fieldOffsetInBits); 1514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } else { 1524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar addTypedData(field->getType(), 1534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar begin + CGM.getContext().toCharUnitsFromBits(fieldOffsetInBits)); 1544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 1554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 1564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 1574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Add "late" C++ data: 1584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (cxxRecord) { 1594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // - virtual bases 1604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar for (auto &vbaseSpecifier : cxxRecord->vbases()) { 1614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto baseRecord = vbaseSpecifier.getType()->getAsCXXRecordDecl(); 1624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar addTypedData(baseRecord, begin + layout.getVBaseClassOffset(baseRecord)); 1634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 1644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 1654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 1664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 1674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid SwiftAggLowering::addBitFieldData(const FieldDecl *bitfield, 1684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar CharUnits recordBegin, 1694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar uint64_t bitfieldBitBegin) { 1704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar assert(bitfield->isBitField()); 1714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto &ctx = CGM.getContext(); 1724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto width = bitfield->getBitWidthValue(ctx); 1734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 1744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // We can ignore zero-width bit-fields. 1754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (width == 0) return; 1764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 1774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // toCharUnitsFromBits rounds down. 1784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar CharUnits bitfieldByteBegin = ctx.toCharUnitsFromBits(bitfieldBitBegin); 1794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 1804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Find the offset of the last byte that is partially occupied by the 1814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // bit-field; since we otherwise expect exclusive ends, the end is the 1824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // next byte. 1834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar uint64_t bitfieldBitLast = bitfieldBitBegin + width - 1; 1844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar CharUnits bitfieldByteEnd = 1854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar ctx.toCharUnitsFromBits(bitfieldBitLast) + CharUnits::One(); 1864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar addOpaqueData(recordBegin + bitfieldByteBegin, 1874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar recordBegin + bitfieldByteEnd); 1884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 1894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 1904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid SwiftAggLowering::addTypedData(llvm::Type *type, CharUnits begin) { 1914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar assert(type && "didn't provide type for typed data"); 1924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar addTypedData(type, begin, begin + getTypeStoreSize(CGM, type)); 1934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 1944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 1954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid SwiftAggLowering::addTypedData(llvm::Type *type, 1964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar CharUnits begin, CharUnits end) { 1974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar assert(type && "didn't provide type for typed data"); 1984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar assert(getTypeStoreSize(CGM, type) == end - begin); 1994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 2004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Legalize vector types. 2014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (auto vecTy = dyn_cast<llvm::VectorType>(type)) { 2024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar SmallVector<llvm::Type*, 4> componentTys; 2034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar legalizeVectorType(CGM, end - begin, vecTy, componentTys); 2044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar assert(componentTys.size() >= 1); 2054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 2064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Walk the initial components. 2074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar for (size_t i = 0, e = componentTys.size(); i != e - 1; ++i) { 2084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar llvm::Type *componentTy = componentTys[i]; 2094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto componentSize = getTypeStoreSize(CGM, componentTy); 2104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar assert(componentSize < end - begin); 2114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar addLegalTypedData(componentTy, begin, begin + componentSize); 2124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar begin += componentSize; 2134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 2144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 2154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return addLegalTypedData(componentTys.back(), begin, end); 2164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 2174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 2184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Legalize integer types. 2194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (auto intTy = dyn_cast<llvm::IntegerType>(type)) { 2204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (!isLegalIntegerType(CGM, intTy)) 2214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return addOpaqueData(begin, end); 2224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 2234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 2244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // All other types should be legal. 2254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return addLegalTypedData(type, begin, end); 2264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 2274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 2284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid SwiftAggLowering::addLegalTypedData(llvm::Type *type, 2294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar CharUnits begin, CharUnits end) { 2304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Require the type to be naturally aligned. 2314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (!begin.isZero() && !begin.isMultipleOf(getNaturalAlignment(CGM, type))) { 2324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 2334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Try splitting vector types. 2344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (auto vecTy = dyn_cast<llvm::VectorType>(type)) { 2354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto split = splitLegalVectorType(CGM, end - begin, vecTy); 2364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto eltTy = split.first; 2374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto numElts = split.second; 2384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 2394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto eltSize = (end - begin) / numElts; 2404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar assert(eltSize == getTypeStoreSize(CGM, eltTy)); 2414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar for (size_t i = 0, e = numElts; i != e; ++i) { 2424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar addLegalTypedData(eltTy, begin, begin + eltSize); 2434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar begin += eltSize; 2444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 2454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar assert(begin == end); 2464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return; 2474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 2484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 2494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return addOpaqueData(begin, end); 2504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 2514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 2524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar addEntry(type, begin, end); 2534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 2544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 2554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid SwiftAggLowering::addEntry(llvm::Type *type, 2564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar CharUnits begin, CharUnits end) { 2574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar assert((!type || 2584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar (!isa<llvm::StructType>(type) && !isa<llvm::ArrayType>(type))) && 2594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar "cannot add aggregate-typed data"); 2604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar assert(!type || begin.isMultipleOf(getNaturalAlignment(CGM, type))); 2614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 2624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Fast path: we can just add entries to the end. 2634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (Entries.empty() || Entries.back().End <= begin) { 2644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Entries.push_back({begin, end, type}); 2654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return; 2664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 2674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 2684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Find the first existing entry that ends after the start of the new data. 2694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // TODO: do a binary search if Entries is big enough for it to matter. 2704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar size_t index = Entries.size() - 1; 2714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar while (index != 0) { 2724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (Entries[index - 1].End <= begin) break; 2734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar --index; 2744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 2754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 2764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // The entry ends after the start of the new data. 2774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // If the entry starts after the end of the new data, there's no conflict. 2784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (Entries[index].Begin >= end) { 2794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // This insertion is potentially O(n), but the way we generally build 2804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // these layouts makes that unlikely to matter: we'd need a union of 2814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // several very large types. 2824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Entries.insert(Entries.begin() + index, {begin, end, type}); 2834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return; 2844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 2854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 2864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Otherwise, the ranges overlap. The new range might also overlap 2874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // with later ranges. 2884967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarrestartAfterSplit: 2894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 2904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Simplest case: an exact overlap. 2914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (Entries[index].Begin == begin && Entries[index].End == end) { 2924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // If the types match exactly, great. 2934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (Entries[index].Type == type) return; 2944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 2954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // If either type is opaque, make the entry opaque and return. 2964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (Entries[index].Type == nullptr) { 2974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return; 2984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } else if (type == nullptr) { 2994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Entries[index].Type = nullptr; 3004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return; 3014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 3024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 3034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // If they disagree in an ABI-agnostic way, just resolve the conflict 3044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // arbitrarily. 3054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (auto entryType = getCommonType(Entries[index].Type, type)) { 3064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Entries[index].Type = entryType; 3074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return; 3084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 3094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 3104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Otherwise, make the entry opaque. 3114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Entries[index].Type = nullptr; 3124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return; 3134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 3144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 3154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Okay, we have an overlapping conflict of some sort. 3164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 3174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // If we have a vector type, split it. 3184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (auto vecTy = dyn_cast_or_null<llvm::VectorType>(type)) { 3194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto eltTy = vecTy->getElementType(); 3204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar CharUnits eltSize = (end - begin) / vecTy->getNumElements(); 3214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar assert(eltSize == getTypeStoreSize(CGM, eltTy)); 3224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar for (unsigned i = 0, e = vecTy->getNumElements(); i != e; ++i) { 3234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar addEntry(eltTy, begin, begin + eltSize); 3244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar begin += eltSize; 3254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 3264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar assert(begin == end); 3274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return; 3284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 3294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 3304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // If the entry is a vector type, split it and try again. 3314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (Entries[index].Type && Entries[index].Type->isVectorTy()) { 3324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar splitVectorEntry(index); 3334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar goto restartAfterSplit; 3344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 3354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 3364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Okay, we have no choice but to make the existing entry opaque. 3374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 3384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Entries[index].Type = nullptr; 3394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 3404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Stretch the start of the entry to the beginning of the range. 3414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (begin < Entries[index].Begin) { 3424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Entries[index].Begin = begin; 3434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar assert(index == 0 || begin >= Entries[index - 1].End); 3444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 3454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 3464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Stretch the end of the entry to the end of the range; but if we run 3474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // into the start of the next entry, just leave the range there and repeat. 3484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar while (end > Entries[index].End) { 3494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar assert(Entries[index].Type == nullptr); 3504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 3514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // If the range doesn't overlap the next entry, we're done. 3524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (index == Entries.size() - 1 || end <= Entries[index + 1].Begin) { 3534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Entries[index].End = end; 3544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar break; 3554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 3564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 3574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Otherwise, stretch to the start of the next entry. 3584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Entries[index].End = Entries[index + 1].Begin; 3594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 3604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Continue with the next entry. 3614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar index++; 3624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 3634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // This entry needs to be made opaque if it is not already. 3644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (Entries[index].Type == nullptr) 3654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar continue; 3664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 3674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Split vector entries unless we completely subsume them. 3684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (Entries[index].Type->isVectorTy() && 3694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar end < Entries[index].End) { 3704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar splitVectorEntry(index); 3714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 3724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 3734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Make the entry opaque. 3744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Entries[index].Type = nullptr; 3754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 3764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 3774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 3784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// Replace the entry of vector type at offset 'index' with a sequence 3794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// of its component vectors. 3804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid SwiftAggLowering::splitVectorEntry(unsigned index) { 3814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto vecTy = cast<llvm::VectorType>(Entries[index].Type); 3824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto split = splitLegalVectorType(CGM, Entries[index].getWidth(), vecTy); 3834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 3844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto eltTy = split.first; 3854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar CharUnits eltSize = getTypeStoreSize(CGM, eltTy); 3864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto numElts = split.second; 3874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Entries.insert(&Entries[index + 1], numElts - 1, StorageEntry()); 3884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 3894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar CharUnits begin = Entries[index].Begin; 3904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar for (unsigned i = 0; i != numElts; ++i) { 3914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Entries[index].Type = eltTy; 3924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Entries[index].Begin = begin; 3934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Entries[index].End = begin + eltSize; 3944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar begin += eltSize; 3954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 3964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 3974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 3984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// Given a power-of-two unit size, return the offset of the aligned unit 3994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// of that size which contains the given offset. 4004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// 4014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// In other words, round down to the nearest multiple of the unit size. 4024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstatic CharUnits getOffsetAtStartOfUnit(CharUnits offset, CharUnits unitSize) { 4034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar assert(isPowerOf2(unitSize.getQuantity())); 4044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto unitMask = ~(unitSize.getQuantity() - 1); 4054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return CharUnits::fromQuantity(offset.getQuantity() & unitMask); 4064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 4074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 4084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstatic bool areBytesInSameUnit(CharUnits first, CharUnits second, 4094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar CharUnits chunkSize) { 4104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return getOffsetAtStartOfUnit(first, chunkSize) 4114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar == getOffsetAtStartOfUnit(second, chunkSize); 4124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 4134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 4144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid SwiftAggLowering::finish() { 4154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (Entries.empty()) { 4164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Finished = true; 4174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return; 4184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 4194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 4204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // We logically split the layout down into a series of chunks of this size, 4214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // which is generally the size of a pointer. 4224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar const CharUnits chunkSize = getMaximumVoluntaryIntegerSize(CGM); 4234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 4244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // First pass: if two entries share a chunk, make them both opaque 4254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // and stretch one to meet the next. 4264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar bool hasOpaqueEntries = (Entries[0].Type == nullptr); 4274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar for (size_t i = 1, e = Entries.size(); i != e; ++i) { 4284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (areBytesInSameUnit(Entries[i - 1].End - CharUnits::One(), 4294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Entries[i].Begin, chunkSize)) { 4304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Entries[i - 1].Type = nullptr; 4314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Entries[i].Type = nullptr; 4324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Entries[i - 1].End = Entries[i].Begin; 4334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar hasOpaqueEntries = true; 4344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 4354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } else if (Entries[i].Type == nullptr) { 4364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar hasOpaqueEntries = true; 4374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 4384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 4394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 4404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // The rest of the algorithm leaves non-opaque entries alone, so if we 4414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // have no opaque entries, we're done. 4424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (!hasOpaqueEntries) { 4434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Finished = true; 4444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return; 4454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 4464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 4474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Okay, move the entries to a temporary and rebuild Entries. 4484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto orig = std::move(Entries); 4494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar assert(Entries.empty()); 4504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 4514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar for (size_t i = 0, e = orig.size(); i != e; ++i) { 4524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Just copy over non-opaque entries. 4534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (orig[i].Type != nullptr) { 4544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Entries.push_back(orig[i]); 4554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar continue; 4564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 4574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 4584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Scan forward to determine the full extent of the next opaque range. 4594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // We know from the first pass that only contiguous ranges will overlap 4604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // the same aligned chunk. 4614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto begin = orig[i].Begin; 4624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto end = orig[i].End; 4634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar while (i + 1 != e && 4644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar orig[i + 1].Type == nullptr && 4654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar end == orig[i + 1].Begin) { 4664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar end = orig[i + 1].End; 4674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar i++; 4684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 4694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 4704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Add an entry per intersected chunk. 4714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar do { 4724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Find the smallest aligned storage unit in the maximal aligned 4734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // storage unit containing 'begin' that contains all the bytes in 4744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // the intersection between the range and this chunk. 4754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar CharUnits localBegin = begin; 4764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar CharUnits chunkBegin = getOffsetAtStartOfUnit(localBegin, chunkSize); 4774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar CharUnits chunkEnd = chunkBegin + chunkSize; 4784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar CharUnits localEnd = std::min(end, chunkEnd); 4794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 4804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Just do a simple loop over ever-increasing unit sizes. 4814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar CharUnits unitSize = CharUnits::One(); 4824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar CharUnits unitBegin, unitEnd; 4834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar for (; ; unitSize *= 2) { 4844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar assert(unitSize <= chunkSize); 4854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar unitBegin = getOffsetAtStartOfUnit(localBegin, unitSize); 4864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar unitEnd = unitBegin + unitSize; 4874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (unitEnd >= localEnd) break; 4884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 4894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 4904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Add an entry for this unit. 4914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto entryTy = 4924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar llvm::IntegerType::get(CGM.getLLVMContext(), 4934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar CGM.getContext().toBits(unitSize)); 4944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Entries.push_back({unitBegin, unitEnd, entryTy}); 4954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 4964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // The next chunk starts where this chunk left off. 4974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar begin = localEnd; 4984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } while (begin != end); 4994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 5004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 5014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Okay, finally finished. 5024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Finished = true; 5034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 5044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 5054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid SwiftAggLowering::enumerateComponents(EnumerationCallback callback) const { 5064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar assert(Finished && "haven't yet finished lowering"); 5074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 5084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar for (auto &entry : Entries) { 5094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar callback(entry.Begin, entry.Type); 5104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 5114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 5124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 5134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstd::pair<llvm::StructType*, llvm::Type*> 5144967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarSwiftAggLowering::getCoerceAndExpandTypes() const { 5154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar assert(Finished && "haven't yet finished lowering"); 5164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 5174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto &ctx = CGM.getLLVMContext(); 5184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 5194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (Entries.empty()) { 5204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto type = llvm::StructType::get(ctx); 5214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return { type, type }; 5224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 5234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 5244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar SmallVector<llvm::Type*, 8> elts; 5254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar CharUnits lastEnd = CharUnits::Zero(); 5264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar bool hasPadding = false; 5274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar bool packed = false; 5284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar for (auto &entry : Entries) { 5294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (entry.Begin != lastEnd) { 5304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto paddingSize = entry.Begin - lastEnd; 5314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar assert(!paddingSize.isNegative()); 5324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 5334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto padding = llvm::ArrayType::get(llvm::Type::getInt8Ty(ctx), 5344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar paddingSize.getQuantity()); 5354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar elts.push_back(padding); 5364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar hasPadding = true; 5374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 5384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 5394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (!packed && !entry.Begin.isMultipleOf( 5404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar CharUnits::fromQuantity( 5414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar CGM.getDataLayout().getABITypeAlignment(entry.Type)))) 5424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar packed = true; 5434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 5444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar elts.push_back(entry.Type); 5454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar lastEnd = entry.End; 5464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 5474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 5484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // We don't need to adjust 'packed' to deal with possible tail padding 5494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // because we never do that kind of access through the coercion type. 5504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto coercionType = llvm::StructType::get(ctx, elts, packed); 5514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 5524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar llvm::Type *unpaddedType = coercionType; 5534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (hasPadding) { 5544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar elts.clear(); 5554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar for (auto &entry : Entries) { 5564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar elts.push_back(entry.Type); 5574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 5584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (elts.size() == 1) { 5594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar unpaddedType = elts[0]; 5604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } else { 5614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar unpaddedType = llvm::StructType::get(ctx, elts, /*packed*/ false); 5624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 5634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } else if (Entries.size() == 1) { 5644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar unpaddedType = Entries[0].Type; 5654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 5664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 5674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return { coercionType, unpaddedType }; 5684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 5694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 5704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarbool SwiftAggLowering::shouldPassIndirectly(bool asReturnValue) const { 5714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar assert(Finished && "haven't yet finished lowering"); 5724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 5734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Empty types don't need to be passed indirectly. 5744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (Entries.empty()) return false; 5754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 5764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar CharUnits totalSize = Entries.back().End; 5774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 5784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Avoid copying the array of types when there's just a single element. 5794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (Entries.size() == 1) { 5804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return getSwiftABIInfo(CGM).shouldPassIndirectlyForSwift(totalSize, 5814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Entries.back().Type, 5824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar asReturnValue); 5834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 5844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 5854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar SmallVector<llvm::Type*, 8> componentTys; 5864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar componentTys.reserve(Entries.size()); 5874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar for (auto &entry : Entries) { 5884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar componentTys.push_back(entry.Type); 5894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 5904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return getSwiftABIInfo(CGM).shouldPassIndirectlyForSwift(totalSize, 5914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar componentTys, 5924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar asReturnValue); 5934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 5944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 5954967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarCharUnits swiftcall::getMaximumVoluntaryIntegerSize(CodeGenModule &CGM) { 5964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Currently always the size of an ordinary pointer. 5974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return CGM.getContext().toCharUnitsFromBits( 5984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar CGM.getContext().getTargetInfo().getPointerWidth(0)); 5994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 6004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 6014967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarCharUnits swiftcall::getNaturalAlignment(CodeGenModule &CGM, llvm::Type *type) { 6024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // For Swift's purposes, this is always just the store size of the type 6034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // rounded up to a power of 2. 6044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto size = (unsigned long long) getTypeStoreSize(CGM, type).getQuantity(); 6054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (!isPowerOf2(size)) { 6064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar size = 1ULL << (llvm::findLastSet(size, llvm::ZB_Undefined) + 1); 6074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 6084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar assert(size >= CGM.getDataLayout().getABITypeAlignment(type)); 6094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return CharUnits::fromQuantity(size); 6104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 6114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 6124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarbool swiftcall::isLegalIntegerType(CodeGenModule &CGM, 6134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar llvm::IntegerType *intTy) { 6144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto size = intTy->getBitWidth(); 6154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar switch (size) { 6164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar case 1: 6174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar case 8: 6184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar case 16: 6194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar case 32: 6204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar case 64: 6214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Just assume that the above are always legal. 6224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return true; 6234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 6244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar case 128: 6254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return CGM.getContext().getTargetInfo().hasInt128Type(); 6264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 6274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar default: 6284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return false; 6294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 6304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 6314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 6324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarbool swiftcall::isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize, 6334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar llvm::VectorType *vectorTy) { 6344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return isLegalVectorType(CGM, vectorSize, vectorTy->getElementType(), 6354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar vectorTy->getNumElements()); 6364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 6374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 6384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarbool swiftcall::isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize, 6394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar llvm::Type *eltTy, unsigned numElts) { 6404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar assert(numElts > 1 && "illegal vector length"); 6414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return getSwiftABIInfo(CGM) 6424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar .isLegalVectorTypeForSwift(vectorSize, eltTy, numElts); 6434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 6444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 6454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstd::pair<llvm::Type*, unsigned> 6464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarswiftcall::splitLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize, 6474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar llvm::VectorType *vectorTy) { 6484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto numElts = vectorTy->getNumElements(); 6494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto eltTy = vectorTy->getElementType(); 6504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 6514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Try to split the vector type in half. 6524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (numElts >= 4 && isPowerOf2(numElts)) { 6534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (isLegalVectorType(CGM, vectorSize / 2, eltTy, numElts / 2)) 6544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return {llvm::VectorType::get(eltTy, numElts / 2), 2}; 6554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 6564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 6574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return {eltTy, numElts}; 6584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 6594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 6604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid swiftcall::legalizeVectorType(CodeGenModule &CGM, CharUnits origVectorSize, 6614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar llvm::VectorType *origVectorTy, 6624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar llvm::SmallVectorImpl<llvm::Type*> &components) { 6634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // If it's already a legal vector type, use it. 6644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (isLegalVectorType(CGM, origVectorSize, origVectorTy)) { 6654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar components.push_back(origVectorTy); 6664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return; 6674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 6684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 6694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Try to split the vector into legal subvectors. 6704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto numElts = origVectorTy->getNumElements(); 6714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto eltTy = origVectorTy->getElementType(); 6724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar assert(numElts != 1); 6734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 6744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // The largest size that we're still considering making subvectors of. 6754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Always a power of 2. 6764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar unsigned logCandidateNumElts = llvm::findLastSet(numElts, llvm::ZB_Undefined); 6774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar unsigned candidateNumElts = 1U << logCandidateNumElts; 6784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar assert(candidateNumElts <= numElts && candidateNumElts * 2 > numElts); 6794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 6804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Minor optimization: don't check the legality of this exact size twice. 6814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (candidateNumElts == numElts) { 6824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar logCandidateNumElts--; 6834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar candidateNumElts >>= 1; 6844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 6854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 6864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar CharUnits eltSize = (origVectorSize / numElts); 6874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar CharUnits candidateSize = eltSize * candidateNumElts; 6884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 6894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // The sensibility of this algorithm relies on the fact that we never 6904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // have a legal non-power-of-2 vector size without having the power of 2 6914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // also be legal. 6924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar while (logCandidateNumElts > 0) { 6934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar assert(candidateNumElts == 1U << logCandidateNumElts); 6944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar assert(candidateNumElts <= numElts); 6954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar assert(candidateSize == eltSize * candidateNumElts); 6964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 6974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Skip illegal vector sizes. 6984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (!isLegalVectorType(CGM, candidateSize, eltTy, candidateNumElts)) { 6994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar logCandidateNumElts--; 7004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar candidateNumElts /= 2; 7014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar candidateSize /= 2; 7024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar continue; 7034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 7044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 7054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Add the right number of vectors of this size. 7064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto numVecs = numElts >> logCandidateNumElts; 7074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar components.append(numVecs, llvm::VectorType::get(eltTy, candidateNumElts)); 7084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar numElts -= (numVecs << logCandidateNumElts); 7094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 7104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (numElts == 0) return; 7114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 7124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // It's possible that the number of elements remaining will be legal. 7134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // This can happen with e.g. <7 x float> when <3 x float> is legal. 7144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // This only needs to be separately checked if it's not a power of 2. 7154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (numElts > 2 && !isPowerOf2(numElts) && 7164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar isLegalVectorType(CGM, eltSize * numElts, eltTy, numElts)) { 7174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar components.push_back(llvm::VectorType::get(eltTy, numElts)); 7184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return; 7194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 7204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 7214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Bring vecSize down to something no larger than numElts. 7224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar do { 7234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar logCandidateNumElts--; 7244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar candidateNumElts /= 2; 7254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar candidateSize /= 2; 7264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } while (candidateNumElts > numElts); 7274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 7284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 7294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Otherwise, just append a bunch of individual elements. 7304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar components.append(numElts, eltTy); 7314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 7324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 7334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarbool swiftcall::shouldPassCXXRecordIndirectly(CodeGenModule &CGM, 7344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar const CXXRecordDecl *record) { 7354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Following a recommendation from Richard Smith, pass a C++ type 7364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // indirectly only if the destructor is non-trivial or *all* of the 7374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // copy/move constructors are deleted or non-trivial. 7384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 7394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (record->hasNonTrivialDestructor()) 7404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return true; 7414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 7424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // It would be nice if this were summarized on the CXXRecordDecl. 7434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar for (auto ctor : record->ctors()) { 7444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (ctor->isCopyOrMoveConstructor() && !ctor->isDeleted() && 7454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar ctor->isTrivial()) { 7464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return false; 7474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 7484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 7494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 7504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return true; 7514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 7524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 7534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstatic ABIArgInfo classifyExpandedType(SwiftAggLowering &lowering, 7544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar bool forReturn, 7554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar CharUnits alignmentForIndirect) { 7564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (lowering.empty()) { 7574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return ABIArgInfo::getIgnore(); 7584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } else if (lowering.shouldPassIndirectly(forReturn)) { 7594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return ABIArgInfo::getIndirect(alignmentForIndirect, /*byval*/ false); 7604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } else { 7614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto types = lowering.getCoerceAndExpandTypes(); 7624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return ABIArgInfo::getCoerceAndExpand(types.first, types.second); 7634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 7644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 7654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 7664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstatic ABIArgInfo classifyType(CodeGenModule &CGM, CanQualType type, 7674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar bool forReturn) { 7684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (auto recordType = dyn_cast<RecordType>(type)) { 7694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto record = recordType->getDecl(); 7704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto &layout = CGM.getContext().getASTRecordLayout(record); 7714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 7724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (auto cxxRecord = dyn_cast<CXXRecordDecl>(record)) { 7734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (shouldPassCXXRecordIndirectly(CGM, cxxRecord)) 7744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return ABIArgInfo::getIndirect(layout.getAlignment(), /*byval*/ false); 7754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 7764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 7774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar SwiftAggLowering lowering(CGM); 7784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar lowering.addTypedData(recordType->getDecl(), CharUnits::Zero(), layout); 7794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar lowering.finish(); 7804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 7814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return classifyExpandedType(lowering, forReturn, layout.getAlignment()); 7824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 7834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 7844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Just assume that all of our target ABIs can support returning at least 7854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // two integer or floating-point values. 7864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (isa<ComplexType>(type)) { 7874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return (forReturn ? ABIArgInfo::getDirect() : ABIArgInfo::getExpand()); 7884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 7894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 7904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Vector types may need to be legalized. 7914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (isa<VectorType>(type)) { 7924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar SwiftAggLowering lowering(CGM); 7934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar lowering.addTypedData(type, CharUnits::Zero()); 7944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar lowering.finish(); 7954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 7964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar CharUnits alignment = CGM.getContext().getTypeAlignInChars(type); 7974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return classifyExpandedType(lowering, forReturn, alignment); 7984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 7994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 8004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Member pointer types need to be expanded, but it's a simple form of 8014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // expansion that 'Direct' can handle. Note that CanBeFlattened should be 8024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // true for this to work. 8034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 8044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // 'void' needs to be ignored. 8054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (type->isVoidType()) { 8064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return ABIArgInfo::getIgnore(); 8074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 8084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 8094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Everything else can be passed directly. 8104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return ABIArgInfo::getDirect(); 8114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 8124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 8134967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarABIArgInfo swiftcall::classifyReturnType(CodeGenModule &CGM, CanQualType type) { 8144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return classifyType(CGM, type, /*forReturn*/ true); 8154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 8164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 8174967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarABIArgInfo swiftcall::classifyArgumentType(CodeGenModule &CGM, 8184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar CanQualType type) { 8194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return classifyType(CGM, type, /*forReturn*/ false); 8204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 8214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 8224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid swiftcall::computeABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI) { 8234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto &retInfo = FI.getReturnInfo(); 8244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar retInfo = classifyReturnType(CGM, FI.getReturnType()); 8254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 8264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar for (unsigned i = 0, e = FI.arg_size(); i != e; ++i) { 8274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto &argInfo = FI.arg_begin()[i]; 8284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar argInfo.info = classifyArgumentType(CGM, argInfo.type); 8294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 8304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 831