X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=include%2Fllvm%2FTarget%2FTargetData.h;h=f8ea64b4ea66b43b53544d01acb100c67770aa9d;hp=b51b519fb6d047d8824b07a39b1b60a5d104d18c;hb=9085750d3126618ab1b3a4104c34bc504f8b09f4;hpb=f452207d202618f92cbc04bcc6251ecae0eb6d61 diff --git a/include/llvm/Target/TargetData.h b/include/llvm/Target/TargetData.h index b51b519fb6d..f8ea64b4ea6 100644 --- a/include/llvm/Target/TargetData.h +++ b/include/llvm/Target/TargetData.h @@ -2,8 +2,8 @@ // // 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 is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -22,6 +22,7 @@ #include "llvm/Pass.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/ADT/SmallVector.h" #include @@ -29,16 +30,19 @@ namespace llvm { class Value; class Type; +class IntegerType; class StructType; class StructLayout; class GlobalVariable; +class LLVMContext; /// 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 + AGGREGATE_ALIGN = 'a', ///< Aggregate alignment + STACK_ALIGN = 's' ///< Stack objects alignment }; /// Target alignment element. /// @@ -87,11 +91,14 @@ private: */ static const TargetAlignElem InvalidAlignmentElem; + // Opaque pointer for the StructType -> StructLayout map. + mutable void* LayoutMap; + //! Set/initialize target alignments void setAlignment(AlignTypeEnum align_type, unsigned char abi_align, unsigned char pref_align, uint32_t bit_width); unsigned getAlignmentInfo(AlignTypeEnum align_type, uint32_t bit_width, - bool ABIAlign) const; + bool ABIAlign, const Type *Ty) const; //! Internal helper method that returns requested alignment for type. unsigned char getAlignment(const Type *Ty, bool abi_or_pref) const; @@ -108,35 +115,35 @@ public: /// /// @note This has to exist, because this is a pass, but it should never be /// used. - TargetData() : ImmutablePass((intptr_t)&ID) { - assert(0 && "ERROR: Bad TargetData ctor used. " - "Tool did not specify a TargetData to use?"); - abort(); + TargetData() : ImmutablePass(&ID) { + llvm_report_error("Bad TargetData ctor used. " + "Tool did not specify a TargetData to use?"); } - + /// Constructs a TargetData from a specification string. See init(). - explicit TargetData(const std::string &TargetDescription) - : ImmutablePass((intptr_t)&ID) { + explicit TargetData(const std::string &TargetDescription) + : ImmutablePass(&ID) { init(TargetDescription); } /// Initialize target data from properties stored in the module. explicit TargetData(const Module *M); - TargetData(const TargetData &TD) : - ImmutablePass((intptr_t)&ID), + TargetData(const TargetData &TD) : + ImmutablePass(&ID), LittleEndian(TD.isLittleEndian()), PointerMemSize(TD.PointerMemSize), PointerABIAlign(TD.PointerABIAlign), PointerPrefAlign(TD.PointerPrefAlign), - Alignments(TD.Alignments) + Alignments(TD.Alignments), + LayoutMap(0) { } ~TargetData(); // Not virtual, do not subclass this class //! Parse a target data layout string and initialize TargetData alignments. void init(const std::string &TargetDescription); - + /// Target endianness... bool isLittleEndian() const { return LittleEndian; } bool isBigEndian() const { return !LittleEndian; } @@ -154,20 +161,69 @@ public: /// Target pointer size, in bits unsigned char getPointerSizeInBits() const { return 8*PointerMemSize; } - /// getTypeSize - Return the number of bytes necessary to hold the specified - /// type. - uint64_t getTypeSize(const Type *Ty) const; + /// 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. + /// specified type. For example, returns 36 for i36 and 80 for x86_fp80. uint64_t getTypeSizeInBits(const 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(const 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(const 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(const 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(const Type* Ty) const { + return 8*getTypeAllocSize(Ty); + } + /// getABITypeAlignment - Return the minimum ABI-required alignment for the /// specified type. unsigned char getABITypeAlignment(const Type *Ty) const; + /// getCallFrameTypeAlignment - Return the minimum ABI-required alignment + /// for the specified type when it is part of a call frame. + unsigned char getCallFrameTypeAlignment(const Type *Ty) const; + + /// getPrefTypeAlignment - Return the preferred stack/global alignment for - /// the specified type. + /// the specified type. This is always at least as good as the ABI alignment. unsigned char getPrefTypeAlignment(const Type *Ty) const; /// getPreferredTypeAlignmentShift - Return the preferred alignment for the @@ -178,30 +234,45 @@ public: /// getIntPtrType - Return an unsigned integer type that is the same size or /// greater to the host pointer size. /// - const Type *getIntPtrType() const; + const 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. + /// getIndexedOffset - return the offset from the beginning of the type for + /// the specified indices. This is used to implement getelementptr. /// uint64_t getIndexedOffset(const Type *Ty, Value* const* Indices, unsigned NumIndices) 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(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 InvalidateStructLayoutInfo(const 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); + } + static char ID; // Pass identification, replacement for typeid }; @@ -218,12 +289,16 @@ public: uint64_t getSizeInBytes() const { return StructSize; } - + + uint64_t getSizeInBits() const { + return 8*StructSize; + } + unsigned getAlignment() const { return StructAlignment; } - - /// getElementContainingOffset - Given a valid offset into the structure, + + /// getElementContainingOffset - Given a valid byte offset into the structure, /// return the structure index that contains it. /// unsigned getElementContainingOffset(uint64_t Offset) const; @@ -232,7 +307,11 @@ public: 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(const StructType *ST, const TargetData &TD);