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