106c3fb27SDimitry Andric //===- ABIInfo.cpp --------------------------------------------------------===// 206c3fb27SDimitry Andric // 306c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 406c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 506c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 606c3fb27SDimitry Andric // 706c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 806c3fb27SDimitry Andric 906c3fb27SDimitry Andric #include "ABIInfo.h" 1006c3fb27SDimitry Andric #include "ABIInfoImpl.h" 1106c3fb27SDimitry Andric 1206c3fb27SDimitry Andric using namespace clang; 1306c3fb27SDimitry Andric using namespace clang::CodeGen; 1406c3fb27SDimitry Andric 1506c3fb27SDimitry Andric // Pin the vtable to this file. 1606c3fb27SDimitry Andric ABIInfo::~ABIInfo() = default; 1706c3fb27SDimitry Andric 1806c3fb27SDimitry Andric CGCXXABI &ABIInfo::getCXXABI() const { return CGT.getCXXABI(); } 1906c3fb27SDimitry Andric 2006c3fb27SDimitry Andric ASTContext &ABIInfo::getContext() const { return CGT.getContext(); } 2106c3fb27SDimitry Andric 2206c3fb27SDimitry Andric llvm::LLVMContext &ABIInfo::getVMContext() const { 2306c3fb27SDimitry Andric return CGT.getLLVMContext(); 2406c3fb27SDimitry Andric } 2506c3fb27SDimitry Andric 2606c3fb27SDimitry Andric const llvm::DataLayout &ABIInfo::getDataLayout() const { 2706c3fb27SDimitry Andric return CGT.getDataLayout(); 2806c3fb27SDimitry Andric } 2906c3fb27SDimitry Andric 3006c3fb27SDimitry Andric const TargetInfo &ABIInfo::getTarget() const { return CGT.getTarget(); } 3106c3fb27SDimitry Andric 3206c3fb27SDimitry Andric const CodeGenOptions &ABIInfo::getCodeGenOpts() const { 3306c3fb27SDimitry Andric return CGT.getCodeGenOpts(); 3406c3fb27SDimitry Andric } 3506c3fb27SDimitry Andric 3606c3fb27SDimitry Andric bool ABIInfo::isAndroid() const { return getTarget().getTriple().isAndroid(); } 3706c3fb27SDimitry Andric 3806c3fb27SDimitry Andric bool ABIInfo::isOHOSFamily() const { 3906c3fb27SDimitry Andric return getTarget().getTriple().isOHOSFamily(); 4006c3fb27SDimitry Andric } 4106c3fb27SDimitry Andric 42*0fca6ea1SDimitry Andric RValue ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr, 43*0fca6ea1SDimitry Andric QualType Ty, AggValueSlot Slot) const { 44*0fca6ea1SDimitry Andric return RValue::getIgnored(); 4506c3fb27SDimitry Andric } 4606c3fb27SDimitry Andric 4706c3fb27SDimitry Andric bool ABIInfo::isHomogeneousAggregateBaseType(QualType Ty) const { 4806c3fb27SDimitry Andric return false; 4906c3fb27SDimitry Andric } 5006c3fb27SDimitry Andric 5106c3fb27SDimitry Andric bool ABIInfo::isHomogeneousAggregateSmallEnough(const Type *Base, 5206c3fb27SDimitry Andric uint64_t Members) const { 5306c3fb27SDimitry Andric return false; 5406c3fb27SDimitry Andric } 5506c3fb27SDimitry Andric 5606c3fb27SDimitry Andric bool ABIInfo::isZeroLengthBitfieldPermittedInHomogeneousAggregate() const { 5706c3fb27SDimitry Andric // For compatibility with GCC, ignore empty bitfields in C++ mode. 5806c3fb27SDimitry Andric return getContext().getLangOpts().CPlusPlus; 5906c3fb27SDimitry Andric } 6006c3fb27SDimitry Andric 6106c3fb27SDimitry Andric bool ABIInfo::isHomogeneousAggregate(QualType Ty, const Type *&Base, 6206c3fb27SDimitry Andric uint64_t &Members) const { 6306c3fb27SDimitry Andric if (const ConstantArrayType *AT = getContext().getAsConstantArrayType(Ty)) { 64*0fca6ea1SDimitry Andric uint64_t NElements = AT->getZExtSize(); 6506c3fb27SDimitry Andric if (NElements == 0) 6606c3fb27SDimitry Andric return false; 6706c3fb27SDimitry Andric if (!isHomogeneousAggregate(AT->getElementType(), Base, Members)) 6806c3fb27SDimitry Andric return false; 6906c3fb27SDimitry Andric Members *= NElements; 7006c3fb27SDimitry Andric } else if (const RecordType *RT = Ty->getAs<RecordType>()) { 7106c3fb27SDimitry Andric const RecordDecl *RD = RT->getDecl(); 7206c3fb27SDimitry Andric if (RD->hasFlexibleArrayMember()) 7306c3fb27SDimitry Andric return false; 7406c3fb27SDimitry Andric 7506c3fb27SDimitry Andric Members = 0; 7606c3fb27SDimitry Andric 7706c3fb27SDimitry Andric // If this is a C++ record, check the properties of the record such as 7806c3fb27SDimitry Andric // bases and ABI specific restrictions 7906c3fb27SDimitry Andric if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) { 8006c3fb27SDimitry Andric if (!getCXXABI().isPermittedToBeHomogeneousAggregate(CXXRD)) 8106c3fb27SDimitry Andric return false; 8206c3fb27SDimitry Andric 8306c3fb27SDimitry Andric for (const auto &I : CXXRD->bases()) { 8406c3fb27SDimitry Andric // Ignore empty records. 8506c3fb27SDimitry Andric if (isEmptyRecord(getContext(), I.getType(), true)) 8606c3fb27SDimitry Andric continue; 8706c3fb27SDimitry Andric 8806c3fb27SDimitry Andric uint64_t FldMembers; 8906c3fb27SDimitry Andric if (!isHomogeneousAggregate(I.getType(), Base, FldMembers)) 9006c3fb27SDimitry Andric return false; 9106c3fb27SDimitry Andric 9206c3fb27SDimitry Andric Members += FldMembers; 9306c3fb27SDimitry Andric } 9406c3fb27SDimitry Andric } 9506c3fb27SDimitry Andric 9606c3fb27SDimitry Andric for (const auto *FD : RD->fields()) { 9706c3fb27SDimitry Andric // Ignore (non-zero arrays of) empty records. 9806c3fb27SDimitry Andric QualType FT = FD->getType(); 9906c3fb27SDimitry Andric while (const ConstantArrayType *AT = 10006c3fb27SDimitry Andric getContext().getAsConstantArrayType(FT)) { 101*0fca6ea1SDimitry Andric if (AT->isZeroSize()) 10206c3fb27SDimitry Andric return false; 10306c3fb27SDimitry Andric FT = AT->getElementType(); 10406c3fb27SDimitry Andric } 10506c3fb27SDimitry Andric if (isEmptyRecord(getContext(), FT, true)) 10606c3fb27SDimitry Andric continue; 10706c3fb27SDimitry Andric 10806c3fb27SDimitry Andric if (isZeroLengthBitfieldPermittedInHomogeneousAggregate() && 10906c3fb27SDimitry Andric FD->isZeroLengthBitField(getContext())) 11006c3fb27SDimitry Andric continue; 11106c3fb27SDimitry Andric 11206c3fb27SDimitry Andric uint64_t FldMembers; 11306c3fb27SDimitry Andric if (!isHomogeneousAggregate(FD->getType(), Base, FldMembers)) 11406c3fb27SDimitry Andric return false; 11506c3fb27SDimitry Andric 11606c3fb27SDimitry Andric Members = (RD->isUnion() ? 11706c3fb27SDimitry Andric std::max(Members, FldMembers) : Members + FldMembers); 11806c3fb27SDimitry Andric } 11906c3fb27SDimitry Andric 12006c3fb27SDimitry Andric if (!Base) 12106c3fb27SDimitry Andric return false; 12206c3fb27SDimitry Andric 12306c3fb27SDimitry Andric // Ensure there is no padding. 12406c3fb27SDimitry Andric if (getContext().getTypeSize(Base) * Members != 12506c3fb27SDimitry Andric getContext().getTypeSize(Ty)) 12606c3fb27SDimitry Andric return false; 12706c3fb27SDimitry Andric } else { 12806c3fb27SDimitry Andric Members = 1; 12906c3fb27SDimitry Andric if (const ComplexType *CT = Ty->getAs<ComplexType>()) { 13006c3fb27SDimitry Andric Members = 2; 13106c3fb27SDimitry Andric Ty = CT->getElementType(); 13206c3fb27SDimitry Andric } 13306c3fb27SDimitry Andric 13406c3fb27SDimitry Andric // Most ABIs only support float, double, and some vector type widths. 13506c3fb27SDimitry Andric if (!isHomogeneousAggregateBaseType(Ty)) 13606c3fb27SDimitry Andric return false; 13706c3fb27SDimitry Andric 13806c3fb27SDimitry Andric // The base type must be the same for all members. Types that 13906c3fb27SDimitry Andric // agree in both total size and mode (float vs. vector) are 14006c3fb27SDimitry Andric // treated as being equivalent here. 14106c3fb27SDimitry Andric const Type *TyPtr = Ty.getTypePtr(); 14206c3fb27SDimitry Andric if (!Base) { 14306c3fb27SDimitry Andric Base = TyPtr; 14406c3fb27SDimitry Andric // If it's a non-power-of-2 vector, its size is already a power-of-2, 14506c3fb27SDimitry Andric // so make sure to widen it explicitly. 14606c3fb27SDimitry Andric if (const VectorType *VT = Base->getAs<VectorType>()) { 14706c3fb27SDimitry Andric QualType EltTy = VT->getElementType(); 14806c3fb27SDimitry Andric unsigned NumElements = 14906c3fb27SDimitry Andric getContext().getTypeSize(VT) / getContext().getTypeSize(EltTy); 15006c3fb27SDimitry Andric Base = getContext() 15106c3fb27SDimitry Andric .getVectorType(EltTy, NumElements, VT->getVectorKind()) 15206c3fb27SDimitry Andric .getTypePtr(); 15306c3fb27SDimitry Andric } 15406c3fb27SDimitry Andric } 15506c3fb27SDimitry Andric 15606c3fb27SDimitry Andric if (Base->isVectorType() != TyPtr->isVectorType() || 15706c3fb27SDimitry Andric getContext().getTypeSize(Base) != getContext().getTypeSize(TyPtr)) 15806c3fb27SDimitry Andric return false; 15906c3fb27SDimitry Andric } 16006c3fb27SDimitry Andric return Members > 0 && isHomogeneousAggregateSmallEnough(Base, Members); 16106c3fb27SDimitry Andric } 16206c3fb27SDimitry Andric 16306c3fb27SDimitry Andric bool ABIInfo::isPromotableIntegerTypeForABI(QualType Ty) const { 16406c3fb27SDimitry Andric if (getContext().isPromotableIntegerType(Ty)) 16506c3fb27SDimitry Andric return true; 16606c3fb27SDimitry Andric 16706c3fb27SDimitry Andric if (const auto *EIT = Ty->getAs<BitIntType>()) 16806c3fb27SDimitry Andric if (EIT->getNumBits() < getContext().getTypeSize(getContext().IntTy)) 16906c3fb27SDimitry Andric return true; 17006c3fb27SDimitry Andric 17106c3fb27SDimitry Andric return false; 17206c3fb27SDimitry Andric } 17306c3fb27SDimitry Andric 17406c3fb27SDimitry Andric ABIArgInfo ABIInfo::getNaturalAlignIndirect(QualType Ty, bool ByVal, 17506c3fb27SDimitry Andric bool Realign, 17606c3fb27SDimitry Andric llvm::Type *Padding) const { 17706c3fb27SDimitry Andric return ABIArgInfo::getIndirect(getContext().getTypeAlignInChars(Ty), ByVal, 17806c3fb27SDimitry Andric Realign, Padding); 17906c3fb27SDimitry Andric } 18006c3fb27SDimitry Andric 18106c3fb27SDimitry Andric ABIArgInfo ABIInfo::getNaturalAlignIndirectInReg(QualType Ty, 18206c3fb27SDimitry Andric bool Realign) const { 18306c3fb27SDimitry Andric return ABIArgInfo::getIndirectInReg(getContext().getTypeAlignInChars(Ty), 18406c3fb27SDimitry Andric /*ByVal*/ false, Realign); 18506c3fb27SDimitry Andric } 18606c3fb27SDimitry Andric 187*0fca6ea1SDimitry Andric void ABIInfo::appendAttributeMangling(TargetAttr *Attr, 188*0fca6ea1SDimitry Andric raw_ostream &Out) const { 189*0fca6ea1SDimitry Andric if (Attr->isDefaultVersion()) 190*0fca6ea1SDimitry Andric return; 191*0fca6ea1SDimitry Andric appendAttributeMangling(Attr->getFeaturesStr(), Out); 192*0fca6ea1SDimitry Andric } 193*0fca6ea1SDimitry Andric 194*0fca6ea1SDimitry Andric void ABIInfo::appendAttributeMangling(TargetVersionAttr *Attr, 195*0fca6ea1SDimitry Andric raw_ostream &Out) const { 196*0fca6ea1SDimitry Andric appendAttributeMangling(Attr->getNamesStr(), Out); 197*0fca6ea1SDimitry Andric } 198*0fca6ea1SDimitry Andric 199*0fca6ea1SDimitry Andric void ABIInfo::appendAttributeMangling(TargetClonesAttr *Attr, unsigned Index, 200*0fca6ea1SDimitry Andric raw_ostream &Out) const { 201*0fca6ea1SDimitry Andric appendAttributeMangling(Attr->getFeatureStr(Index), Out); 202*0fca6ea1SDimitry Andric Out << '.' << Attr->getMangledIndex(Index); 203*0fca6ea1SDimitry Andric } 204*0fca6ea1SDimitry Andric 205*0fca6ea1SDimitry Andric void ABIInfo::appendAttributeMangling(StringRef AttrStr, 206*0fca6ea1SDimitry Andric raw_ostream &Out) const { 207*0fca6ea1SDimitry Andric if (AttrStr == "default") { 208*0fca6ea1SDimitry Andric Out << ".default"; 209*0fca6ea1SDimitry Andric return; 210*0fca6ea1SDimitry Andric } 211*0fca6ea1SDimitry Andric 212*0fca6ea1SDimitry Andric Out << '.'; 213*0fca6ea1SDimitry Andric const TargetInfo &TI = CGT.getTarget(); 214*0fca6ea1SDimitry Andric ParsedTargetAttr Info = TI.parseTargetAttr(AttrStr); 215*0fca6ea1SDimitry Andric 216*0fca6ea1SDimitry Andric llvm::sort(Info.Features, [&TI](StringRef LHS, StringRef RHS) { 217*0fca6ea1SDimitry Andric // Multiversioning doesn't allow "no-${feature}", so we can 218*0fca6ea1SDimitry Andric // only have "+" prefixes here. 219*0fca6ea1SDimitry Andric assert(LHS.starts_with("+") && RHS.starts_with("+") && 220*0fca6ea1SDimitry Andric "Features should always have a prefix."); 221*0fca6ea1SDimitry Andric return TI.multiVersionSortPriority(LHS.substr(1)) > 222*0fca6ea1SDimitry Andric TI.multiVersionSortPriority(RHS.substr(1)); 223*0fca6ea1SDimitry Andric }); 224*0fca6ea1SDimitry Andric 225*0fca6ea1SDimitry Andric bool IsFirst = true; 226*0fca6ea1SDimitry Andric if (!Info.CPU.empty()) { 227*0fca6ea1SDimitry Andric IsFirst = false; 228*0fca6ea1SDimitry Andric Out << "arch_" << Info.CPU; 229*0fca6ea1SDimitry Andric } 230*0fca6ea1SDimitry Andric 231*0fca6ea1SDimitry Andric for (StringRef Feat : Info.Features) { 232*0fca6ea1SDimitry Andric if (!IsFirst) 233*0fca6ea1SDimitry Andric Out << '_'; 234*0fca6ea1SDimitry Andric IsFirst = false; 235*0fca6ea1SDimitry Andric Out << Feat.substr(1); 236*0fca6ea1SDimitry Andric } 237*0fca6ea1SDimitry Andric } 238*0fca6ea1SDimitry Andric 23906c3fb27SDimitry Andric // Pin the vtable to this file. 24006c3fb27SDimitry Andric SwiftABIInfo::~SwiftABIInfo() = default; 24106c3fb27SDimitry Andric 24206c3fb27SDimitry Andric /// Does the given lowering require more than the given number of 24306c3fb27SDimitry Andric /// registers when expanded? 24406c3fb27SDimitry Andric /// 24506c3fb27SDimitry Andric /// This is intended to be the basis of a reasonable basic implementation 24606c3fb27SDimitry Andric /// of should{Pass,Return}Indirectly. 24706c3fb27SDimitry Andric /// 24806c3fb27SDimitry Andric /// For most targets, a limit of four total registers is reasonable; this 24906c3fb27SDimitry Andric /// limits the amount of code required in order to move around the value 25006c3fb27SDimitry Andric /// in case it wasn't produced immediately prior to the call by the caller 25106c3fb27SDimitry Andric /// (or wasn't produced in exactly the right registers) or isn't used 25206c3fb27SDimitry Andric /// immediately within the callee. But some targets may need to further 25306c3fb27SDimitry Andric /// limit the register count due to an inability to support that many 25406c3fb27SDimitry Andric /// return registers. 25506c3fb27SDimitry Andric bool SwiftABIInfo::occupiesMoreThan(ArrayRef<llvm::Type *> scalarTypes, 25606c3fb27SDimitry Andric unsigned maxAllRegisters) const { 25706c3fb27SDimitry Andric unsigned intCount = 0, fpCount = 0; 25806c3fb27SDimitry Andric for (llvm::Type *type : scalarTypes) { 25906c3fb27SDimitry Andric if (type->isPointerTy()) { 26006c3fb27SDimitry Andric intCount++; 26106c3fb27SDimitry Andric } else if (auto intTy = dyn_cast<llvm::IntegerType>(type)) { 26206c3fb27SDimitry Andric auto ptrWidth = CGT.getTarget().getPointerWidth(LangAS::Default); 26306c3fb27SDimitry Andric intCount += (intTy->getBitWidth() + ptrWidth - 1) / ptrWidth; 26406c3fb27SDimitry Andric } else { 26506c3fb27SDimitry Andric assert(type->isVectorTy() || type->isFloatingPointTy()); 26606c3fb27SDimitry Andric fpCount++; 26706c3fb27SDimitry Andric } 26806c3fb27SDimitry Andric } 26906c3fb27SDimitry Andric 27006c3fb27SDimitry Andric return (intCount + fpCount > maxAllRegisters); 27106c3fb27SDimitry Andric } 27206c3fb27SDimitry Andric 27306c3fb27SDimitry Andric bool SwiftABIInfo::shouldPassIndirectly(ArrayRef<llvm::Type *> ComponentTys, 27406c3fb27SDimitry Andric bool AsReturnValue) const { 27506c3fb27SDimitry Andric return occupiesMoreThan(ComponentTys, /*total=*/4); 27606c3fb27SDimitry Andric } 27706c3fb27SDimitry Andric 27806c3fb27SDimitry Andric bool SwiftABIInfo::isLegalVectorType(CharUnits VectorSize, llvm::Type *EltTy, 27906c3fb27SDimitry Andric unsigned NumElts) const { 28006c3fb27SDimitry Andric // The default implementation of this assumes that the target guarantees 28106c3fb27SDimitry Andric // 128-bit SIMD support but nothing more. 28206c3fb27SDimitry Andric return (VectorSize.getQuantity() > 8 && VectorSize.getQuantity() <= 16); 28306c3fb27SDimitry Andric } 284