diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 10:51:19 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 10:51:19 +0000 |
commit | eb11fae6d08f479c0799db45860a98af528fa6e7 (patch) | |
tree | 44d492a50c8c1a7eb8e2d17ea3360ec4d066f042 /lib/IR/DataLayout.cpp | |
parent | b8a2042aa938069e862750553db0e4d82d25822c (diff) |
Notes
Diffstat (limited to 'lib/IR/DataLayout.cpp')
-rw-r--r-- | lib/IR/DataLayout.cpp | 84 |
1 files changed, 67 insertions, 17 deletions
diff --git a/lib/IR/DataLayout.cpp b/lib/IR/DataLayout.cpp index f4dddeb30d0b..62c67127276e 100644 --- a/lib/IR/DataLayout.cpp +++ b/lib/IR/DataLayout.cpp @@ -129,13 +129,15 @@ LayoutAlignElem::operator==(const LayoutAlignElem &rhs) const { PointerAlignElem PointerAlignElem::get(uint32_t AddressSpace, unsigned ABIAlign, - unsigned PrefAlign, uint32_t TypeByteWidth) { + unsigned PrefAlign, uint32_t TypeByteWidth, + uint32_t IndexWidth) { assert(ABIAlign <= PrefAlign && "Preferred alignment worse than ABI!"); PointerAlignElem retval; retval.AddressSpace = AddressSpace; retval.ABIAlign = ABIAlign; retval.PrefAlign = PrefAlign; retval.TypeByteWidth = TypeByteWidth; + retval.IndexWidth = IndexWidth; return retval; } @@ -144,7 +146,8 @@ PointerAlignElem::operator==(const PointerAlignElem &rhs) const { return (ABIAlign == rhs.ABIAlign && AddressSpace == rhs.AddressSpace && PrefAlign == rhs.PrefAlign - && TypeByteWidth == rhs.TypeByteWidth); + && TypeByteWidth == rhs.TypeByteWidth + && IndexWidth == rhs.IndexWidth); } //===----------------------------------------------------------------------===// @@ -181,6 +184,7 @@ void DataLayout::reset(StringRef Desc) { BigEndian = false; AllocaAddrSpace = 0; StackNaturalAlign = 0; + ProgramAddrSpace = 0; ManglingMode = MM_None; NonIntegralAddressSpaces.clear(); @@ -189,7 +193,7 @@ void DataLayout::reset(StringRef Desc) { setAlignment((AlignTypeEnum)E.AlignType, E.ABIAlign, E.PrefAlign, E.TypeBitWidth); } - setPointerAlignment(0, 8, 8, 8); + setPointerAlignment(0, 8, 8, 8, 8); parseSpecifier(Desc); } @@ -221,6 +225,13 @@ static unsigned inBytes(unsigned Bits) { return Bits / 8; } +static unsigned getAddrSpace(StringRef R) { + unsigned AddrSpace = getInt(R); + if (!isUInt<24>(AddrSpace)) + report_fatal_error("Invalid address space, must be a 24-bit integer"); + return AddrSpace; +} + void DataLayout::parseSpecifier(StringRef Desc) { StringRepresentation = Desc; while (!Desc.empty()) { @@ -287,6 +298,10 @@ void DataLayout::parseSpecifier(StringRef Desc) { report_fatal_error( "Pointer ABI alignment must be a power of 2"); + // Size of index used in GEP for address calculation. + // The parameter is optional. By default it is equal to size of pointer. + unsigned IndexSize = PointerMemSize; + // Preferred alignment. unsigned PointerPrefAlign = PointerABIAlign; if (!Rest.empty()) { @@ -295,10 +310,17 @@ void DataLayout::parseSpecifier(StringRef Desc) { if (!isPowerOf2_64(PointerPrefAlign)) report_fatal_error( "Pointer preferred alignment must be a power of 2"); - } + // Now read the index. It is the second optional parameter here. + if (!Rest.empty()) { + Split = split(Rest, ':'); + IndexSize = inBytes(getInt(Tok)); + if (!IndexSize) + report_fatal_error("Invalid index size of 0 bytes"); + } + } setPointerAlignment(AddrSpace, PointerABIAlign, PointerPrefAlign, - PointerMemSize); + PointerMemSize, IndexSize); break; } case 'i': @@ -358,10 +380,12 @@ void DataLayout::parseSpecifier(StringRef Desc) { StackNaturalAlign = inBytes(getInt(Tok)); break; } + case 'P': { // Function address space. + ProgramAddrSpace = getAddrSpace(Tok); + break; + } case 'A': { // Default stack/alloca address space. - AllocaAddrSpace = getInt(Tok); - if (!isUInt<24>(AllocaAddrSpace)) - report_fatal_error("Invalid address space, must be a 24bit integer"); + AllocaAddrSpace = getAddrSpace(Tok); break; } case 'm': @@ -408,6 +432,7 @@ bool DataLayout::operator==(const DataLayout &Other) const { bool Ret = BigEndian == Other.BigEndian && AllocaAddrSpace == Other.AllocaAddrSpace && StackNaturalAlign == Other.StackNaturalAlign && + ProgramAddrSpace == Other.ProgramAddrSpace && ManglingMode == Other.ManglingMode && LegalIntWidths == Other.LegalIntWidths && Alignments == Other.Alignments && Pointers == Other.Pointers; @@ -467,8 +492,8 @@ DataLayout::findPointerLowerBound(uint32_t AddressSpace) { } void DataLayout::setPointerAlignment(uint32_t AddrSpace, unsigned ABIAlign, - unsigned PrefAlign, - uint32_t TypeByteWidth) { + unsigned PrefAlign, uint32_t TypeByteWidth, + uint32_t IndexWidth) { if (PrefAlign < ABIAlign) report_fatal_error( "Preferred alignment cannot be less than the ABI alignment"); @@ -476,11 +501,12 @@ void DataLayout::setPointerAlignment(uint32_t AddrSpace, unsigned ABIAlign, PointersTy::iterator I = findPointerLowerBound(AddrSpace); if (I == Pointers.end() || I->AddressSpace != AddrSpace) { Pointers.insert(I, PointerAlignElem::get(AddrSpace, ABIAlign, PrefAlign, - TypeByteWidth)); + TypeByteWidth, IndexWidth)); } else { I->ABIAlign = ABIAlign; I->PrefAlign = PrefAlign; I->TypeByteWidth = TypeByteWidth; + I->IndexWidth = IndexWidth; } } @@ -570,10 +596,8 @@ const StructLayout *DataLayout::getStructLayout(StructType *Ty) const { // Otherwise, create the struct layout. Because it is variable length, we // malloc it, then use placement new. int NumElts = Ty->getNumElements(); - StructLayout *L = - (StructLayout *)malloc(sizeof(StructLayout)+(NumElts-1) * sizeof(uint64_t)); - if (L == nullptr) - report_bad_alloc_error("Allocation of StructLayout elements failed."); + StructLayout *L = (StructLayout *) + safe_malloc(sizeof(StructLayout)+(NumElts-1) * sizeof(uint64_t)); // Set SL before calling StructLayout's ctor. The ctor could cause other // entries to be added to TheMap, invalidating our reference. @@ -618,6 +642,22 @@ unsigned DataLayout::getPointerTypeSizeInBits(Type *Ty) const { return getPointerSizeInBits(cast<PointerType>(Ty)->getAddressSpace()); } +unsigned DataLayout::getIndexSize(unsigned AS) const { + PointersTy::const_iterator I = findPointerLowerBound(AS); + if (I == Pointers.end() || I->AddressSpace != AS) { + I = findPointerLowerBound(0); + assert(I->AddressSpace == 0); + } + return I->IndexWidth; +} + +unsigned DataLayout::getIndexTypeSizeInBits(Type *Ty) const { + assert(Ty->isPtrOrPtrVectorTy() && + "This should only be called with a pointer or pointer vector type"); + Ty = Ty->getScalarType(); + return getIndexSizeInBits(cast<PointerType>(Ty)->getAddressSpace()); +} + /*! \param abi_or_pref Flag that determines which alignment is returned. true returns the ABI alignment, false returns the preferred alignment. @@ -701,13 +741,13 @@ unsigned DataLayout::getPreferredTypeAlignmentShift(Type *Ty) const { IntegerType *DataLayout::getIntPtrType(LLVMContext &C, unsigned AddressSpace) const { - return IntegerType::get(C, getPointerSizeInBits(AddressSpace)); + return IntegerType::get(C, getIndexSizeInBits(AddressSpace)); } Type *DataLayout::getIntPtrType(Type *Ty) const { assert(Ty->isPtrOrPtrVectorTy() && "Expected a pointer or pointer vector type."); - unsigned NumBits = getPointerTypeSizeInBits(Ty); + unsigned NumBits = getIndexTypeSizeInBits(Ty); IntegerType *IntTy = IntegerType::get(Ty->getContext(), NumBits); if (VectorType *VecTy = dyn_cast<VectorType>(Ty)) return VectorType::get(IntTy, VecTy->getNumElements()); @@ -726,6 +766,16 @@ unsigned DataLayout::getLargestLegalIntTypeSizeInBits() const { return Max != LegalIntWidths.end() ? *Max : 0; } +Type *DataLayout::getIndexType(Type *Ty) const { + assert(Ty->isPtrOrPtrVectorTy() && + "Expected a pointer or pointer vector type."); + unsigned NumBits = getIndexTypeSizeInBits(Ty); + IntegerType *IntTy = IntegerType::get(Ty->getContext(), NumBits); + if (VectorType *VecTy = dyn_cast<VectorType>(Ty)) + return VectorType::get(IntTy, VecTy->getNumElements()); + return IntTy; +} + int64_t DataLayout::getIndexedOffsetInType(Type *ElemTy, ArrayRef<Value *> Indices) const { int64_t Result = 0; |