brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.1 KiB · 1600589 Raw
304 lines · cpp
1//===- ABIInfo.cpp --------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "ABIInfo.h"10#include "ABIInfoImpl.h"11 12using namespace clang;13using namespace clang::CodeGen;14 15// Pin the vtable to this file.16ABIInfo::~ABIInfo() = default;17 18CGCXXABI &ABIInfo::getCXXABI() const { return CGT.getCXXABI(); }19 20ASTContext &ABIInfo::getContext() const { return CGT.getContext(); }21 22llvm::LLVMContext &ABIInfo::getVMContext() const {23  return CGT.getLLVMContext();24}25 26const llvm::DataLayout &ABIInfo::getDataLayout() const {27  return CGT.getDataLayout();28}29 30const TargetInfo &ABIInfo::getTarget() const { return CGT.getTarget(); }31 32const CodeGenOptions &ABIInfo::getCodeGenOpts() const {33  return CGT.getCodeGenOpts();34}35 36bool ABIInfo::isAndroid() const { return getTarget().getTriple().isAndroid(); }37 38bool ABIInfo::isOHOSFamily() const {39  return getTarget().getTriple().isOHOSFamily();40}41 42RValue ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr,43                            QualType Ty, AggValueSlot Slot) const {44  return RValue::getIgnored();45}46 47bool ABIInfo::isHomogeneousAggregateBaseType(QualType Ty) const {48  return false;49}50 51bool ABIInfo::isHomogeneousAggregateSmallEnough(const Type *Base,52                                                uint64_t Members) const {53  return false;54}55 56bool ABIInfo::isZeroLengthBitfieldPermittedInHomogeneousAggregate() const {57  // For compatibility with GCC, ignore empty bitfields in C++ mode.58  return getContext().getLangOpts().CPlusPlus;59}60 61bool ABIInfo::isHomogeneousAggregate(QualType Ty, const Type *&Base,62                                     uint64_t &Members) const {63  if (const ConstantArrayType *AT = getContext().getAsConstantArrayType(Ty)) {64    uint64_t NElements = AT->getZExtSize();65    if (NElements == 0)66      return false;67    if (!isHomogeneousAggregate(AT->getElementType(), Base, Members))68      return false;69    Members *= NElements;70  } else if (const auto *RD = Ty->getAsRecordDecl()) {71    if (RD->hasFlexibleArrayMember())72      return false;73 74    Members = 0;75 76    // If this is a C++ record, check the properties of the record such as77    // bases and ABI specific restrictions78    if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {79      if (!getCXXABI().isPermittedToBeHomogeneousAggregate(CXXRD))80        return false;81 82      for (const auto &I : CXXRD->bases()) {83        // Ignore empty records.84        if (isEmptyRecord(getContext(), I.getType(), true))85          continue;86 87        uint64_t FldMembers;88        if (!isHomogeneousAggregate(I.getType(), Base, FldMembers))89          return false;90 91        Members += FldMembers;92      }93    }94 95    for (const auto *FD : RD->fields()) {96      // Ignore (non-zero arrays of) empty records.97      QualType FT = FD->getType();98      while (const ConstantArrayType *AT =99             getContext().getAsConstantArrayType(FT)) {100        if (AT->isZeroSize())101          return false;102        FT = AT->getElementType();103      }104      if (isEmptyRecord(getContext(), FT, true))105        continue;106 107      if (isZeroLengthBitfieldPermittedInHomogeneousAggregate() &&108          FD->isZeroLengthBitField())109        continue;110 111      uint64_t FldMembers;112      if (!isHomogeneousAggregate(FD->getType(), Base, FldMembers))113        return false;114 115      Members = (RD->isUnion() ?116                 std::max(Members, FldMembers) : Members + FldMembers);117    }118 119    if (!Base)120      return false;121 122    // Ensure there is no padding.123    if (getContext().getTypeSize(Base) * Members !=124        getContext().getTypeSize(Ty))125      return false;126  } else {127    Members = 1;128    if (const ComplexType *CT = Ty->getAs<ComplexType>()) {129      Members = 2;130      Ty = CT->getElementType();131    }132 133    // Most ABIs only support float, double, and some vector type widths.134    if (!isHomogeneousAggregateBaseType(Ty))135      return false;136 137    // 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.140    const Type *TyPtr = Ty.getTypePtr();141    if (!Base) {142      Base = 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.145      if (const VectorType *VT = Base->getAs<VectorType>()) {146        QualType EltTy = VT->getElementType();147        unsigned NumElements =148            getContext().getTypeSize(VT) / getContext().getTypeSize(EltTy);149        Base = getContext()150                   .getVectorType(EltTy, NumElements, VT->getVectorKind())151                   .getTypePtr();152      }153    }154 155    if (Base->isVectorType() != TyPtr->isVectorType() ||156        getContext().getTypeSize(Base) != getContext().getTypeSize(TyPtr))157      return false;158  }159  return Members > 0 && isHomogeneousAggregateSmallEnough(Base, Members);160}161 162bool ABIInfo::isPromotableIntegerTypeForABI(QualType Ty) const {163  if (getContext().isPromotableIntegerType(Ty))164    return true;165 166  if (const auto *EIT = Ty->getAs<BitIntType>())167    if (EIT->getNumBits() < getContext().getTypeSize(getContext().IntTy))168      return true;169 170  return false;171}172 173ABIArgInfo ABIInfo::getNaturalAlignIndirect(QualType Ty, unsigned AddrSpace,174                                            bool ByVal, bool Realign,175                                            llvm::Type *Padding) const {176  return ABIArgInfo::getIndirect(getContext().getTypeAlignInChars(Ty),177                                 AddrSpace, ByVal, Realign, Padding);178}179 180ABIArgInfo ABIInfo::getNaturalAlignIndirectInReg(QualType Ty,181                                                 bool Realign) const {182  return ABIArgInfo::getIndirectInReg(getContext().getTypeAlignInChars(Ty),183                                      /*ByVal*/ false, Realign);184}185 186void ABIInfo::appendAttributeMangling(TargetAttr *Attr,187                                      raw_ostream &Out) const {188  if (Attr->isDefaultVersion())189    return;190  appendAttributeMangling(Attr->getFeaturesStr(), Out);191}192 193void ABIInfo::appendAttributeMangling(TargetVersionAttr *Attr,194                                      raw_ostream &Out) const {195  appendAttributeMangling(Attr->getNamesStr(), Out);196}197 198void ABIInfo::appendAttributeMangling(TargetClonesAttr *Attr, unsigned Index,199                                      raw_ostream &Out) const {200  appendAttributeMangling(Attr->getFeatureStr(Index), Out);201  Out << '.' << Attr->getMangledIndex(Index);202}203 204void ABIInfo::appendAttributeMangling(StringRef AttrStr,205                                      raw_ostream &Out) const {206  if (AttrStr == "default") {207    Out << ".default";208    return;209  }210 211  Out << '.';212  const TargetInfo &TI = CGT.getTarget();213  ParsedTargetAttr Info = TI.parseTargetAttr(AttrStr);214 215  llvm::sort(Info.Features, [&TI](StringRef LHS, StringRef RHS) {216    // Multiversioning doesn't allow "no-${feature}", so we can217    // only have "+" prefixes here.218    assert(LHS.starts_with("+") && RHS.starts_with("+") &&219           "Features should always have a prefix.");220    return TI.getFMVPriority({LHS.substr(1)})221        .ugt(TI.getFMVPriority({RHS.substr(1)}));222  });223 224  bool IsFirst = true;225  if (!Info.CPU.empty()) {226    IsFirst = false;227    Out << "arch_" << Info.CPU;228  }229 230  for (StringRef Feat : Info.Features) {231    if (!IsFirst)232      Out << '_';233    IsFirst = false;234    Out << Feat.substr(1);235  }236}237 238llvm::FixedVectorType *239ABIInfo::getOptimalVectorMemoryType(llvm::FixedVectorType *T,240                                    const LangOptions &Opt) const {241  if (T->getNumElements() == 3 && !Opt.PreserveVec3Type)242    return llvm::FixedVectorType::get(T->getElementType(), 4);243  return T;244}245 246llvm::Value *ABIInfo::createCoercedLoad(Address SrcAddr, const ABIArgInfo &AI,247                                        CodeGenFunction &CGF) const {248  return nullptr;249}250 251void ABIInfo::createCoercedStore(llvm::Value *Val, Address DstAddr,252                                 const ABIArgInfo &AI, bool DestIsVolatile,253                                 CodeGenFunction &CGF) const {}254 255ABIArgInfo ABIInfo::classifyArgForArm64ECVarArg(QualType Ty) const {256  llvm_unreachable("Only implemented for x86");257}258 259// Pin the vtable to this file.260SwiftABIInfo::~SwiftABIInfo() = default;261 262/// Does the given lowering require more than the given number of263/// registers when expanded?264///265/// This is intended to be the basis of a reasonable basic implementation266/// of should{Pass,Return}Indirectly.267///268/// For most targets, a limit of four total registers is reasonable; this269/// limits the amount of code required in order to move around the value270/// in case it wasn't produced immediately prior to the call by the caller271/// (or wasn't produced in exactly the right registers) or isn't used272/// immediately within the callee.  But some targets may need to further273/// limit the register count due to an inability to support that many274/// return registers.275bool SwiftABIInfo::occupiesMoreThan(ArrayRef<llvm::Type *> scalarTypes,276                                    unsigned maxAllRegisters) const {277  unsigned intCount = 0, fpCount = 0;278  for (llvm::Type *type : scalarTypes) {279    if (type->isPointerTy()) {280      intCount++;281    } else if (auto intTy = dyn_cast<llvm::IntegerType>(type)) {282      auto ptrWidth = CGT.getTarget().getPointerWidth(LangAS::Default);283      intCount += (intTy->getBitWidth() + ptrWidth - 1) / ptrWidth;284    } else {285      assert(type->isVectorTy() || type->isFloatingPointTy());286      fpCount++;287    }288  }289 290  return (intCount + fpCount > maxAllRegisters);291}292 293bool SwiftABIInfo::shouldPassIndirectly(ArrayRef<llvm::Type *> ComponentTys,294                                        bool AsReturnValue) const {295  return occupiesMoreThan(ComponentTys, /*total=*/4);296}297 298bool SwiftABIInfo::isLegalVectorType(CharUnits VectorSize, llvm::Type *EltTy,299                                     unsigned NumElts) const {300  // The default implementation of this assumes that the target guarantees301  // 128-bit SIMD support but nothing more.302  return (VectorSize.getQuantity() > 8 && VectorSize.getQuantity() <= 16);303}304