X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FTargetData.cpp;h=5bcd6583635bed8003917f59b382932603738d17;hb=762ccea600158bb317dcccdff3303e942426cb71;hp=f83adefbee3426e2124a3c093aef21a6d274db9e;hpb=a0fcc08e6542a0376917b5c76a0af3eb2650c535;p=oota-llvm.git diff --git a/lib/Target/TargetData.cpp b/lib/Target/TargetData.cpp index f83adefbee3..5bcd6583635 100644 --- a/lib/Target/TargetData.cpp +++ b/lib/Target/TargetData.cpp @@ -23,6 +23,8 @@ #include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/System/Mutex.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringExtras.h" #include @@ -45,19 +47,20 @@ StructLayout::StructLayout(const StructType *ST, const TargetData &TD) { StructSize = 0; NumElements = ST->getNumElements(); - // Loop over each of the elements, placing them in memory... + // Loop over each of the elements, placing them in memory. for (unsigned i = 0, e = NumElements; i != e; ++i) { const Type *Ty = ST->getElementType(i); unsigned TyAlign = ST->isPacked() ? 1 : TD.getABITypeAlignment(Ty); - // Add padding if necessary to align the data element properly... - StructSize = (StructSize + TyAlign - 1)/TyAlign * TyAlign; + // Add padding if necessary to align the data element properly. + if ((StructSize & (TyAlign-1)) != 0) + StructSize = TargetData::RoundUpAlignment(StructSize, TyAlign); - // Keep track of maximum alignment constraint + // Keep track of maximum alignment constraint. StructAlignment = std::max(TyAlign, StructAlignment); MemberOffsets[i] = StructSize; - StructSize += TD.getABITypeSize(Ty); // Consume space for this data item + StructSize += TD.getTypeAllocSize(Ty); // Consume space for this data item } // Empty structures have alignment of 1 byte. @@ -65,8 +68,8 @@ StructLayout::StructLayout(const StructType *ST, const TargetData &TD) { // Add padding to the end of the struct so that it could be put in an array // and all array elements would be aligned correctly. - if (StructSize % StructAlignment != 0) - StructSize = (StructSize/StructAlignment + 1) * StructAlignment; + if ((StructSize & (StructAlignment-1)) != 0) + StructSize = TargetData::RoundUpAlignment(StructSize, StructAlignment); } @@ -153,13 +156,13 @@ const TargetAlignElem TargetData::InvalidAlignmentElem =

@verbatim::@endverbatim: Numeric type alignment. Type is - one of i|f|v|a, corresponding to integer, floating point, vector (aka - packed) or aggregate. Size indicates the size, e.g., 32 or 64 bits. + one of i|f|v|a, corresponding to integer, floating point, vector, or + aggregate. Size indicates the size, e.g., 32 or 64 bits. \p - The default string, fully specified is: + The default string, fully specified, is:

- "E-p:64:64:64-a0:0:0-f32:32:32-f64:0:64" - "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:0:64" + "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64" + "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64" "-v64:64:64-v128:128:128"

