X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FTargetData.cpp;h=63c5b6178a3f8803e52e8dddb376babc2bb4a029;hb=e668bdaa52c0e172afd6b4f0b06abf27119005c5;hp=8aea15430833caadf223e2d771db5e4263f96674;hpb=c8e876470572817295362737d8fbcf460e4cbfa8;p=oota-llvm.git diff --git a/lib/Target/TargetData.cpp b/lib/Target/TargetData.cpp index 8aea1543083..63c5b6178a3 100644 --- a/lib/Target/TargetData.cpp +++ b/lib/Target/TargetData.cpp @@ -1,10 +1,10 @@ //===-- TargetData.cpp - Data size & alignment routines --------------------==// -// +// // The LLVM Compiler Infrastructure // // This file was developed by the LLVM research group and is distributed under // the University of Illinois Open Source License. See LICENSE.TXT for details. -// +// //===----------------------------------------------------------------------===// // // This file defines target properties related to datatype size/offset/alignment @@ -21,6 +21,8 @@ #include "llvm/DerivedTypes.h" #include "llvm/Constants.h" #include "llvm/Support/GetElementPtrTypeIterator.h" +#include "llvm/Support/MathExtras.h" +#include using namespace llvm; // Handle the Pass registration stuff necessary to use TargetData's. @@ -41,7 +43,7 @@ StructLayout::StructLayout(const StructType *ST, const TargetData &TD) { StructSize = 0; // Loop over each of the elements, placing them in memory... - for (StructType::element_iterator TI = ST->element_begin(), + for (StructType::element_iterator TI = ST->element_begin(), TE = ST->element_end(); TI != TE; ++TI) { const Type *Ty = *TI; unsigned char A; @@ -70,6 +72,22 @@ StructLayout::StructLayout(const StructType *ST, const TargetData &TD) { StructSize = (StructSize/StructAlignment + 1) * StructAlignment; } + +/// getElementContainingOffset - Given a valid offset into the structure, +/// return the structure index that contains it. +unsigned StructLayout::getElementContainingOffset(uint64_t Offset) const { + std::vector::const_iterator SI = + std::upper_bound(MemberOffsets.begin(), MemberOffsets.end(), + Offset); + assert(SI != MemberOffsets.begin() && "Offset not in structure type!"); + --SI; + assert(*SI <= Offset && "upper_bound didn't work"); + assert((SI == MemberOffsets.begin() || *(SI-1) < Offset) && + (SI+1 == MemberOffsets.end() || *(SI+1) > Offset) && + "Upper bound didn't work!"); + return SI-MemberOffsets.begin(); +} + //===----------------------------------------------------------------------===// // TargetData Class Implementation //===----------------------------------------------------------------------===// @@ -77,7 +95,7 @@ StructLayout::StructLayout(const StructType *ST, const TargetData &TD) { TargetData::TargetData(const std::string &TargetName, bool isLittleEndian, unsigned char PtrSize, unsigned char PtrAl, unsigned char DoubleAl, - unsigned char FloatAl, unsigned char LongAl, + unsigned char FloatAl, unsigned char LongAl, unsigned char IntAl, unsigned char ShortAl, unsigned char ByteAl, unsigned char BoolAl) { @@ -106,13 +124,16 @@ TargetData::TargetData(const std::string &ToolName, const Module *M) { PointerAlignment = PointerSize; DoubleAlignment = PointerSize; FloatAlignment = 4; - LongAlignment = 8; + LongAlignment = PointerSize; IntAlignment = 4; ShortAlignment = 2; ByteAlignment = 1; BoolAlignment = 1; } +/// Layouts - The lazy cache of structure layout information maintained by +/// TargetData. +/// static std::map, StructLayout> *Layouts = 0; @@ -147,6 +168,21 @@ const StructLayout *TargetData::getStructLayout(const StructType *Ty) const { } } +/// InvalidateStructLayoutInfo - TargetData speculatively caches StructLayout +/// objects. If a TargetData object is alive when types are being refined and +/// 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 (!Layouts) return; // No cache. + + std::map, + StructLayout>::iterator I = Layouts->find(std::make_pair(this, Ty)); + if (I != Layouts->end()) + Layouts->erase(I); +} + + + static inline void getTypeInfo(const Type *Ty, const TargetData *TD, uint64_t &Size, unsigned char &Alignment) { assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!"); @@ -174,13 +210,23 @@ static inline void getTypeInfo(const Type *Ty, const TargetData *TD, Size = AlignedSize*ATy->getNumElements(); return; } + case Type::PackedTyID: { + const PackedType *PTy = cast(Ty); + getTypeInfo(PTy->getElementType(), TD, Size, Alignment); + unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment; + Size = AlignedSize*PTy->getNumElements(); + // FIXME: The alignments of specific packed types are target dependent. + // For now, just set it to be equal to Size. + Alignment = Size; + return; + } case Type::StructTyID: { // Get the layout annotation... which is lazily created on demand. const StructLayout *Layout = TD->getStructLayout(cast(Ty)); Size = Layout->StructSize; Alignment = Layout->StructAlignment; return; } - + default: assert(0 && "Bad type for getTypeInfo!!!"); return; @@ -201,6 +247,12 @@ unsigned char TargetData::getTypeAlignment(const Type *Ty) const { return Align; } +unsigned char TargetData::getTypeAlignmentShift(const Type *Ty) const { + unsigned Align = getTypeAlignment(Ty); + assert(!(Align & (Align-1)) && "Alignment is not a power of two!"); + return Log2_32(Align); +} + /// getIntPtrType - Return an unsigned integer type that is the same size or /// greater to the host pointer size. const Type *TargetData::getIntPtrType() const {