Path: blob/main/contrib/llvm-project/clang/lib/CodeGen/ABIInfo.cpp
35233 views
//===- ABIInfo.cpp --------------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "ABIInfo.h"9#include "ABIInfoImpl.h"1011using namespace clang;12using namespace clang::CodeGen;1314// Pin the vtable to this file.15ABIInfo::~ABIInfo() = default;1617CGCXXABI &ABIInfo::getCXXABI() const { return CGT.getCXXABI(); }1819ASTContext &ABIInfo::getContext() const { return CGT.getContext(); }2021llvm::LLVMContext &ABIInfo::getVMContext() const {22return CGT.getLLVMContext();23}2425const llvm::DataLayout &ABIInfo::getDataLayout() const {26return CGT.getDataLayout();27}2829const TargetInfo &ABIInfo::getTarget() const { return CGT.getTarget(); }3031const CodeGenOptions &ABIInfo::getCodeGenOpts() const {32return CGT.getCodeGenOpts();33}3435bool ABIInfo::isAndroid() const { return getTarget().getTriple().isAndroid(); }3637bool ABIInfo::isOHOSFamily() const {38return getTarget().getTriple().isOHOSFamily();39}4041RValue ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr,42QualType Ty, AggValueSlot Slot) const {43return RValue::getIgnored();44}4546bool ABIInfo::isHomogeneousAggregateBaseType(QualType Ty) const {47return false;48}4950bool ABIInfo::isHomogeneousAggregateSmallEnough(const Type *Base,51uint64_t Members) const {52return false;53}5455bool ABIInfo::isZeroLengthBitfieldPermittedInHomogeneousAggregate() const {56// For compatibility with GCC, ignore empty bitfields in C++ mode.57return getContext().getLangOpts().CPlusPlus;58}5960bool ABIInfo::isHomogeneousAggregate(QualType Ty, const Type *&Base,61uint64_t &Members) const {62if (const ConstantArrayType *AT = getContext().getAsConstantArrayType(Ty)) {63uint64_t NElements = AT->getZExtSize();64if (NElements == 0)65return false;66if (!isHomogeneousAggregate(AT->getElementType(), Base, Members))67return false;68Members *= NElements;69} else if (const RecordType *RT = Ty->getAs<RecordType>()) {70const RecordDecl *RD = RT->getDecl();71if (RD->hasFlexibleArrayMember())72return false;7374Members = 0;7576// If this is a C++ record, check the properties of the record such as77// bases and ABI specific restrictions78if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {79if (!getCXXABI().isPermittedToBeHomogeneousAggregate(CXXRD))80return false;8182for (const auto &I : CXXRD->bases()) {83// Ignore empty records.84if (isEmptyRecord(getContext(), I.getType(), true))85continue;8687uint64_t FldMembers;88if (!isHomogeneousAggregate(I.getType(), Base, FldMembers))89return false;9091Members += FldMembers;92}93}9495for (const auto *FD : RD->fields()) {96// Ignore (non-zero arrays of) empty records.97QualType FT = FD->getType();98while (const ConstantArrayType *AT =99getContext().getAsConstantArrayType(FT)) {100if (AT->isZeroSize())101return false;102FT = AT->getElementType();103}104if (isEmptyRecord(getContext(), FT, true))105continue;106107if (isZeroLengthBitfieldPermittedInHomogeneousAggregate() &&108FD->isZeroLengthBitField(getContext()))109continue;110111uint64_t FldMembers;112if (!isHomogeneousAggregate(FD->getType(), Base, FldMembers))113return false;114115Members = (RD->isUnion() ?116std::max(Members, FldMembers) : Members + FldMembers);117}118119if (!Base)120return false;121122// Ensure there is no padding.123if (getContext().getTypeSize(Base) * Members !=124getContext().getTypeSize(Ty))125return false;126} else {127Members = 1;128if (const ComplexType *CT = Ty->getAs<ComplexType>()) {129Members = 2;130Ty = CT->getElementType();131}132133// Most ABIs only support float, double, and some vector type widths.134if (!isHomogeneousAggregateBaseType(Ty))135return false;136137// The base type must be the same for all members. Types that138// agree in both total size and mode (float vs. vector) are139// treated as being equivalent here.140const Type *TyPtr = Ty.getTypePtr();141if (!Base) {142Base = TyPtr;143// If it's a non-power-of-2 vector, its size is already a power-of-2,144// so make sure to widen it explicitly.145if (const VectorType *VT = Base->getAs<VectorType>()) {146QualType EltTy = VT->getElementType();147unsigned NumElements =148getContext().getTypeSize(VT) / getContext().getTypeSize(EltTy);149Base = getContext()150.getVectorType(EltTy, NumElements, VT->getVectorKind())151.getTypePtr();152}153}154155if (Base->isVectorType() != TyPtr->isVectorType() ||156getContext().getTypeSize(Base) != getContext().getTypeSize(TyPtr))157return false;158}159return Members > 0 && isHomogeneousAggregateSmallEnough(Base, Members);160}161162bool ABIInfo::isPromotableIntegerTypeForABI(QualType Ty) const {163if (getContext().isPromotableIntegerType(Ty))164return true;165166if (const auto *EIT = Ty->getAs<BitIntType>())167if (EIT->getNumBits() < getContext().getTypeSize(getContext().IntTy))168return true;169170return false;171}172173ABIArgInfo ABIInfo::getNaturalAlignIndirect(QualType Ty, bool ByVal,174bool Realign,175llvm::Type *Padding) const {176return ABIArgInfo::getIndirect(getContext().getTypeAlignInChars(Ty), ByVal,177Realign, Padding);178}179180ABIArgInfo ABIInfo::getNaturalAlignIndirectInReg(QualType Ty,181bool Realign) const {182return ABIArgInfo::getIndirectInReg(getContext().getTypeAlignInChars(Ty),183/*ByVal*/ false, Realign);184}185186void ABIInfo::appendAttributeMangling(TargetAttr *Attr,187raw_ostream &Out) const {188if (Attr->isDefaultVersion())189return;190appendAttributeMangling(Attr->getFeaturesStr(), Out);191}192193void ABIInfo::appendAttributeMangling(TargetVersionAttr *Attr,194raw_ostream &Out) const {195appendAttributeMangling(Attr->getNamesStr(), Out);196}197198void ABIInfo::appendAttributeMangling(TargetClonesAttr *Attr, unsigned Index,199raw_ostream &Out) const {200appendAttributeMangling(Attr->getFeatureStr(Index), Out);201Out << '.' << Attr->getMangledIndex(Index);202}203204void ABIInfo::appendAttributeMangling(StringRef AttrStr,205raw_ostream &Out) const {206if (AttrStr == "default") {207Out << ".default";208return;209}210211Out << '.';212const TargetInfo &TI = CGT.getTarget();213ParsedTargetAttr Info = TI.parseTargetAttr(AttrStr);214215llvm::sort(Info.Features, [&TI](StringRef LHS, StringRef RHS) {216// Multiversioning doesn't allow "no-${feature}", so we can217// only have "+" prefixes here.218assert(LHS.starts_with("+") && RHS.starts_with("+") &&219"Features should always have a prefix.");220return TI.multiVersionSortPriority(LHS.substr(1)) >221TI.multiVersionSortPriority(RHS.substr(1));222});223224bool IsFirst = true;225if (!Info.CPU.empty()) {226IsFirst = false;227Out << "arch_" << Info.CPU;228}229230for (StringRef Feat : Info.Features) {231if (!IsFirst)232Out << '_';233IsFirst = false;234Out << Feat.substr(1);235}236}237238// Pin the vtable to this file.239SwiftABIInfo::~SwiftABIInfo() = default;240241/// Does the given lowering require more than the given number of242/// registers when expanded?243///244/// This is intended to be the basis of a reasonable basic implementation245/// of should{Pass,Return}Indirectly.246///247/// For most targets, a limit of four total registers is reasonable; this248/// limits the amount of code required in order to move around the value249/// in case it wasn't produced immediately prior to the call by the caller250/// (or wasn't produced in exactly the right registers) or isn't used251/// immediately within the callee. But some targets may need to further252/// limit the register count due to an inability to support that many253/// return registers.254bool SwiftABIInfo::occupiesMoreThan(ArrayRef<llvm::Type *> scalarTypes,255unsigned maxAllRegisters) const {256unsigned intCount = 0, fpCount = 0;257for (llvm::Type *type : scalarTypes) {258if (type->isPointerTy()) {259intCount++;260} else if (auto intTy = dyn_cast<llvm::IntegerType>(type)) {261auto ptrWidth = CGT.getTarget().getPointerWidth(LangAS::Default);262intCount += (intTy->getBitWidth() + ptrWidth - 1) / ptrWidth;263} else {264assert(type->isVectorTy() || type->isFloatingPointTy());265fpCount++;266}267}268269return (intCount + fpCount > maxAllRegisters);270}271272bool SwiftABIInfo::shouldPassIndirectly(ArrayRef<llvm::Type *> ComponentTys,273bool AsReturnValue) const {274return occupiesMoreThan(ComponentTys, /*total=*/4);275}276277bool SwiftABIInfo::isLegalVectorType(CharUnits VectorSize, llvm::Type *EltTy,278unsigned NumElts) const {279// The default implementation of this assumes that the target guarantees280// 128-bit SIMD support but nothing more.281return (VectorSize.getQuantity() > 8 && VectorSize.getQuantity() <= 16);282}283284285