diff options
Diffstat (limited to 'clang/lib/CodeGen/CodeGenTypes.cpp')
| -rw-r--r-- | clang/lib/CodeGen/CodeGenTypes.cpp | 59 |
1 files changed, 45 insertions, 14 deletions
diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp index 4839e22c4b14..fcce424747f1 100644 --- a/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/clang/lib/CodeGen/CodeGenTypes.cpp @@ -25,6 +25,7 @@ #include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Module.h" + using namespace clang; using namespace CodeGen; @@ -97,6 +98,14 @@ llvm::Type *CodeGenTypes::ConvertTypeForMem(QualType T, bool ForBitField) { llvm::Type *R = ConvertType(T); + // Check for the boolean vector case. + if (T->isExtVectorBoolType()) { + auto *FixedVT = cast<llvm::FixedVectorType>(R); + // Pad to at least one byte. + uint64_t BytePadded = std::max<uint64_t>(FixedVT->getNumElements(), 8); + return llvm::IntegerType::get(FixedVT->getContext(), BytePadded); + } + // If this is a bool type, or a bit-precise integer type in a bitfield // representation, map this integer to the target-specified size. if ((ForBitField && T->isBitIntType()) || @@ -382,9 +391,6 @@ llvm::Type *CodeGenTypes::ConvertFunctionTypeInternal(QualType QFT) { RecordsBeingLaidOut.erase(Ty); - if (SkippedLayout) - TypeCache.clear(); - if (RecordsBeingLaidOut.empty()) while (!DeferredRecords.empty()) ConvertRecordDeclType(DeferredRecords.pop_back_val()); @@ -415,11 +421,27 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) { if (const RecordType *RT = dyn_cast<RecordType>(Ty)) return ConvertRecordDeclType(RT->getDecl()); - // See if type is already cached. - llvm::DenseMap<const Type *, llvm::Type *>::iterator TCI = TypeCache.find(Ty); - // If type is found in map then use it. Otherwise, convert type T. - if (TCI != TypeCache.end()) - return TCI->second; + // The LLVM type we return for a given Clang type may not always be the same, + // most notably when dealing with recursive structs. We mark these potential + // cases with ShouldUseCache below. Builtin types cannot be recursive. + // TODO: when clang uses LLVM opaque pointers we won't be able to represent + // recursive types with LLVM types, making this logic much simpler. + llvm::Type *CachedType = nullptr; + bool ShouldUseCache = + Ty->isBuiltinType() || + (noRecordsBeingLaidOut() && FunctionsBeingProcessed.empty()); + if (ShouldUseCache) { + llvm::DenseMap<const Type *, llvm::Type *>::iterator TCI = + TypeCache.find(Ty); + if (TCI != TypeCache.end()) + CachedType = TCI->second; + // With expensive checks, check that the type we compute matches the + // cached type. +#ifndef EXPENSIVE_CHECKS + if (CachedType) + return CachedType; +#endif + } // If we don't have it in the cache, convert it now. llvm::Type *ResultType = nullptr; @@ -687,9 +709,12 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) { } case Type::ExtVector: case Type::Vector: { - const VectorType *VT = cast<VectorType>(Ty); - ResultType = llvm::FixedVectorType::get(ConvertType(VT->getElementType()), - VT->getNumElements()); + const auto *VT = cast<VectorType>(Ty); + // An ext_vector_type of Bool is really a vector of bits. + llvm::Type *IRElemTy = VT->isExtVectorBoolType() + ? llvm::Type::getInt1Ty(getLLVMContext()) + : ConvertType(VT->getElementType()); + ResultType = llvm::FixedVectorType::get(IRElemTy, VT->getNumElements()); break; } case Type::ConstantMatrix: { @@ -758,8 +783,11 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) { case Type::MemberPointer: { auto *MPTy = cast<MemberPointerType>(Ty); if (!getCXXABI().isMemberPointerConvertible(MPTy)) { - RecordsWithOpaqueMemberPointers.insert(MPTy->getClass()); - ResultType = llvm::StructType::create(getLLVMContext()); + auto *C = MPTy->getClass(); + auto Insertion = RecordsWithOpaqueMemberPointers.insert({C, nullptr}); + if (Insertion.second) + Insertion.first->second = llvm::StructType::create(getLLVMContext()); + ResultType = Insertion.first->second; } else { ResultType = getCXXABI().ConvertMemberPointerType(MPTy); } @@ -796,8 +824,11 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) { } assert(ResultType && "Didn't convert a type?"); + assert((!CachedType || CachedType == ResultType) && + "Cached type doesn't match computed type"); - TypeCache[Ty] = ResultType; + if (ShouldUseCache) + TypeCache[Ty] = ResultType; return ResultType; } |