Note that in the case of aggregates, 0 is the default ABI and preferred @@ -169,22 +172,23 @@ const TargetAlignElem TargetData::InvalidAlignmentElem = void TargetData::init(const std::string &TargetDescription) { std::string temp = TargetDescription; + LayoutMap = 0; LittleEndian = false; PointerMemSize = 8; PointerABIAlign = 8; PointerPrefAlign = PointerABIAlign; // Default alignments - setAlignment(INTEGER_ALIGN, 1, 1, 1); // Bool - setAlignment(INTEGER_ALIGN, 1, 1, 8); // Byte - setAlignment(INTEGER_ALIGN, 2, 2, 16); // short - setAlignment(INTEGER_ALIGN, 4, 4, 32); // int - setAlignment(INTEGER_ALIGN, 4, 8, 64); // long + setAlignment(INTEGER_ALIGN, 1, 1, 1); // i1 + setAlignment(INTEGER_ALIGN, 1, 1, 8); // i8 + setAlignment(INTEGER_ALIGN, 2, 2, 16); // i16 + setAlignment(INTEGER_ALIGN, 4, 4, 32); // i32 + setAlignment(INTEGER_ALIGN, 4, 8, 64); // i64 setAlignment(FLOAT_ALIGN, 4, 4, 32); // float setAlignment(FLOAT_ALIGN, 8, 8, 64); // double - setAlignment(VECTOR_ALIGN, 8, 8, 64); // v2i32 + setAlignment(VECTOR_ALIGN, 8, 8, 64); // v2i32, v1i64, ... setAlignment(VECTOR_ALIGN, 16, 16, 128); // v16i8, v8i16, v4i32, ... - setAlignment(AGGREGATE_ALIGN, 0, 8, 0); // struct, union, class, ... + setAlignment(AGGREGATE_ALIGN, 0, 8, 0); // struct while (!temp.empty()) { std::string token = getToken(temp, "-"); @@ -232,7 +236,7 @@ void TargetData::init(const std::string &TargetDescription) { } TargetData::TargetData(const Module *M) - : ImmutablePass((intptr_t)&ID) { + : ImmutablePass(&ID) { init(M->getDataLayout()); } @@ -301,71 +305,43 @@ unsigned TargetData::getAlignmentInfo(AlignTypeEnum AlignType, BestMatchIdx = LargestInt; } else { assert(AlignType == VECTOR_ALIGN && "Unknown alignment type!"); - + // If we didn't find a vector size that is smaller or equal to this type, // then we will end up scalarizing this to its element type. Just return // the alignment of the element. return getAlignment(cast(Ty)->getElementType(), ABIInfo); - } + } } - + // Since we got a "best match" index, just return it. return ABIInfo ? Alignments[BestMatchIdx].ABIAlign : Alignments[BestMatchIdx].PrefAlign; } -namespace { - -/// LayoutInfo - The lazy cache of structure layout information maintained by -/// TargetData. Note that the struct types must have been free'd before -/// llvm_shutdown is called (and thus this is deallocated) because all the -/// targets with cached elements should have been destroyed. -/// -typedef std::pair LayoutKey; - -struct DenseMapLayoutKeyInfo { - static inline LayoutKey getEmptyKey() { return LayoutKey(0, 0); } - static inline LayoutKey getTombstoneKey() { - return LayoutKey((TargetData*)(intptr_t)-1, 0); - } - static unsigned getHashValue(const LayoutKey &Val) { - return DenseMapInfo::getHashValue(Val.first) ^ - DenseMapInfo::getHashValue(Val.second); - } - static bool isEqual(const LayoutKey &LHS, const LayoutKey &RHS) { - return LHS == RHS; - } - - static bool isPod() { return true; } -}; - -typedef DenseMap LayoutInfoTy; - -} - -static ManagedStatic LayoutInfo; +typedef DenseMapLayoutInfoTy; TargetData::~TargetData() { - if (LayoutInfo.isConstructed()) { - // Remove any layouts for this TD. - LayoutInfoTy &TheMap = *LayoutInfo; - for (LayoutInfoTy::iterator I = TheMap.begin(), E = TheMap.end(); - I != E; ) { - if (I->first.first == this) { - I->second->~StructLayout(); - free(I->second); - TheMap.erase(I++); - } else { - ++I; - } - } + if (!LayoutMap) + return; + + // Remove any layouts for this TD. + LayoutInfoTy &TheMap = *static_cast(LayoutMap); + for (LayoutInfoTy::iterator I = TheMap.begin(), E = TheMap.end(); I != E; ) { + I->second->~StructLayout(); + free(I->second); + TheMap.erase(I++); } + + delete static_cast(LayoutMap); } const StructLayout *TargetData::getStructLayout(const StructType *Ty) const { - LayoutInfoTy &TheMap = *LayoutInfo; + if (!LayoutMap) + LayoutMap = static_cast(new LayoutInfoTy()); - StructLayout *&SL = TheMap[LayoutKey(this, Ty)]; + LayoutInfoTy &TheMap = *static_cast(LayoutMap); + + StructLayout *&SL = TheMap[Ty]; if (SL) return SL; // Otherwise, create the struct layout. Because it is variable length, we @@ -387,14 +363,15 @@ const StructLayout *TargetData::getStructLayout(const StructType *Ty) const { /// removed, this method must be called whenever a StructType is removed to /// avoid a dangling pointer in this cache. void TargetData::InvalidateStructLayoutInfo(const StructType *Ty) const { - if (!LayoutInfo.isConstructed()) return; // No cache. + if (!LayoutMap) return; // No cache. - LayoutInfoTy::iterator I = LayoutInfo->find(LayoutKey(this, Ty)); - if (I != LayoutInfo->end()) { - I->second->~StructLayout(); - free(I->second); - LayoutInfo->erase(I); - } + LayoutInfoTy* LayoutInfo = static_cast(LayoutMap); + LayoutInfoTy::iterator I = LayoutInfo->find(Ty); + if (I == LayoutInfo->end()) return; + + I->second->~StructLayout(); + free(I->second); + LayoutInfo->erase(I); } @@ -424,13 +401,11 @@ uint64_t TargetData::getTypeSizeInBits(const Type *Ty) const { return getPointerSizeInBits(); case Type::ArrayTyID: { const ArrayType *ATy = cast(Ty); - return getABITypeSizeInBits(ATy->getElementType())*ATy->getNumElements(); + return getTypeAllocSizeInBits(ATy->getElementType())*ATy->getNumElements(); } - case Type::StructTyID: { + case Type::StructTyID: // Get the layout annotation... which is lazily created on demand. - const StructLayout *Layout = getStructLayout(cast(Ty)); - return Layout->getSizeInBits(); - } + return getStructLayout(cast(Ty))->getSizeInBits(); case Type::IntegerTyID: return cast(Ty)->getBitWidth(); case Type::VoidTyID: @@ -446,12 +421,10 @@ uint64_t TargetData::getTypeSizeInBits(const Type *Ty) const { // only 80 bits contain information. case Type::X86_FP80TyID: return 80; - case Type::VectorTyID: { - const VectorType *PTy = cast(Ty); - return PTy->getBitWidth(); - } + case Type::VectorTyID: + return cast(Ty)->getBitWidth(); default: - assert(0 && "TargetData::getTypeSizeInBits(): Unsupported type"); + llvm_unreachable("TargetData::getTypeSizeInBits(): Unsupported type"); break; } return 0; @@ -470,7 +443,7 @@ unsigned char TargetData::getAlignment(const Type *Ty, bool abi_or_pref) const { assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!"); switch (Ty->getTypeID()) { - /* Early escape for the non-numeric types */ + // Early escape for the non-numeric types. case Type::LabelTyID: case Type::PointerTyID: return (abi_or_pref @@ -478,12 +451,12 @@ unsigned char TargetData::getAlignment(const Type *Ty, bool abi_or_pref) const { : getPointerPrefAlignment()); case Type::ArrayTyID: return getAlignment(cast(Ty)->getElementType(), abi_or_pref); - + case Type::StructTyID: { // Packed structure types always have an ABI alignment of one. if (cast(Ty)->isPacked() && abi_or_pref) return 1; - + // Get the layout annotation... which is lazily created on demand. const StructLayout *Layout = getStructLayout(cast(Ty)); unsigned Align = getAlignmentInfo(AGGREGATE_ALIGN, 0, abi_or_pref, Ty); @@ -506,7 +479,7 @@ unsigned char TargetData::getAlignment(const Type *Ty, bool abi_or_pref) const { AlignType = VECTOR_ALIGN; break; default: - assert(0 && "Bad type for getAlignment!!!"); + llvm_unreachable("Bad type for getAlignment!!!"); break; } @@ -538,8 +511,8 @@ unsigned char TargetData::getPreferredTypeAlignmentShift(const Type *Ty) const { /// getIntPtrType - Return an unsigned integer type that is the same size or /// greater to the host pointer size. -const Type *TargetData::getIntPtrType() const { - return IntegerType::get(getPointerSizeInBits()); +const IntegerType *TargetData::getIntPtrType(LLVMContext &C) const { + return IntegerType::get(C, getPointerSizeInBits()); } @@ -553,7 +526,8 @@ uint64_t TargetData::getIndexedOffset(const Type *ptrTy, Value* const* Indices, TI = gep_type_begin(ptrTy, Indices, Indices+NumIndices); for (unsigned CurIDX = 0; CurIDX != NumIndices; ++CurIDX, ++TI) { if (const StructType *STy = dyn_cast(*TI)) { - assert(Indices[CurIDX]->getType() == Type::Int32Ty && + assert(Indices[CurIDX]->getType() == + Type::getInt32Ty(ptrTy->getContext()) && "Illegal struct idx"); unsigned FieldNo = cast(Indices[CurIDX])->getZExtValue(); @@ -571,7 +545,7 @@ uint64_t TargetData::getIndexedOffset(const Type *ptrTy, Value* const* Indices, // Get the array index and the size of each array element. int64_t arrayIdx = cast(Indices[CurIDX])->getSExtValue(); - Result += arrayIdx * (int64_t)getABITypeSize(Ty); + Result += arrayIdx * (int64_t)getTypeAllocSize(Ty); } }