1992cb984SSergei Barannikov //===- ABIInfo.cpp --------------------------------------------------------===// 2992cb984SSergei Barannikov // 3992cb984SSergei Barannikov // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4992cb984SSergei Barannikov // See https://llvm.org/LICENSE.txt for license information. 5992cb984SSergei Barannikov // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6992cb984SSergei Barannikov // 7992cb984SSergei Barannikov //===----------------------------------------------------------------------===// 8992cb984SSergei Barannikov 9992cb984SSergei Barannikov #include "ABIInfo.h" 10992cb984SSergei Barannikov #include "ABIInfoImpl.h" 11992cb984SSergei Barannikov 12992cb984SSergei Barannikov using namespace clang; 13992cb984SSergei Barannikov using namespace clang::CodeGen; 14992cb984SSergei Barannikov 15992cb984SSergei Barannikov // Pin the vtable to this file. 16992cb984SSergei Barannikov ABIInfo::~ABIInfo() = default; 17992cb984SSergei Barannikov 18992cb984SSergei Barannikov CGCXXABI &ABIInfo::getCXXABI() const { return CGT.getCXXABI(); } 19992cb984SSergei Barannikov 20992cb984SSergei Barannikov ASTContext &ABIInfo::getContext() const { return CGT.getContext(); } 21992cb984SSergei Barannikov 22992cb984SSergei Barannikov llvm::LLVMContext &ABIInfo::getVMContext() const { 23992cb984SSergei Barannikov return CGT.getLLVMContext(); 24992cb984SSergei Barannikov } 25992cb984SSergei Barannikov 26992cb984SSergei Barannikov const llvm::DataLayout &ABIInfo::getDataLayout() const { 27992cb984SSergei Barannikov return CGT.getDataLayout(); 28992cb984SSergei Barannikov } 29992cb984SSergei Barannikov 30992cb984SSergei Barannikov const TargetInfo &ABIInfo::getTarget() const { return CGT.getTarget(); } 31992cb984SSergei Barannikov 32992cb984SSergei Barannikov const CodeGenOptions &ABIInfo::getCodeGenOpts() const { 33992cb984SSergei Barannikov return CGT.getCodeGenOpts(); 34992cb984SSergei Barannikov } 35992cb984SSergei Barannikov 36992cb984SSergei Barannikov bool ABIInfo::isAndroid() const { return getTarget().getTriple().isAndroid(); } 37992cb984SSergei Barannikov 38992cb984SSergei Barannikov bool ABIInfo::isOHOSFamily() const { 39992cb984SSergei Barannikov return getTarget().getTriple().isOHOSFamily(); 40992cb984SSergei Barannikov } 41992cb984SSergei Barannikov 426d973b45SMariya Podchishchaeva RValue ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr, 436d973b45SMariya Podchishchaeva QualType Ty, AggValueSlot Slot) const { 446d973b45SMariya Podchishchaeva return RValue::getIgnored(); 45992cb984SSergei Barannikov } 46992cb984SSergei Barannikov 47992cb984SSergei Barannikov bool ABIInfo::isHomogeneousAggregateBaseType(QualType Ty) const { 48992cb984SSergei Barannikov return false; 49992cb984SSergei Barannikov } 50992cb984SSergei Barannikov 51992cb984SSergei Barannikov bool ABIInfo::isHomogeneousAggregateSmallEnough(const Type *Base, 52992cb984SSergei Barannikov uint64_t Members) const { 53992cb984SSergei Barannikov return false; 54992cb984SSergei Barannikov } 55992cb984SSergei Barannikov 56992cb984SSergei Barannikov bool ABIInfo::isZeroLengthBitfieldPermittedInHomogeneousAggregate() const { 57992cb984SSergei Barannikov // For compatibility with GCC, ignore empty bitfields in C++ mode. 58992cb984SSergei Barannikov return getContext().getLangOpts().CPlusPlus; 59992cb984SSergei Barannikov } 60992cb984SSergei Barannikov 61992cb984SSergei Barannikov bool ABIInfo::isHomogeneousAggregate(QualType Ty, const Type *&Base, 62992cb984SSergei Barannikov uint64_t &Members) const { 63992cb984SSergei Barannikov if (const ConstantArrayType *AT = getContext().getAsConstantArrayType(Ty)) { 6428ddbd4aSChris B uint64_t NElements = AT->getZExtSize(); 65992cb984SSergei Barannikov if (NElements == 0) 66992cb984SSergei Barannikov return false; 67992cb984SSergei Barannikov if (!isHomogeneousAggregate(AT->getElementType(), Base, Members)) 68992cb984SSergei Barannikov return false; 69992cb984SSergei Barannikov Members *= NElements; 70992cb984SSergei Barannikov } else if (const RecordType *RT = Ty->getAs<RecordType>()) { 71992cb984SSergei Barannikov const RecordDecl *RD = RT->getDecl(); 72992cb984SSergei Barannikov if (RD->hasFlexibleArrayMember()) 73992cb984SSergei Barannikov return false; 74992cb984SSergei Barannikov 75992cb984SSergei Barannikov Members = 0; 76992cb984SSergei Barannikov 77992cb984SSergei Barannikov // If this is a C++ record, check the properties of the record such as 78992cb984SSergei Barannikov // bases and ABI specific restrictions 79992cb984SSergei Barannikov if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) { 80992cb984SSergei Barannikov if (!getCXXABI().isPermittedToBeHomogeneousAggregate(CXXRD)) 81992cb984SSergei Barannikov return false; 82992cb984SSergei Barannikov 83992cb984SSergei Barannikov for (const auto &I : CXXRD->bases()) { 84992cb984SSergei Barannikov // Ignore empty records. 85992cb984SSergei Barannikov if (isEmptyRecord(getContext(), I.getType(), true)) 86992cb984SSergei Barannikov continue; 87992cb984SSergei Barannikov 88992cb984SSergei Barannikov uint64_t FldMembers; 89992cb984SSergei Barannikov if (!isHomogeneousAggregate(I.getType(), Base, FldMembers)) 90992cb984SSergei Barannikov return false; 91992cb984SSergei Barannikov 92992cb984SSergei Barannikov Members += FldMembers; 93992cb984SSergei Barannikov } 94992cb984SSergei Barannikov } 95992cb984SSergei Barannikov 96992cb984SSergei Barannikov for (const auto *FD : RD->fields()) { 97992cb984SSergei Barannikov // Ignore (non-zero arrays of) empty records. 98992cb984SSergei Barannikov QualType FT = FD->getType(); 99992cb984SSergei Barannikov while (const ConstantArrayType *AT = 100992cb984SSergei Barannikov getContext().getAsConstantArrayType(FT)) { 10128ddbd4aSChris B if (AT->isZeroSize()) 102992cb984SSergei Barannikov return false; 103992cb984SSergei Barannikov FT = AT->getElementType(); 104992cb984SSergei Barannikov } 105992cb984SSergei Barannikov if (isEmptyRecord(getContext(), FT, true)) 106992cb984SSergei Barannikov continue; 107992cb984SSergei Barannikov 108992cb984SSergei Barannikov if (isZeroLengthBitfieldPermittedInHomogeneousAggregate() && 109cfe26358STimm Baeder FD->isZeroLengthBitField()) 110992cb984SSergei Barannikov continue; 111992cb984SSergei Barannikov 112992cb984SSergei Barannikov uint64_t FldMembers; 113992cb984SSergei Barannikov if (!isHomogeneousAggregate(FD->getType(), Base, FldMembers)) 114992cb984SSergei Barannikov return false; 115992cb984SSergei Barannikov 116992cb984SSergei Barannikov Members = (RD->isUnion() ? 117992cb984SSergei Barannikov std::max(Members, FldMembers) : Members + FldMembers); 118992cb984SSergei Barannikov } 119992cb984SSergei Barannikov 120992cb984SSergei Barannikov if (!Base) 121992cb984SSergei Barannikov return false; 122992cb984SSergei Barannikov 123992cb984SSergei Barannikov // Ensure there is no padding. 124992cb984SSergei Barannikov if (getContext().getTypeSize(Base) * Members != 125992cb984SSergei Barannikov getContext().getTypeSize(Ty)) 126992cb984SSergei Barannikov return false; 127992cb984SSergei Barannikov } else { 128992cb984SSergei Barannikov Members = 1; 129992cb984SSergei Barannikov if (const ComplexType *CT = Ty->getAs<ComplexType>()) { 130992cb984SSergei Barannikov Members = 2; 131992cb984SSergei Barannikov Ty = CT->getElementType(); 132992cb984SSergei Barannikov } 133992cb984SSergei Barannikov 134992cb984SSergei Barannikov // Most ABIs only support float, double, and some vector type widths. 135992cb984SSergei Barannikov if (!isHomogeneousAggregateBaseType(Ty)) 136992cb984SSergei Barannikov return false; 137992cb984SSergei Barannikov 138992cb984SSergei Barannikov // The base type must be the same for all members. Types that 139992cb984SSergei Barannikov // agree in both total size and mode (float vs. vector) are 140992cb984SSergei Barannikov // treated as being equivalent here. 141992cb984SSergei Barannikov const Type *TyPtr = Ty.getTypePtr(); 142992cb984SSergei Barannikov if (!Base) { 143992cb984SSergei Barannikov Base = TyPtr; 144992cb984SSergei Barannikov // If it's a non-power-of-2 vector, its size is already a power-of-2, 145992cb984SSergei Barannikov // so make sure to widen it explicitly. 146992cb984SSergei Barannikov if (const VectorType *VT = Base->getAs<VectorType>()) { 147992cb984SSergei Barannikov QualType EltTy = VT->getElementType(); 148992cb984SSergei Barannikov unsigned NumElements = 149992cb984SSergei Barannikov getContext().getTypeSize(VT) / getContext().getTypeSize(EltTy); 150992cb984SSergei Barannikov Base = getContext() 151992cb984SSergei Barannikov .getVectorType(EltTy, NumElements, VT->getVectorKind()) 152992cb984SSergei Barannikov .getTypePtr(); 153992cb984SSergei Barannikov } 154992cb984SSergei Barannikov } 155992cb984SSergei Barannikov 156992cb984SSergei Barannikov if (Base->isVectorType() != TyPtr->isVectorType() || 157992cb984SSergei Barannikov getContext().getTypeSize(Base) != getContext().getTypeSize(TyPtr)) 158992cb984SSergei Barannikov return false; 159992cb984SSergei Barannikov } 160992cb984SSergei Barannikov return Members > 0 && isHomogeneousAggregateSmallEnough(Base, Members); 161992cb984SSergei Barannikov } 162992cb984SSergei Barannikov 163992cb984SSergei Barannikov bool ABIInfo::isPromotableIntegerTypeForABI(QualType Ty) const { 164992cb984SSergei Barannikov if (getContext().isPromotableIntegerType(Ty)) 165992cb984SSergei Barannikov return true; 166992cb984SSergei Barannikov 167992cb984SSergei Barannikov if (const auto *EIT = Ty->getAs<BitIntType>()) 168992cb984SSergei Barannikov if (EIT->getNumBits() < getContext().getTypeSize(getContext().IntTy)) 169992cb984SSergei Barannikov return true; 170992cb984SSergei Barannikov 171992cb984SSergei Barannikov return false; 172992cb984SSergei Barannikov } 173992cb984SSergei Barannikov 174992cb984SSergei Barannikov ABIArgInfo ABIInfo::getNaturalAlignIndirect(QualType Ty, bool ByVal, 175992cb984SSergei Barannikov bool Realign, 176992cb984SSergei Barannikov llvm::Type *Padding) const { 177992cb984SSergei Barannikov return ABIArgInfo::getIndirect(getContext().getTypeAlignInChars(Ty), ByVal, 178992cb984SSergei Barannikov Realign, Padding); 179992cb984SSergei Barannikov } 180992cb984SSergei Barannikov 181992cb984SSergei Barannikov ABIArgInfo ABIInfo::getNaturalAlignIndirectInReg(QualType Ty, 182992cb984SSergei Barannikov bool Realign) const { 183992cb984SSergei Barannikov return ABIArgInfo::getIndirectInReg(getContext().getTypeAlignInChars(Ty), 184992cb984SSergei Barannikov /*ByVal*/ false, Realign); 185992cb984SSergei Barannikov } 186992cb984SSergei Barannikov 187b42b7c8aSAlexandros Lamprineas void ABIInfo::appendAttributeMangling(TargetAttr *Attr, 188b42b7c8aSAlexandros Lamprineas raw_ostream &Out) const { 189b42b7c8aSAlexandros Lamprineas if (Attr->isDefaultVersion()) 190b42b7c8aSAlexandros Lamprineas return; 191b42b7c8aSAlexandros Lamprineas appendAttributeMangling(Attr->getFeaturesStr(), Out); 192b42b7c8aSAlexandros Lamprineas } 193b42b7c8aSAlexandros Lamprineas 194b42b7c8aSAlexandros Lamprineas void ABIInfo::appendAttributeMangling(TargetVersionAttr *Attr, 195b42b7c8aSAlexandros Lamprineas raw_ostream &Out) const { 196b42b7c8aSAlexandros Lamprineas appendAttributeMangling(Attr->getNamesStr(), Out); 197b42b7c8aSAlexandros Lamprineas } 198b42b7c8aSAlexandros Lamprineas 199b42b7c8aSAlexandros Lamprineas void ABIInfo::appendAttributeMangling(TargetClonesAttr *Attr, unsigned Index, 200b42b7c8aSAlexandros Lamprineas raw_ostream &Out) const { 201b42b7c8aSAlexandros Lamprineas appendAttributeMangling(Attr->getFeatureStr(Index), Out); 202b42b7c8aSAlexandros Lamprineas Out << '.' << Attr->getMangledIndex(Index); 203b42b7c8aSAlexandros Lamprineas } 204b42b7c8aSAlexandros Lamprineas 205b42b7c8aSAlexandros Lamprineas void ABIInfo::appendAttributeMangling(StringRef AttrStr, 206b42b7c8aSAlexandros Lamprineas raw_ostream &Out) const { 207b42b7c8aSAlexandros Lamprineas if (AttrStr == "default") { 208b42b7c8aSAlexandros Lamprineas Out << ".default"; 209b42b7c8aSAlexandros Lamprineas return; 210b42b7c8aSAlexandros Lamprineas } 211b42b7c8aSAlexandros Lamprineas 212b42b7c8aSAlexandros Lamprineas Out << '.'; 213b42b7c8aSAlexandros Lamprineas const TargetInfo &TI = CGT.getTarget(); 214b42b7c8aSAlexandros Lamprineas ParsedTargetAttr Info = TI.parseTargetAttr(AttrStr); 215b42b7c8aSAlexandros Lamprineas 216b42b7c8aSAlexandros Lamprineas llvm::sort(Info.Features, [&TI](StringRef LHS, StringRef RHS) { 217b42b7c8aSAlexandros Lamprineas // Multiversioning doesn't allow "no-${feature}", so we can 218b42b7c8aSAlexandros Lamprineas // only have "+" prefixes here. 219b42b7c8aSAlexandros Lamprineas assert(LHS.starts_with("+") && RHS.starts_with("+") && 220b42b7c8aSAlexandros Lamprineas "Features should always have a prefix."); 22188c2af80SAlexandros Lamprineas return TI.getFMVPriority({LHS.substr(1)}) > 22288c2af80SAlexandros Lamprineas TI.getFMVPriority({RHS.substr(1)}); 223b42b7c8aSAlexandros Lamprineas }); 224b42b7c8aSAlexandros Lamprineas 225b42b7c8aSAlexandros Lamprineas bool IsFirst = true; 226b42b7c8aSAlexandros Lamprineas if (!Info.CPU.empty()) { 227b42b7c8aSAlexandros Lamprineas IsFirst = false; 228b42b7c8aSAlexandros Lamprineas Out << "arch_" << Info.CPU; 229b42b7c8aSAlexandros Lamprineas } 230b42b7c8aSAlexandros Lamprineas 231b42b7c8aSAlexandros Lamprineas for (StringRef Feat : Info.Features) { 232b42b7c8aSAlexandros Lamprineas if (!IsFirst) 233b42b7c8aSAlexandros Lamprineas Out << '_'; 234b42b7c8aSAlexandros Lamprineas IsFirst = false; 235b42b7c8aSAlexandros Lamprineas Out << Feat.substr(1); 236b42b7c8aSAlexandros Lamprineas } 237b42b7c8aSAlexandros Lamprineas } 238b42b7c8aSAlexandros Lamprineas 239*03744d2aSShilei Tian llvm::FixedVectorType * 240*03744d2aSShilei Tian ABIInfo::getOptimalVectorMemoryType(llvm::FixedVectorType *T, 241*03744d2aSShilei Tian const LangOptions &Opt) const { 242*03744d2aSShilei Tian if (T->getNumElements() == 3 && !Opt.PreserveVec3Type) 243*03744d2aSShilei Tian return llvm::FixedVectorType::get(T->getElementType(), 4); 244*03744d2aSShilei Tian return T; 245*03744d2aSShilei Tian } 246*03744d2aSShilei Tian 247992cb984SSergei Barannikov // Pin the vtable to this file. 248992cb984SSergei Barannikov SwiftABIInfo::~SwiftABIInfo() = default; 249992cb984SSergei Barannikov 250992cb984SSergei Barannikov /// Does the given lowering require more than the given number of 251992cb984SSergei Barannikov /// registers when expanded? 252992cb984SSergei Barannikov /// 253992cb984SSergei Barannikov /// This is intended to be the basis of a reasonable basic implementation 254992cb984SSergei Barannikov /// of should{Pass,Return}Indirectly. 255992cb984SSergei Barannikov /// 256992cb984SSergei Barannikov /// For most targets, a limit of four total registers is reasonable; this 257992cb984SSergei Barannikov /// limits the amount of code required in order to move around the value 258992cb984SSergei Barannikov /// in case it wasn't produced immediately prior to the call by the caller 259992cb984SSergei Barannikov /// (or wasn't produced in exactly the right registers) or isn't used 260992cb984SSergei Barannikov /// immediately within the callee. But some targets may need to further 261992cb984SSergei Barannikov /// limit the register count due to an inability to support that many 262992cb984SSergei Barannikov /// return registers. 263992cb984SSergei Barannikov bool SwiftABIInfo::occupiesMoreThan(ArrayRef<llvm::Type *> scalarTypes, 264992cb984SSergei Barannikov unsigned maxAllRegisters) const { 265992cb984SSergei Barannikov unsigned intCount = 0, fpCount = 0; 266992cb984SSergei Barannikov for (llvm::Type *type : scalarTypes) { 267992cb984SSergei Barannikov if (type->isPointerTy()) { 268992cb984SSergei Barannikov intCount++; 269992cb984SSergei Barannikov } else if (auto intTy = dyn_cast<llvm::IntegerType>(type)) { 270992cb984SSergei Barannikov auto ptrWidth = CGT.getTarget().getPointerWidth(LangAS::Default); 271992cb984SSergei Barannikov intCount += (intTy->getBitWidth() + ptrWidth - 1) / ptrWidth; 272992cb984SSergei Barannikov } else { 273992cb984SSergei Barannikov assert(type->isVectorTy() || type->isFloatingPointTy()); 274992cb984SSergei Barannikov fpCount++; 275992cb984SSergei Barannikov } 276992cb984SSergei Barannikov } 277992cb984SSergei Barannikov 278992cb984SSergei Barannikov return (intCount + fpCount > maxAllRegisters); 279992cb984SSergei Barannikov } 280992cb984SSergei Barannikov 281992cb984SSergei Barannikov bool SwiftABIInfo::shouldPassIndirectly(ArrayRef<llvm::Type *> ComponentTys, 282992cb984SSergei Barannikov bool AsReturnValue) const { 283992cb984SSergei Barannikov return occupiesMoreThan(ComponentTys, /*total=*/4); 284992cb984SSergei Barannikov } 285992cb984SSergei Barannikov 286992cb984SSergei Barannikov bool SwiftABIInfo::isLegalVectorType(CharUnits VectorSize, llvm::Type *EltTy, 287992cb984SSergei Barannikov unsigned NumElts) const { 288992cb984SSergei Barannikov // The default implementation of this assumes that the target guarantees 289992cb984SSergei Barannikov // 128-bit SIMD support but nothing more. 290992cb984SSergei Barannikov return (VectorSize.getQuantity() > 8 && VectorSize.getQuantity() <= 16); 291992cb984SSergei Barannikov } 292