X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FTargetData.cpp;h=f83adefbee3426e2124a3c093aef21a6d274db9e;hb=6fa1c051dc515b6fd1f9a26ac12fed985469bff5;hp=8cef53de12130a23a1e4b24eebae1e4b94941bcc;hpb=4ee451de366474b9c228b4e5fa573795a715216d;p=oota-llvm.git diff --git a/lib/Target/TargetData.cpp b/lib/Target/TargetData.cpp index 8cef53de121..f83adefbee3 100644 --- a/lib/Target/TargetData.cpp +++ b/lib/Target/TargetData.cpp @@ -27,14 +27,13 @@ #include "llvm/ADT/StringExtras.h" #include #include -#include using namespace llvm; // Handle the Pass registration stuff necessary to use TargetData's. -namespace { - // Register the default SparcV9 implementation... - RegisterPass X("targetdata", "Target Data Layout"); -} + +// Register the default SparcV9 implementation... +static RegisterPass X("targetdata", "Target Data Layout", false, + true); char TargetData::ID = 0; //===----------------------------------------------------------------------===// @@ -49,10 +48,7 @@ StructLayout::StructLayout(const StructType *ST, const TargetData &TD) { // 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); - uint64_t TySize = ST->isPacked() ? - TD.getTypeStoreSize(Ty) : TD.getABITypeSize(Ty); + unsigned TyAlign = ST->isPacked() ? 1 : TD.getABITypeAlignment(Ty); // Add padding if necessary to align the data element properly... StructSize = (StructSize + TyAlign - 1)/TyAlign * TyAlign; @@ -61,7 +57,7 @@ StructLayout::StructLayout(const StructType *ST, const TargetData &TD) { StructAlignment = std::max(TyAlign, StructAlignment); MemberOffsets[i] = StructSize; - StructSize += TySize; // Consume space for this data item + StructSize += TD.getABITypeSize(Ty); // Consume space for this data item } // Empty structures have alignment of 1 byte. @@ -101,6 +97,7 @@ unsigned StructLayout::getElementContainingOffset(uint64_t Offset) const { TargetAlignElem TargetAlignElem::get(AlignTypeEnum align_type, unsigned char abi_align, unsigned char pref_align, uint32_t bit_width) { + assert(abi_align <= pref_align && "Preferred alignment worse than ABI!"); TargetAlignElem retval; retval.AlignType = align_type; retval.ABIAlign = abi_align; @@ -154,7 +151,8 @@ const TargetAlignElem TargetData::InvalidAlignmentElem = p:@verbatim::@endverbatim: Pointer size, ABI and preferred alignment.

- @verbatim::@endverbatim: Numeric type alignment. Type is + @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. \p @@ -241,6 +239,7 @@ TargetData::TargetData(const Module *M) void TargetData::setAlignment(AlignTypeEnum align_type, unsigned char abi_align, unsigned char pref_align, uint32_t bit_width) { + assert(abi_align <= pref_align && "Preferred alignment worse than ABI!"); for (unsigned i = 0, e = Alignments.size(); i != e; ++i) { if (Alignments[i].AlignType == align_type && Alignments[i].TypeBitWidth == bit_width) { @@ -258,7 +257,8 @@ TargetData::setAlignment(AlignTypeEnum align_type, unsigned char abi_align, /// getAlignmentInfo - Return the alignment (either ABI if ABIInfo = true or /// preferred if ABIInfo = false) the target wants for the specified datatype. unsigned TargetData::getAlignmentInfo(AlignTypeEnum AlignType, - uint32_t BitWidth, bool ABIInfo) const { + uint32_t BitWidth, bool ABIInfo, + const Type *Ty) const { // Check to see if we have an exact match and remember the best match we see. int BestMatchIdx = -1; int LargestInt = -1; @@ -293,19 +293,29 @@ unsigned TargetData::getAlignmentInfo(AlignTypeEnum AlignType, } } - // For integers, if we didn't find a best match, use the largest one found. - if (BestMatchIdx == -1) - BestMatchIdx = LargestInt; - // Okay, we didn't find an exact solution. Fall back here depending on what // is being looked for. - assert(BestMatchIdx != -1 && "Didn't find alignment info for this datatype!"); - + if (BestMatchIdx == -1) { + // If we didn't find an integer alignment, fall back on most conservative. + if (AlignType == INTEGER_ALIGN) { + 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 @@ -330,8 +340,10 @@ struct DenseMapLayoutKeyInfo { }; typedef DenseMap LayoutInfoTy; -static ManagedStatic LayoutInfo; +} + +static ManagedStatic LayoutInfo; TargetData::~TargetData() { if (LayoutInfo.isConstructed()) { @@ -474,7 +486,7 @@ unsigned char TargetData::getAlignment(const Type *Ty, bool abi_or_pref) const { // 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); + unsigned Align = getAlignmentInfo(AGGREGATE_ALIGN, 0, abi_or_pref, Ty); return std::max(Align, (unsigned)Layout->getAlignment()); } case Type::IntegerTyID: @@ -490,22 +502,16 @@ unsigned char TargetData::getAlignment(const Type *Ty, bool abi_or_pref) const { case Type::X86_FP80TyID: AlignType = FLOAT_ALIGN; break; - case Type::VectorTyID: { - const VectorType *VTy = cast(Ty); - // Degenerate vectors are assumed to be scalar-ized - if (VTy->getNumElements() == 1) - return getAlignment(VTy->getElementType(), abi_or_pref); - else - AlignType = VECTOR_ALIGN; + case Type::VectorTyID: + AlignType = VECTOR_ALIGN; break; - } default: assert(0 && "Bad type for getAlignment!!!"); break; } return getAlignmentInfo((AlignTypeEnum)AlignType, getTypeSizeInBits(Ty), - abi_or_pref); + abi_or_pref, Ty); } unsigned char TargetData::getABITypeAlignment(const Type *Ty) const { @@ -572,22 +578,29 @@ uint64_t TargetData::getIndexedOffset(const Type *ptrTy, Value* const* Indices, return Result; } -/// getPreferredAlignmentLog - Return the preferred alignment of the -/// specified global, returned in log form. This includes an explicitly -/// requested alignment (if the global has one). -unsigned TargetData::getPreferredAlignmentLog(const GlobalVariable *GV) const { +/// getPreferredAlignment - Return the preferred alignment of the specified +/// global. This includes an explicitly requested alignment (if the global +/// has one). +unsigned TargetData::getPreferredAlignment(const GlobalVariable *GV) const { const Type *ElemType = GV->getType()->getElementType(); - unsigned Alignment = getPreferredTypeAlignmentShift(ElemType); - if (GV->getAlignment() > (1U << Alignment)) - Alignment = Log2_32(GV->getAlignment()); - + unsigned Alignment = getPrefTypeAlignment(ElemType); + if (GV->getAlignment() > Alignment) + Alignment = GV->getAlignment(); + if (GV->hasInitializer()) { - if (Alignment < 4) { + if (Alignment < 16) { // If the global is not external, see if it is large. If so, give it a // larger alignment. if (getTypeSizeInBits(ElemType) > 128) - Alignment = 4; // 16-byte alignment. + Alignment = 16; // 16-byte alignment. } } return Alignment; } + +/// getPreferredAlignmentLog - Return the preferred alignment of the +/// specified global, returned in log form. This includes an explicitly +/// requested alignment (if the global has one). +unsigned TargetData::getPreferredAlignmentLog(const GlobalVariable *GV) const { + return Log2_32(getPreferredAlignment(GV)); +}