Index: include/llvm/InitializePasses.h =================================================================== --- include/llvm/InitializePasses.h (revision 165282) +++ include/llvm/InitializePasses.h (working copy) @@ -246,7 +246,6 @@ void initializeTailCallElimPass(PassRegistry&); void initializeTailDuplicatePassPass(PassRegistry&); void initializeTargetPassConfigPass(PassRegistry&); -void initializeTargetDataPass(PassRegistry&); void initializeDataLayoutPass(PassRegistry&); void initializeTargetLibraryInfoPass(PassRegistry&); void initializeTwoAddressInstructionPassPass(PassRegistry&); Index: include/llvm/Target/TargetData.h =================================================================== --- include/llvm/Target/TargetData.h (revision 165282) +++ include/llvm/Target/TargetData.h (working copy) @@ -7,357 +7,47 @@ // //===----------------------------------------------------------------------===// // -// This file defines target properties related to datatype size/offset/alignment -// information. It uses lazy annotations to cache information about how -// structure types are laid out and used. +// This file defines the wrapper for DataLayout to provide compatibility +// with the old TargetData class. // -// This structure should be created once, filled in if the defaults are not -// correct and then passed around by const&. None of the members functions -// require modification to the object. -// //===----------------------------------------------------------------------===// #ifndef LLVM_TARGET_TARGETDATA_H #define LLVM_TARGET_TARGETDATA_H +#include "llvm/DataLayout.h" #include "llvm/Pass.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/DataTypes.h" namespace llvm { -class Value; -class Type; -class IntegerType; -class StructType; -class StructLayout; -class GlobalVariable; -class LLVMContext; -template -class ArrayRef; - -/// Enum used to categorize the alignment types stored by TargetAlignElem -enum AlignTypeEnum { - INTEGER_ALIGN = 'i', ///< Integer type alignment - VECTOR_ALIGN = 'v', ///< Vector type alignment - FLOAT_ALIGN = 'f', ///< Floating point type alignment - AGGREGATE_ALIGN = 'a', ///< Aggregate alignment - STACK_ALIGN = 's' ///< Stack objects alignment -}; - -/// Target alignment element. -/// -/// Stores the alignment data associated with a given alignment type (pointer, -/// integer, vector, float) and type bit width. -/// -/// @note The unusual order of elements in the structure attempts to reduce -/// padding and make the structure slightly more cache friendly. -struct TargetAlignElem { - unsigned AlignType : 8; ///< Alignment type (AlignTypeEnum) - unsigned TypeBitWidth : 24; ///< Type bit width - unsigned ABIAlign : 16; ///< ABI alignment for this type/bitw - unsigned PrefAlign : 16; ///< Pref. alignment for this type/bitw - - /// Initializer - static TargetAlignElem get(AlignTypeEnum align_type, unsigned abi_align, - unsigned pref_align, uint32_t bit_width); - /// Equality predicate - bool operator==(const TargetAlignElem &rhs) const; -}; - -/// TargetData - This class holds a parsed version of the target data layout -/// string in a module and provides methods for querying it. The target data -/// layout string is specified *by the target* - a frontend generating LLVM IR -/// is required to generate the right target data for the target being codegen'd -/// to. If some measure of portability is desired, an empty string may be -/// specified in the module. -class TargetData : public ImmutablePass { -private: - bool LittleEndian; ///< Defaults to false - unsigned PointerMemSize; ///< Pointer size in bytes - unsigned PointerABIAlign; ///< Pointer ABI alignment - unsigned PointerPrefAlign; ///< Pointer preferred alignment - unsigned StackNaturalAlign; ///< Stack natural alignment - - SmallVector LegalIntWidths; ///< Legal Integers. - - /// Alignments- Where the primitive type alignment data is stored. - /// - /// @sa init(). - /// @note Could support multiple size pointer alignments, e.g., 32-bit - /// pointers vs. 64-bit pointers by extending TargetAlignment, but for now, - /// we don't. - SmallVector Alignments; - - /// InvalidAlignmentElem - This member is a signal that a requested alignment - /// type and bit width were not found in the SmallVector. - static const TargetAlignElem InvalidAlignmentElem; - - // The StructType -> StructLayout map. - mutable void *LayoutMap; - - //! Set/initialize target alignments - void setAlignment(AlignTypeEnum align_type, unsigned abi_align, - unsigned pref_align, uint32_t bit_width); - unsigned getAlignmentInfo(AlignTypeEnum align_type, uint32_t bit_width, - bool ABIAlign, Type *Ty) const; - //! Internal helper method that returns requested alignment for type. - unsigned getAlignment(Type *Ty, bool abi_or_pref) const; - - /// Valid alignment predicate. - /// - /// Predicate that tests a TargetAlignElem reference returned by get() against - /// InvalidAlignmentElem. - bool validAlignment(const TargetAlignElem &align) const { - return &align != &InvalidAlignmentElem; - } - - /// Initialise a TargetData object with default values, ensure that the - /// target data pass is registered. - void init(); - +/// TargetData - This class is just a wrapper to help with the transition to the +/// new DataLayout class. +class TargetData : public DataLayout { public: /// Default ctor. /// /// @note This has to exist, because this is a pass, but it should never be /// used. - TargetData(); + TargetData() : DataLayout() {}; - /// Constructs a TargetData from a specification string. See init(). + /// Constructs a TargetData from a specification string. + /// See DataLayout::init(). explicit TargetData(StringRef TargetDescription) - : ImmutablePass(ID) { - std::string errMsg = parseSpecifier(TargetDescription, this); - assert(errMsg == "" && "Invalid target data layout string."); - (void)errMsg; - } + : DataLayout(TargetDescription) {} - /// Parses a target data specification string. Returns an error message - /// if the string is malformed, or the empty string on success. Optionally - /// initialises a TargetData object if passed a non-null pointer. - static std::string parseSpecifier(StringRef TargetDescription, TargetData* td = 0); - /// Initialize target data from properties stored in the module. - explicit TargetData(const Module *M); + explicit TargetData(const Module *M) : DataLayout(M) {} - TargetData(const TargetData &TD) : - ImmutablePass(ID), - LittleEndian(TD.isLittleEndian()), - PointerMemSize(TD.PointerMemSize), - PointerABIAlign(TD.PointerABIAlign), - PointerPrefAlign(TD.PointerPrefAlign), - LegalIntWidths(TD.LegalIntWidths), - Alignments(TD.Alignments), - LayoutMap(0) - { } + TargetData(const TargetData &TD) : DataLayout(TD) {} - ~TargetData(); // Not virtual, do not subclass this class - - /// Target endianness... - bool isLittleEndian() const { return LittleEndian; } - bool isBigEndian() const { return !LittleEndian; } - - /// getStringRepresentation - Return the string representation of the - /// TargetData. This representation is in the same format accepted by the - /// string constructor above. - std::string getStringRepresentation() const; - - /// isLegalInteger - This function returns true if the specified type is - /// known to be a native integer type supported by the CPU. For example, - /// i64 is not native on most 32-bit CPUs and i37 is not native on any known - /// one. This returns false if the integer width is not legal. - /// - /// The width is specified in bits. - /// - bool isLegalInteger(unsigned Width) const { - for (unsigned i = 0, e = (unsigned)LegalIntWidths.size(); i != e; ++i) - if (LegalIntWidths[i] == Width) - return true; - return false; - } - - bool isIllegalInteger(unsigned Width) const { - return !isLegalInteger(Width); - } - - /// Returns true if the given alignment exceeds the natural stack alignment. - bool exceedsNaturalStackAlignment(unsigned Align) const { - return (StackNaturalAlign != 0) && (Align > StackNaturalAlign); - } - - /// fitsInLegalInteger - This function returns true if the specified type fits - /// in a native integer type supported by the CPU. For example, if the CPU - /// only supports i32 as a native integer type, then i27 fits in a legal - // integer type but i45 does not. - bool fitsInLegalInteger(unsigned Width) const { - for (unsigned i = 0, e = (unsigned)LegalIntWidths.size(); i != e; ++i) - if (Width <= LegalIntWidths[i]) - return true; - return false; - } - - /// Target pointer alignment - unsigned getPointerABIAlignment() const { return PointerABIAlign; } - /// Return target's alignment for stack-based pointers - unsigned getPointerPrefAlignment() const { return PointerPrefAlign; } - /// Target pointer size - unsigned getPointerSize() const { return PointerMemSize; } - /// Target pointer size, in bits - unsigned getPointerSizeInBits() const { return 8*PointerMemSize; } - - /// Size examples: - /// - /// Type SizeInBits StoreSizeInBits AllocSizeInBits[*] - /// ---- ---------- --------------- --------------- - /// i1 1 8 8 - /// i8 8 8 8 - /// i19 19 24 32 - /// i32 32 32 32 - /// i100 100 104 128 - /// i128 128 128 128 - /// Float 32 32 32 - /// Double 64 64 64 - /// X86_FP80 80 80 96 - /// - /// [*] The alloc size depends on the alignment, and thus on the target. - /// These values are for x86-32 linux. - - /// getTypeSizeInBits - Return the number of bits necessary to hold the - /// specified type. For example, returns 36 for i36 and 80 for x86_fp80. - uint64_t getTypeSizeInBits(Type* Ty) const; - - /// getTypeStoreSize - Return the maximum number of bytes that may be - /// overwritten by storing the specified type. For example, returns 5 - /// for i36 and 10 for x86_fp80. - uint64_t getTypeStoreSize(Type *Ty) const { - return (getTypeSizeInBits(Ty)+7)/8; - } - - /// getTypeStoreSizeInBits - Return the maximum number of bits that may be - /// overwritten by storing the specified type; always a multiple of 8. For - /// example, returns 40 for i36 and 80 for x86_fp80. - uint64_t getTypeStoreSizeInBits(Type *Ty) const { - return 8*getTypeStoreSize(Ty); - } - - /// getTypeAllocSize - Return the offset in bytes between successive objects - /// of the specified type, including alignment padding. This is the amount - /// that alloca reserves for this type. For example, returns 12 or 16 for - /// x86_fp80, depending on alignment. - uint64_t getTypeAllocSize(Type* Ty) const { - // Round up to the next alignment boundary. - return RoundUpAlignment(getTypeStoreSize(Ty), getABITypeAlignment(Ty)); - } - - /// getTypeAllocSizeInBits - Return the offset in bits between successive - /// objects of the specified type, including alignment padding; always a - /// multiple of 8. This is the amount that alloca reserves for this type. - /// For example, returns 96 or 128 for x86_fp80, depending on alignment. - uint64_t getTypeAllocSizeInBits(Type* Ty) const { - return 8*getTypeAllocSize(Ty); - } - - /// getABITypeAlignment - Return the minimum ABI-required alignment for the - /// specified type. - unsigned getABITypeAlignment(Type *Ty) const; - - /// getABIIntegerTypeAlignment - Return the minimum ABI-required alignment for - /// an integer type of the specified bitwidth. - unsigned getABIIntegerTypeAlignment(unsigned BitWidth) const; - - - /// getCallFrameTypeAlignment - Return the minimum ABI-required alignment - /// for the specified type when it is part of a call frame. - unsigned getCallFrameTypeAlignment(Type *Ty) const; - - - /// getPrefTypeAlignment - Return the preferred stack/global alignment for - /// the specified type. This is always at least as good as the ABI alignment. - unsigned getPrefTypeAlignment(Type *Ty) const; - - /// getPreferredTypeAlignmentShift - Return the preferred alignment for the - /// specified type, returned as log2 of the value (a shift amount). - /// - unsigned getPreferredTypeAlignmentShift(Type *Ty) const; - - /// getIntPtrType - Return an unsigned integer type that is the same size or - /// greater to the host pointer size. - /// - IntegerType *getIntPtrType(LLVMContext &C) const; - - /// getIndexedOffset - return the offset from the beginning of the type for - /// the specified indices. This is used to implement getelementptr. - /// - uint64_t getIndexedOffset(Type *Ty, ArrayRef Indices) const; - - /// getStructLayout - Return a StructLayout object, indicating the alignment - /// of the struct, its size, and the offsets of its fields. Note that this - /// information is lazily cached. - const StructLayout *getStructLayout(StructType *Ty) const; - - /// getPreferredAlignment - Return the preferred alignment of the specified - /// global. This includes an explicitly requested alignment (if the global - /// has one). - unsigned getPreferredAlignment(const GlobalVariable *GV) const; - - /// 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 getPreferredAlignmentLog(const GlobalVariable *GV) const; - - /// RoundUpAlignment - Round the specified value up to the next alignment - /// boundary specified by Alignment. For example, 7 rounded up to an - /// alignment boundary of 4 is 8. 8 rounded up to the alignment boundary of 4 - /// is 8 because it is already aligned. template static UIntTy RoundUpAlignment(UIntTy Val, unsigned Alignment) { - assert((Alignment & (Alignment-1)) == 0 && "Alignment must be power of 2!"); - return (Val + (Alignment-1)) & ~UIntTy(Alignment-1); + return DataLayout::RoundUpAlignment(Val, Alignment); } - - static char ID; // Pass identification, replacement for typeid }; -/// StructLayout - used to lazily calculate structure layout information for a -/// target machine, based on the TargetData structure. -/// -class StructLayout { - uint64_t StructSize; - unsigned StructAlignment; - unsigned NumElements; - uint64_t MemberOffsets[1]; // variable sized array! -public: - - uint64_t getSizeInBytes() const { - return StructSize; - } - - uint64_t getSizeInBits() const { - return 8*StructSize; - } - - unsigned getAlignment() const { - return StructAlignment; - } - - /// getElementContainingOffset - Given a valid byte offset into the structure, - /// return the structure index that contains it. - /// - unsigned getElementContainingOffset(uint64_t Offset) const; - - uint64_t getElementOffset(unsigned Idx) const { - assert(Idx < NumElements && "Invalid element idx!"); - return MemberOffsets[Idx]; - } - - uint64_t getElementOffsetInBits(unsigned Idx) const { - return getElementOffset(Idx)*8; - } - -private: - friend class TargetData; // Only TargetData can create this class - StructLayout(StructType *ST, const TargetData &TD); -}; - } // End llvm namespace #endif Index: lib/Target/CMakeLists.txt =================================================================== --- lib/Target/CMakeLists.txt (revision 165282) +++ lib/Target/CMakeLists.txt (working copy) @@ -1,7 +1,6 @@ add_llvm_library(LLVMTarget Mangler.cpp Target.cpp - TargetData.cpp TargetELFWriterInfo.cpp TargetInstrInfo.cpp TargetIntrinsicInfo.cpp Index: lib/Target/TargetData.cpp =================================================================== --- lib/Target/TargetData.cpp (revision 165282) +++ lib/Target/TargetData.cpp (working copy) @@ -1,665 +0,0 @@ -//===-- TargetData.cpp - Data size & alignment routines --------------------==// -// -// The LLVM Compiler Infrastructure -// -// This file 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 -// information. -// -// This structure should be created once, filled in if the defaults are not -// correct and then passed around by const&. None of the members functions -// require modification to the object. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Target/TargetData.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Module.h" -#include "llvm/Support/GetElementPtrTypeIterator.h" -#include "llvm/Support/MathExtras.h" -#include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Support/Mutex.h" -#include "llvm/ADT/DenseMap.h" -#include -#include -using namespace llvm; - -// Handle the Pass registration stuff necessary to use TargetData's. - -// Register the default SparcV9 implementation... -INITIALIZE_PASS(TargetData, "targetdata", "Target Data Layout", false, true) -char TargetData::ID = 0; - -//===----------------------------------------------------------------------===// -// Support for StructLayout -//===----------------------------------------------------------------------===// - -StructLayout::StructLayout(StructType *ST, const TargetData &TD) { - assert(!ST->isOpaque() && "Cannot get layout of opaque structs"); - StructAlignment = 0; - StructSize = 0; - NumElements = ST->getNumElements(); - - // Loop over each of the elements, placing them in memory. - for (unsigned i = 0, e = NumElements; i != e; ++i) { - Type *Ty = ST->getElementType(i); - unsigned TyAlign = ST->isPacked() ? 1 : TD.getABITypeAlignment(Ty); - - // 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. - StructAlignment = std::max(TyAlign, StructAlignment); - - MemberOffsets[i] = StructSize; - StructSize += TD.getTypeAllocSize(Ty); // Consume space for this data item - } - - // Empty structures have alignment of 1 byte. - if (StructAlignment == 0) StructAlignment = 1; - - // 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-1)) != 0) - StructSize = TargetData::RoundUpAlignment(StructSize, StructAlignment); -} - - -/// getElementContainingOffset - Given a valid offset into the structure, -/// return the structure index that contains it. -unsigned StructLayout::getElementContainingOffset(uint64_t Offset) const { - const uint64_t *SI = - std::upper_bound(&MemberOffsets[0], &MemberOffsets[NumElements], Offset); - assert(SI != &MemberOffsets[0] && "Offset not in structure type!"); - --SI; - assert(*SI <= Offset && "upper_bound didn't work"); - assert((SI == &MemberOffsets[0] || *(SI-1) <= Offset) && - (SI+1 == &MemberOffsets[NumElements] || *(SI+1) > Offset) && - "Upper bound didn't work!"); - - // Multiple fields can have the same offset if any of them are zero sized. - // For example, in { i32, [0 x i32], i32 }, searching for offset 4 will stop - // at the i32 element, because it is the last element at that offset. This is - // the right one to return, because anything after it will have a higher - // offset, implying that this element is non-empty. - return SI-&MemberOffsets[0]; -} - -//===----------------------------------------------------------------------===// -// TargetAlignElem, TargetAlign support -//===----------------------------------------------------------------------===// - -TargetAlignElem -TargetAlignElem::get(AlignTypeEnum align_type, unsigned abi_align, - unsigned 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; - retval.PrefAlign = pref_align; - retval.TypeBitWidth = bit_width; - return retval; -} - -bool -TargetAlignElem::operator==(const TargetAlignElem &rhs) const { - return (AlignType == rhs.AlignType - && ABIAlign == rhs.ABIAlign - && PrefAlign == rhs.PrefAlign - && TypeBitWidth == rhs.TypeBitWidth); -} - -const TargetAlignElem -TargetData::InvalidAlignmentElem = { (AlignTypeEnum)0xFF, 0, 0, 0 }; - -//===----------------------------------------------------------------------===// -// TargetData Class Implementation -//===----------------------------------------------------------------------===// - -/// getInt - Get an integer ignoring errors. -static int getInt(StringRef R) { - int Result = 0; - R.getAsInteger(10, Result); - return Result; -} - -void TargetData::init() { - initializeTargetDataPass(*PassRegistry::getPassRegistry()); - - LayoutMap = 0; - LittleEndian = false; - PointerMemSize = 8; - PointerABIAlign = 8; - PointerPrefAlign = PointerABIAlign; - StackNaturalAlign = 0; - - // Default alignments - 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, 2, 2, 16); // half - setAlignment(FLOAT_ALIGN, 4, 4, 32); // float - setAlignment(FLOAT_ALIGN, 8, 8, 64); // double - setAlignment(FLOAT_ALIGN, 16, 16, 128); // ppcf128, quad, ... - setAlignment(VECTOR_ALIGN, 8, 8, 64); // v2i32, v1i64, ... - setAlignment(VECTOR_ALIGN, 16, 16, 128); // v16i8, v8i16, v4i32, ... - setAlignment(AGGREGATE_ALIGN, 0, 8, 0); // struct -} - -std::string TargetData::parseSpecifier(StringRef Desc, TargetData *td) { - - if (td) - td->init(); - - while (!Desc.empty()) { - std::pair Split = Desc.split('-'); - StringRef Token = Split.first; - Desc = Split.second; - - if (Token.empty()) - continue; - - Split = Token.split(':'); - StringRef Specifier = Split.first; - Token = Split.second; - - assert(!Specifier.empty() && "Can't be empty here"); - - switch (Specifier[0]) { - case 'E': - if (td) - td->LittleEndian = false; - break; - case 'e': - if (td) - td->LittleEndian = true; - break; - case 'p': { - // Pointer size. - Split = Token.split(':'); - int PointerMemSizeBits = getInt(Split.first); - if (PointerMemSizeBits < 0 || PointerMemSizeBits % 8 != 0) - return "invalid pointer size, must be a positive 8-bit multiple"; - if (td) - td->PointerMemSize = PointerMemSizeBits / 8; - - // Pointer ABI alignment. - Split = Split.second.split(':'); - int PointerABIAlignBits = getInt(Split.first); - if (PointerABIAlignBits < 0 || PointerABIAlignBits % 8 != 0) { - return "invalid pointer ABI alignment, " - "must be a positive 8-bit multiple"; - } - if (td) - td->PointerABIAlign = PointerABIAlignBits / 8; - - // Pointer preferred alignment. - Split = Split.second.split(':'); - int PointerPrefAlignBits = getInt(Split.first); - if (PointerPrefAlignBits < 0 || PointerPrefAlignBits % 8 != 0) { - return "invalid pointer preferred alignment, " - "must be a positive 8-bit multiple"; - } - if (td) { - td->PointerPrefAlign = PointerPrefAlignBits / 8; - if (td->PointerPrefAlign == 0) - td->PointerPrefAlign = td->PointerABIAlign; - } - break; - } - case 'i': - case 'v': - case 'f': - case 'a': - case 's': { - AlignTypeEnum AlignType; - char field = Specifier[0]; - switch (field) { - default: - case 'i': AlignType = INTEGER_ALIGN; break; - case 'v': AlignType = VECTOR_ALIGN; break; - case 'f': AlignType = FLOAT_ALIGN; break; - case 'a': AlignType = AGGREGATE_ALIGN; break; - case 's': AlignType = STACK_ALIGN; break; - } - int Size = getInt(Specifier.substr(1)); - if (Size < 0) { - return std::string("invalid ") + field + "-size field, " - "must be positive"; - } - - Split = Token.split(':'); - int ABIAlignBits = getInt(Split.first); - if (ABIAlignBits < 0 || ABIAlignBits % 8 != 0) { - return std::string("invalid ") + field +"-abi-alignment field, " - "must be a positive 8-bit multiple"; - } - unsigned ABIAlign = ABIAlignBits / 8; - - Split = Split.second.split(':'); - - int PrefAlignBits = getInt(Split.first); - if (PrefAlignBits < 0 || PrefAlignBits % 8 != 0) { - return std::string("invalid ") + field +"-preferred-alignment field, " - "must be a positive 8-bit multiple"; - } - unsigned PrefAlign = PrefAlignBits / 8; - if (PrefAlign == 0) - PrefAlign = ABIAlign; - - if (td) - td->setAlignment(AlignType, ABIAlign, PrefAlign, Size); - break; - } - case 'n': // Native integer types. - Specifier = Specifier.substr(1); - do { - int Width = getInt(Specifier); - if (Width <= 0) { - return std::string("invalid native integer size \'") + Specifier.str() + - "\', must be a positive integer."; - } - if (td && Width != 0) - td->LegalIntWidths.push_back(Width); - Split = Token.split(':'); - Specifier = Split.first; - Token = Split.second; - } while (!Specifier.empty() || !Token.empty()); - break; - case 'S': { // Stack natural alignment. - int StackNaturalAlignBits = getInt(Specifier.substr(1)); - if (StackNaturalAlignBits < 0 || StackNaturalAlignBits % 8 != 0) { - return "invalid natural stack alignment (S-field), " - "must be a positive 8-bit multiple"; - } - if (td) - td->StackNaturalAlign = StackNaturalAlignBits / 8; - break; - } - default: - break; - } - } - - return ""; -} - -/// Default ctor. -/// -/// @note This has to exist, because this is a pass, but it should never be -/// used. -TargetData::TargetData() : ImmutablePass(ID) { - report_fatal_error("Bad TargetData ctor used. " - "Tool did not specify a TargetData to use?"); -} - -TargetData::TargetData(const Module *M) - : ImmutablePass(ID) { - std::string errMsg = parseSpecifier(M->getDataLayout(), this); - assert(errMsg == "" && "Module M has malformed target data layout string."); - (void)errMsg; -} - -void -TargetData::setAlignment(AlignTypeEnum align_type, unsigned abi_align, - unsigned pref_align, uint32_t bit_width) { - assert(abi_align <= pref_align && "Preferred alignment worse than ABI!"); - assert(pref_align < (1 << 16) && "Alignment doesn't fit in bitfield"); - assert(bit_width < (1 << 24) && "Bit width doesn't fit in bitfield"); - for (unsigned i = 0, e = Alignments.size(); i != e; ++i) { - if (Alignments[i].AlignType == align_type && - Alignments[i].TypeBitWidth == bit_width) { - // Update the abi, preferred alignments. - Alignments[i].ABIAlign = abi_align; - Alignments[i].PrefAlign = pref_align; - return; - } - } - - Alignments.push_back(TargetAlignElem::get(align_type, abi_align, - pref_align, bit_width)); -} - -/// 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, - 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; - for (unsigned i = 0, e = Alignments.size(); i != e; ++i) { - if (Alignments[i].AlignType == AlignType && - Alignments[i].TypeBitWidth == BitWidth) - return ABIInfo ? Alignments[i].ABIAlign : Alignments[i].PrefAlign; - - // The best match so far depends on what we're looking for. - if (AlignType == INTEGER_ALIGN && - Alignments[i].AlignType == INTEGER_ALIGN) { - // The "best match" for integers is the smallest size that is larger than - // the BitWidth requested. - if (Alignments[i].TypeBitWidth > BitWidth && (BestMatchIdx == -1 || - Alignments[i].TypeBitWidth < Alignments[BestMatchIdx].TypeBitWidth)) - BestMatchIdx = i; - // However, if there isn't one that's larger, then we must use the - // largest one we have (see below) - if (LargestInt == -1 || - Alignments[i].TypeBitWidth > Alignments[LargestInt].TypeBitWidth) - LargestInt = i; - } - } - - // Okay, we didn't find an exact solution. Fall back here depending on what - // is being looked for. - 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!"); - - // By default, use natural alignment for vector types. This is consistent - // with what clang and llvm-gcc do. - unsigned Align = getTypeAllocSize(cast(Ty)->getElementType()); - Align *= cast(Ty)->getNumElements(); - // If the alignment is not a power of 2, round up to the next power of 2. - // This happens for non-power-of-2 length vectors. - if (Align & (Align-1)) - Align = NextPowerOf2(Align); - return Align; - } - } - - // Since we got a "best match" index, just return it. - return ABIInfo ? Alignments[BestMatchIdx].ABIAlign - : Alignments[BestMatchIdx].PrefAlign; -} - -namespace { - -class StructLayoutMap { - typedef DenseMap LayoutInfoTy; - LayoutInfoTy LayoutInfo; - -public: - virtual ~StructLayoutMap() { - // Remove any layouts. - for (LayoutInfoTy::iterator I = LayoutInfo.begin(), E = LayoutInfo.end(); - I != E; ++I) { - StructLayout *Value = I->second; - Value->~StructLayout(); - free(Value); - } - } - - StructLayout *&operator[](StructType *STy) { - return LayoutInfo[STy]; - } - - // for debugging... - virtual void dump() const {} -}; - -} // end anonymous namespace - -TargetData::~TargetData() { - delete static_cast(LayoutMap); -} - -const StructLayout *TargetData::getStructLayout(StructType *Ty) const { - if (!LayoutMap) - LayoutMap = new StructLayoutMap(); - - StructLayoutMap *STM = static_cast(LayoutMap); - StructLayout *&SL = (*STM)[Ty]; - if (SL) return SL; - - // 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)); - - // Set SL before calling StructLayout's ctor. The ctor could cause other - // entries to be added to TheMap, invalidating our reference. - SL = L; - - new (L) StructLayout(Ty, *this); - - return L; -} - -std::string TargetData::getStringRepresentation() const { - std::string Result; - raw_string_ostream OS(Result); - - OS << (LittleEndian ? "e" : "E") - << "-p:" << PointerMemSize*8 << ':' << PointerABIAlign*8 - << ':' << PointerPrefAlign*8 - << "-S" << StackNaturalAlign*8; - - for (unsigned i = 0, e = Alignments.size(); i != e; ++i) { - const TargetAlignElem &AI = Alignments[i]; - OS << '-' << (char)AI.AlignType << AI.TypeBitWidth << ':' - << AI.ABIAlign*8 << ':' << AI.PrefAlign*8; - } - - if (!LegalIntWidths.empty()) { - OS << "-n" << (unsigned)LegalIntWidths[0]; - - for (unsigned i = 1, e = LegalIntWidths.size(); i != e; ++i) - OS << ':' << (unsigned)LegalIntWidths[i]; - } - return OS.str(); -} - - -uint64_t TargetData::getTypeSizeInBits(Type *Ty) const { - assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!"); - switch (Ty->getTypeID()) { - case Type::LabelTyID: - case Type::PointerTyID: - return getPointerSizeInBits(); - case Type::ArrayTyID: { - ArrayType *ATy = cast(Ty); - return getTypeAllocSizeInBits(ATy->getElementType())*ATy->getNumElements(); - } - case Type::StructTyID: - // Get the layout annotation... which is lazily created on demand. - return getStructLayout(cast(Ty))->getSizeInBits(); - case Type::IntegerTyID: - return cast(Ty)->getBitWidth(); - case Type::VoidTyID: - return 8; - case Type::HalfTyID: - return 16; - case Type::FloatTyID: - return 32; - case Type::DoubleTyID: - case Type::X86_MMXTyID: - return 64; - case Type::PPC_FP128TyID: - case Type::FP128TyID: - return 128; - // In memory objects this is always aligned to a higher boundary, but - // only 80 bits contain information. - case Type::X86_FP80TyID: - return 80; - case Type::VectorTyID: - return cast(Ty)->getBitWidth(); - default: - llvm_unreachable("TargetData::getTypeSizeInBits(): Unsupported type"); - } -} - -/*! - \param abi_or_pref Flag that determines which alignment is returned. true - returns the ABI alignment, false returns the preferred alignment. - \param Ty The underlying type for which alignment is determined. - - Get the ABI (\a abi_or_pref == true) or preferred alignment (\a abi_or_pref - == false) for the requested type \a Ty. - */ -unsigned TargetData::getAlignment(Type *Ty, bool abi_or_pref) const { - int AlignType = -1; - - assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!"); - switch (Ty->getTypeID()) { - // Early escape for the non-numeric types. - case Type::LabelTyID: - case Type::PointerTyID: - return (abi_or_pref - ? getPointerABIAlignment() - : 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); - return std::max(Align, Layout->getAlignment()); - } - case Type::IntegerTyID: - case Type::VoidTyID: - AlignType = INTEGER_ALIGN; - break; - case Type::HalfTyID: - case Type::FloatTyID: - case Type::DoubleTyID: - // PPC_FP128TyID and FP128TyID have different data contents, but the - // same size and alignment, so they look the same here. - case Type::PPC_FP128TyID: - case Type::FP128TyID: - case Type::X86_FP80TyID: - AlignType = FLOAT_ALIGN; - break; - case Type::X86_MMXTyID: - case Type::VectorTyID: - AlignType = VECTOR_ALIGN; - break; - default: - llvm_unreachable("Bad type for getAlignment!!!"); - } - - return getAlignmentInfo((AlignTypeEnum)AlignType, getTypeSizeInBits(Ty), - abi_or_pref, Ty); -} - -unsigned TargetData::getABITypeAlignment(Type *Ty) const { - return getAlignment(Ty, true); -} - -/// getABIIntegerTypeAlignment - Return the minimum ABI-required alignment for -/// an integer type of the specified bitwidth. -unsigned TargetData::getABIIntegerTypeAlignment(unsigned BitWidth) const { - return getAlignmentInfo(INTEGER_ALIGN, BitWidth, true, 0); -} - - -unsigned TargetData::getCallFrameTypeAlignment(Type *Ty) const { - for (unsigned i = 0, e = Alignments.size(); i != e; ++i) - if (Alignments[i].AlignType == STACK_ALIGN) - return Alignments[i].ABIAlign; - - return getABITypeAlignment(Ty); -} - -unsigned TargetData::getPrefTypeAlignment(Type *Ty) const { - return getAlignment(Ty, false); -} - -unsigned TargetData::getPreferredTypeAlignmentShift(Type *Ty) const { - unsigned Align = getPrefTypeAlignment(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. -IntegerType *TargetData::getIntPtrType(LLVMContext &C) const { - return IntegerType::get(C, getPointerSizeInBits()); -} - - -uint64_t TargetData::getIndexedOffset(Type *ptrTy, - ArrayRef Indices) const { - Type *Ty = ptrTy; - assert(Ty->isPointerTy() && "Illegal argument for getIndexedOffset()"); - uint64_t Result = 0; - - generic_gep_type_iterator - TI = gep_type_begin(ptrTy, Indices); - for (unsigned CurIDX = 0, EndIDX = Indices.size(); CurIDX != EndIDX; - ++CurIDX, ++TI) { - if (StructType *STy = dyn_cast(*TI)) { - assert(Indices[CurIDX]->getType() == - Type::getInt32Ty(ptrTy->getContext()) && - "Illegal struct idx"); - unsigned FieldNo = cast(Indices[CurIDX])->getZExtValue(); - - // Get structure layout information... - const StructLayout *Layout = getStructLayout(STy); - - // Add in the offset, as calculated by the structure layout info... - Result += Layout->getElementOffset(FieldNo); - - // Update Ty to refer to current element - Ty = STy->getElementType(FieldNo); - } else { - // Update Ty to refer to current element - Ty = cast(Ty)->getElementType(); - - // Get the array index and the size of each array element. - if (int64_t arrayIdx = cast(Indices[CurIDX])->getSExtValue()) - Result += (uint64_t)arrayIdx * getTypeAllocSize(Ty); - } - } - - return Result; -} - -/// 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 { - Type *ElemType = GV->getType()->getElementType(); - unsigned Alignment = getPrefTypeAlignment(ElemType); - unsigned GVAlignment = GV->getAlignment(); - if (GVAlignment >= Alignment) { - Alignment = GVAlignment; - } else if (GVAlignment != 0) { - Alignment = std::max(GVAlignment, getABITypeAlignment(ElemType)); - } - - if (GV->hasInitializer() && GVAlignment == 0) { - 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 = 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)); -}