1*06c3fb27SDimitry Andric //===- ABIInfo.cpp --------------------------------------------------------===// 2*06c3fb27SDimitry Andric // 3*06c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*06c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*06c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*06c3fb27SDimitry Andric // 7*06c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 8*06c3fb27SDimitry Andric 9*06c3fb27SDimitry Andric #include "ABIInfo.h" 10*06c3fb27SDimitry Andric #include "ABIInfoImpl.h" 11*06c3fb27SDimitry Andric 12*06c3fb27SDimitry Andric using namespace clang; 13*06c3fb27SDimitry Andric using namespace clang::CodeGen; 14*06c3fb27SDimitry Andric 15*06c3fb27SDimitry Andric // Pin the vtable to this file. 16*06c3fb27SDimitry Andric ABIInfo::~ABIInfo() = default; 17*06c3fb27SDimitry Andric 18*06c3fb27SDimitry Andric CGCXXABI &ABIInfo::getCXXABI() const { return CGT.getCXXABI(); } 19*06c3fb27SDimitry Andric 20*06c3fb27SDimitry Andric ASTContext &ABIInfo::getContext() const { return CGT.getContext(); } 21*06c3fb27SDimitry Andric 22*06c3fb27SDimitry Andric llvm::LLVMContext &ABIInfo::getVMContext() const { 23*06c3fb27SDimitry Andric return CGT.getLLVMContext(); 24*06c3fb27SDimitry Andric } 25*06c3fb27SDimitry Andric 26*06c3fb27SDimitry Andric const llvm::DataLayout &ABIInfo::getDataLayout() const { 27*06c3fb27SDimitry Andric return CGT.getDataLayout(); 28*06c3fb27SDimitry Andric } 29*06c3fb27SDimitry Andric 30*06c3fb27SDimitry Andric const TargetInfo &ABIInfo::getTarget() const { return CGT.getTarget(); } 31*06c3fb27SDimitry Andric 32*06c3fb27SDimitry Andric const CodeGenOptions &ABIInfo::getCodeGenOpts() const { 33*06c3fb27SDimitry Andric return CGT.getCodeGenOpts(); 34*06c3fb27SDimitry Andric } 35*06c3fb27SDimitry Andric 36*06c3fb27SDimitry Andric bool ABIInfo::isAndroid() const { return getTarget().getTriple().isAndroid(); } 37*06c3fb27SDimitry Andric 38*06c3fb27SDimitry Andric bool ABIInfo::isOHOSFamily() const { 39*06c3fb27SDimitry Andric return getTarget().getTriple().isOHOSFamily(); 40*06c3fb27SDimitry Andric } 41*06c3fb27SDimitry Andric 42*06c3fb27SDimitry Andric Address ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr, 43*06c3fb27SDimitry Andric QualType Ty) const { 44*06c3fb27SDimitry Andric return Address::invalid(); 45*06c3fb27SDimitry Andric } 46*06c3fb27SDimitry Andric 47*06c3fb27SDimitry Andric bool ABIInfo::isHomogeneousAggregateBaseType(QualType Ty) const { 48*06c3fb27SDimitry Andric return false; 49*06c3fb27SDimitry Andric } 50*06c3fb27SDimitry Andric 51*06c3fb27SDimitry Andric bool ABIInfo::isHomogeneousAggregateSmallEnough(const Type *Base, 52*06c3fb27SDimitry Andric uint64_t Members) const { 53*06c3fb27SDimitry Andric return false; 54*06c3fb27SDimitry Andric } 55*06c3fb27SDimitry Andric 56*06c3fb27SDimitry Andric bool ABIInfo::isZeroLengthBitfieldPermittedInHomogeneousAggregate() const { 57*06c3fb27SDimitry Andric // For compatibility with GCC, ignore empty bitfields in C++ mode. 58*06c3fb27SDimitry Andric return getContext().getLangOpts().CPlusPlus; 59*06c3fb27SDimitry Andric } 60*06c3fb27SDimitry Andric 61*06c3fb27SDimitry Andric bool ABIInfo::isHomogeneousAggregate(QualType Ty, const Type *&Base, 62*06c3fb27SDimitry Andric uint64_t &Members) const { 63*06c3fb27SDimitry Andric if (const ConstantArrayType *AT = getContext().getAsConstantArrayType(Ty)) { 64*06c3fb27SDimitry Andric uint64_t NElements = AT->getSize().getZExtValue(); 65*06c3fb27SDimitry Andric if (NElements == 0) 66*06c3fb27SDimitry Andric return false; 67*06c3fb27SDimitry Andric if (!isHomogeneousAggregate(AT->getElementType(), Base, Members)) 68*06c3fb27SDimitry Andric return false; 69*06c3fb27SDimitry Andric Members *= NElements; 70*06c3fb27SDimitry Andric } else if (const RecordType *RT = Ty->getAs<RecordType>()) { 71*06c3fb27SDimitry Andric const RecordDecl *RD = RT->getDecl(); 72*06c3fb27SDimitry Andric if (RD->hasFlexibleArrayMember()) 73*06c3fb27SDimitry Andric return false; 74*06c3fb27SDimitry Andric 75*06c3fb27SDimitry Andric Members = 0; 76*06c3fb27SDimitry Andric 77*06c3fb27SDimitry Andric // If this is a C++ record, check the properties of the record such as 78*06c3fb27SDimitry Andric // bases and ABI specific restrictions 79*06c3fb27SDimitry Andric if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) { 80*06c3fb27SDimitry Andric if (!getCXXABI().isPermittedToBeHomogeneousAggregate(CXXRD)) 81*06c3fb27SDimitry Andric return false; 82*06c3fb27SDimitry Andric 83*06c3fb27SDimitry Andric for (const auto &I : CXXRD->bases()) { 84*06c3fb27SDimitry Andric // Ignore empty records. 85*06c3fb27SDimitry Andric if (isEmptyRecord(getContext(), I.getType(), true)) 86*06c3fb27SDimitry Andric continue; 87*06c3fb27SDimitry Andric 88*06c3fb27SDimitry Andric uint64_t FldMembers; 89*06c3fb27SDimitry Andric if (!isHomogeneousAggregate(I.getType(), Base, FldMembers)) 90*06c3fb27SDimitry Andric return false; 91*06c3fb27SDimitry Andric 92*06c3fb27SDimitry Andric Members += FldMembers; 93*06c3fb27SDimitry Andric } 94*06c3fb27SDimitry Andric } 95*06c3fb27SDimitry Andric 96*06c3fb27SDimitry Andric for (const auto *FD : RD->fields()) { 97*06c3fb27SDimitry Andric // Ignore (non-zero arrays of) empty records. 98*06c3fb27SDimitry Andric QualType FT = FD->getType(); 99*06c3fb27SDimitry Andric while (const ConstantArrayType *AT = 100*06c3fb27SDimitry Andric getContext().getAsConstantArrayType(FT)) { 101*06c3fb27SDimitry Andric if (AT->getSize().getZExtValue() == 0) 102*06c3fb27SDimitry Andric return false; 103*06c3fb27SDimitry Andric FT = AT->getElementType(); 104*06c3fb27SDimitry Andric } 105*06c3fb27SDimitry Andric if (isEmptyRecord(getContext(), FT, true)) 106*06c3fb27SDimitry Andric continue; 107*06c3fb27SDimitry Andric 108*06c3fb27SDimitry Andric if (isZeroLengthBitfieldPermittedInHomogeneousAggregate() && 109*06c3fb27SDimitry Andric FD->isZeroLengthBitField(getContext())) 110*06c3fb27SDimitry Andric continue; 111*06c3fb27SDimitry Andric 112*06c3fb27SDimitry Andric uint64_t FldMembers; 113*06c3fb27SDimitry Andric if (!isHomogeneousAggregate(FD->getType(), Base, FldMembers)) 114*06c3fb27SDimitry Andric return false; 115*06c3fb27SDimitry Andric 116*06c3fb27SDimitry Andric Members = (RD->isUnion() ? 117*06c3fb27SDimitry Andric std::max(Members, FldMembers) : Members + FldMembers); 118*06c3fb27SDimitry Andric } 119*06c3fb27SDimitry Andric 120*06c3fb27SDimitry Andric if (!Base) 121*06c3fb27SDimitry Andric return false; 122*06c3fb27SDimitry Andric 123*06c3fb27SDimitry Andric // Ensure there is no padding. 124*06c3fb27SDimitry Andric if (getContext().getTypeSize(Base) * Members != 125*06c3fb27SDimitry Andric getContext().getTypeSize(Ty)) 126*06c3fb27SDimitry Andric return false; 127*06c3fb27SDimitry Andric } else { 128*06c3fb27SDimitry Andric Members = 1; 129*06c3fb27SDimitry Andric if (const ComplexType *CT = Ty->getAs<ComplexType>()) { 130*06c3fb27SDimitry Andric Members = 2; 131*06c3fb27SDimitry Andric Ty = CT->getElementType(); 132*06c3fb27SDimitry Andric } 133*06c3fb27SDimitry Andric 134*06c3fb27SDimitry Andric // Most ABIs only support float, double, and some vector type widths. 135*06c3fb27SDimitry Andric if (!isHomogeneousAggregateBaseType(Ty)) 136*06c3fb27SDimitry Andric return false; 137*06c3fb27SDimitry Andric 138*06c3fb27SDimitry Andric // The base type must be the same for all members. Types that 139*06c3fb27SDimitry Andric // agree in both total size and mode (float vs. vector) are 140*06c3fb27SDimitry Andric // treated as being equivalent here. 141*06c3fb27SDimitry Andric const Type *TyPtr = Ty.getTypePtr(); 142*06c3fb27SDimitry Andric if (!Base) { 143*06c3fb27SDimitry Andric Base = TyPtr; 144*06c3fb27SDimitry Andric // If it's a non-power-of-2 vector, its size is already a power-of-2, 145*06c3fb27SDimitry Andric // so make sure to widen it explicitly. 146*06c3fb27SDimitry Andric if (const VectorType *VT = Base->getAs<VectorType>()) { 147*06c3fb27SDimitry Andric QualType EltTy = VT->getElementType(); 148*06c3fb27SDimitry Andric unsigned NumElements = 149*06c3fb27SDimitry Andric getContext().getTypeSize(VT) / getContext().getTypeSize(EltTy); 150*06c3fb27SDimitry Andric Base = getContext() 151*06c3fb27SDimitry Andric .getVectorType(EltTy, NumElements, VT->getVectorKind()) 152*06c3fb27SDimitry Andric .getTypePtr(); 153*06c3fb27SDimitry Andric } 154*06c3fb27SDimitry Andric } 155*06c3fb27SDimitry Andric 156*06c3fb27SDimitry Andric if (Base->isVectorType() != TyPtr->isVectorType() || 157*06c3fb27SDimitry Andric getContext().getTypeSize(Base) != getContext().getTypeSize(TyPtr)) 158*06c3fb27SDimitry Andric return false; 159*06c3fb27SDimitry Andric } 160*06c3fb27SDimitry Andric return Members > 0 && isHomogeneousAggregateSmallEnough(Base, Members); 161*06c3fb27SDimitry Andric } 162*06c3fb27SDimitry Andric 163*06c3fb27SDimitry Andric bool ABIInfo::isPromotableIntegerTypeForABI(QualType Ty) const { 164*06c3fb27SDimitry Andric if (getContext().isPromotableIntegerType(Ty)) 165*06c3fb27SDimitry Andric return true; 166*06c3fb27SDimitry Andric 167*06c3fb27SDimitry Andric if (const auto *EIT = Ty->getAs<BitIntType>()) 168*06c3fb27SDimitry Andric if (EIT->getNumBits() < getContext().getTypeSize(getContext().IntTy)) 169*06c3fb27SDimitry Andric return true; 170*06c3fb27SDimitry Andric 171*06c3fb27SDimitry Andric return false; 172*06c3fb27SDimitry Andric } 173*06c3fb27SDimitry Andric 174*06c3fb27SDimitry Andric ABIArgInfo ABIInfo::getNaturalAlignIndirect(QualType Ty, bool ByVal, 175*06c3fb27SDimitry Andric bool Realign, 176*06c3fb27SDimitry Andric llvm::Type *Padding) const { 177*06c3fb27SDimitry Andric return ABIArgInfo::getIndirect(getContext().getTypeAlignInChars(Ty), ByVal, 178*06c3fb27SDimitry Andric Realign, Padding); 179*06c3fb27SDimitry Andric } 180*06c3fb27SDimitry Andric 181*06c3fb27SDimitry Andric ABIArgInfo ABIInfo::getNaturalAlignIndirectInReg(QualType Ty, 182*06c3fb27SDimitry Andric bool Realign) const { 183*06c3fb27SDimitry Andric return ABIArgInfo::getIndirectInReg(getContext().getTypeAlignInChars(Ty), 184*06c3fb27SDimitry Andric /*ByVal*/ false, Realign); 185*06c3fb27SDimitry Andric } 186*06c3fb27SDimitry Andric 187*06c3fb27SDimitry Andric // Pin the vtable to this file. 188*06c3fb27SDimitry Andric SwiftABIInfo::~SwiftABIInfo() = default; 189*06c3fb27SDimitry Andric 190*06c3fb27SDimitry Andric /// Does the given lowering require more than the given number of 191*06c3fb27SDimitry Andric /// registers when expanded? 192*06c3fb27SDimitry Andric /// 193*06c3fb27SDimitry Andric /// This is intended to be the basis of a reasonable basic implementation 194*06c3fb27SDimitry Andric /// of should{Pass,Return}Indirectly. 195*06c3fb27SDimitry Andric /// 196*06c3fb27SDimitry Andric /// For most targets, a limit of four total registers is reasonable; this 197*06c3fb27SDimitry Andric /// limits the amount of code required in order to move around the value 198*06c3fb27SDimitry Andric /// in case it wasn't produced immediately prior to the call by the caller 199*06c3fb27SDimitry Andric /// (or wasn't produced in exactly the right registers) or isn't used 200*06c3fb27SDimitry Andric /// immediately within the callee. But some targets may need to further 201*06c3fb27SDimitry Andric /// limit the register count due to an inability to support that many 202*06c3fb27SDimitry Andric /// return registers. 203*06c3fb27SDimitry Andric bool SwiftABIInfo::occupiesMoreThan(ArrayRef<llvm::Type *> scalarTypes, 204*06c3fb27SDimitry Andric unsigned maxAllRegisters) const { 205*06c3fb27SDimitry Andric unsigned intCount = 0, fpCount = 0; 206*06c3fb27SDimitry Andric for (llvm::Type *type : scalarTypes) { 207*06c3fb27SDimitry Andric if (type->isPointerTy()) { 208*06c3fb27SDimitry Andric intCount++; 209*06c3fb27SDimitry Andric } else if (auto intTy = dyn_cast<llvm::IntegerType>(type)) { 210*06c3fb27SDimitry Andric auto ptrWidth = CGT.getTarget().getPointerWidth(LangAS::Default); 211*06c3fb27SDimitry Andric intCount += (intTy->getBitWidth() + ptrWidth - 1) / ptrWidth; 212*06c3fb27SDimitry Andric } else { 213*06c3fb27SDimitry Andric assert(type->isVectorTy() || type->isFloatingPointTy()); 214*06c3fb27SDimitry Andric fpCount++; 215*06c3fb27SDimitry Andric } 216*06c3fb27SDimitry Andric } 217*06c3fb27SDimitry Andric 218*06c3fb27SDimitry Andric return (intCount + fpCount > maxAllRegisters); 219*06c3fb27SDimitry Andric } 220*06c3fb27SDimitry Andric 221*06c3fb27SDimitry Andric bool SwiftABIInfo::shouldPassIndirectly(ArrayRef<llvm::Type *> ComponentTys, 222*06c3fb27SDimitry Andric bool AsReturnValue) const { 223*06c3fb27SDimitry Andric return occupiesMoreThan(ComponentTys, /*total=*/4); 224*06c3fb27SDimitry Andric } 225*06c3fb27SDimitry Andric 226*06c3fb27SDimitry Andric bool SwiftABIInfo::isLegalVectorType(CharUnits VectorSize, llvm::Type *EltTy, 227*06c3fb27SDimitry Andric unsigned NumElts) const { 228*06c3fb27SDimitry Andric // The default implementation of this assumes that the target guarantees 229*06c3fb27SDimitry Andric // 128-bit SIMD support but nothing more. 230*06c3fb27SDimitry Andric return (VectorSize.getQuantity() > 8 && VectorSize.getQuantity() <= 16); 231*06c3fb27SDimitry Andric } 232