LLVM API Documentation
00001 //===-- llvm/Target/TargetData.h - Data size & alignment info ---*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines target properties related to datatype size/offset/alignment 00011 // information. It uses lazy annotations to cache information about how 00012 // structure types are laid out and used. 00013 // 00014 // This structure should be created once, filled in if the defaults are not 00015 // correct and then passed around by const&. None of the members functions 00016 // require modification to the object. 00017 // 00018 //===----------------------------------------------------------------------===// 00019 00020 #ifndef LLVM_TARGET_TARGETDATA_H 00021 #define LLVM_TARGET_TARGETDATA_H 00022 00023 #include "llvm/Pass.h" 00024 #include "llvm/Support/DataTypes.h" 00025 #include "llvm/ADT/SmallVector.h" 00026 #include <string> 00027 00028 namespace llvm { 00029 00030 class Value; 00031 class Type; 00032 class StructType; 00033 class StructLayout; 00034 class GlobalVariable; 00035 00036 /// Enum used to categorize the alignment types stored by TargetAlignElem 00037 enum AlignTypeEnum { 00038 INTEGER_ALIGN = 'i', ///< Integer type alignment 00039 VECTOR_ALIGN = 'v', ///< Vector type alignment 00040 FLOAT_ALIGN = 'f', ///< Floating point type alignment 00041 AGGREGATE_ALIGN = 'a', ///< Aggregate alignment 00042 STACK_ALIGN = 's' ///< Stack objects alignment 00043 }; 00044 /// Target alignment element. 00045 /// 00046 /// Stores the alignment data associated with a given alignment type (pointer, 00047 /// integer, vector, float) and type bit width. 00048 /// 00049 /// @note The unusual order of elements in the structure attempts to reduce 00050 /// padding and make the structure slightly more cache friendly. 00051 struct TargetAlignElem { 00052 AlignTypeEnum AlignType : 8; //< Alignment type (AlignTypeEnum) 00053 unsigned char ABIAlign; //< ABI alignment for this type/bitw 00054 unsigned char PrefAlign; //< Pref. alignment for this type/bitw 00055 uint32_t TypeBitWidth; //< Type bit width 00056 00057 /// Initializer 00058 static TargetAlignElem get(AlignTypeEnum align_type, unsigned char abi_align, 00059 unsigned char pref_align, uint32_t bit_width); 00060 /// Equality predicate 00061 bool operator==(const TargetAlignElem &rhs) const; 00062 /// output stream operator 00063 std::ostream &dump(std::ostream &os) const; 00064 }; 00065 00066 class TargetData : public ImmutablePass { 00067 private: 00068 bool LittleEndian; ///< Defaults to false 00069 unsigned char PointerMemSize; ///< Pointer size in bytes 00070 unsigned char PointerABIAlign; ///< Pointer ABI alignment 00071 unsigned char PointerPrefAlign; ///< Pointer preferred alignment 00072 00073 //! Where the primitive type alignment data is stored. 00074 /*! 00075 @sa init(). 00076 @note Could support multiple size pointer alignments, e.g., 32-bit pointers 00077 vs. 64-bit pointers by extending TargetAlignment, but for now, we don't. 00078 */ 00079 SmallVector<TargetAlignElem, 16> Alignments; 00080 //! Alignment iterator shorthand 00081 typedef SmallVector<TargetAlignElem, 16>::iterator align_iterator; 00082 //! Constant alignment iterator shorthand 00083 typedef SmallVector<TargetAlignElem, 16>::const_iterator align_const_iterator; 00084 //! Invalid alignment. 00085 /*! 00086 This member is a signal that a requested alignment type and bit width were 00087 not found in the SmallVector. 00088 */ 00089 static const TargetAlignElem InvalidAlignmentElem; 00090 00091 //! Set/initialize target alignments 00092 void setAlignment(AlignTypeEnum align_type, unsigned char abi_align, 00093 unsigned char pref_align, uint32_t bit_width); 00094 unsigned getAlignmentInfo(AlignTypeEnum align_type, uint32_t bit_width, 00095 bool ABIAlign, const Type *Ty) const; 00096 //! Internal helper method that returns requested alignment for type. 00097 unsigned char getAlignment(const Type *Ty, bool abi_or_pref) const; 00098 00099 /// Valid alignment predicate. 00100 /// 00101 /// Predicate that tests a TargetAlignElem reference returned by get() against 00102 /// InvalidAlignmentElem. 00103 inline bool validAlignment(const TargetAlignElem &align) const { 00104 return (&align != &InvalidAlignmentElem); 00105 } 00106 00107 public: 00108 /// Default ctor. 00109 /// 00110 /// @note This has to exist, because this is a pass, but it should never be 00111 /// used. 00112 TargetData() : ImmutablePass(intptr_t(&ID)) { 00113 assert(0 && "ERROR: Bad TargetData ctor used. " 00114 "Tool did not specify a TargetData to use?"); 00115 abort(); 00116 } 00117 00118 /// Constructs a TargetData from a specification string. See init(). 00119 explicit TargetData(const std::string &TargetDescription) 00120 : ImmutablePass(intptr_t(&ID)) { 00121 init(TargetDescription); 00122 } 00123 00124 /// Initialize target data from properties stored in the module. 00125 explicit TargetData(const Module *M); 00126 00127 TargetData(const TargetData &TD) : 00128 ImmutablePass(intptr_t(&ID)), 00129 LittleEndian(TD.isLittleEndian()), 00130 PointerMemSize(TD.PointerMemSize), 00131 PointerABIAlign(TD.PointerABIAlign), 00132 PointerPrefAlign(TD.PointerPrefAlign), 00133 Alignments(TD.Alignments) 00134 { } 00135 00136 ~TargetData(); // Not virtual, do not subclass this class 00137 00138 //! Parse a target data layout string and initialize TargetData alignments. 00139 void init(const std::string &TargetDescription); 00140 00141 /// Target endianness... 00142 bool isLittleEndian() const { return LittleEndian; } 00143 bool isBigEndian() const { return !LittleEndian; } 00144 00145 /// getStringRepresentation - Return the string representation of the 00146 /// TargetData. This representation is in the same format accepted by the 00147 /// string constructor above. 00148 std::string getStringRepresentation() const; 00149 /// Target pointer alignment 00150 unsigned char getPointerABIAlignment() const { return PointerABIAlign; } 00151 /// Return target's alignment for stack-based pointers 00152 unsigned char getPointerPrefAlignment() const { return PointerPrefAlign; } 00153 /// Target pointer size 00154 unsigned char getPointerSize() const { return PointerMemSize; } 00155 /// Target pointer size, in bits 00156 unsigned char getPointerSizeInBits() const { return 8*PointerMemSize; } 00157 00158 /// getTypeSizeInBits - Return the number of bits necessary to hold the 00159 /// specified type. For example, returns 36 for i36 and 80 for x86_fp80. 00160 uint64_t getTypeSizeInBits(const Type* Ty) const; 00161 00162 /// getTypeStoreSize - Return the maximum number of bytes that may be 00163 /// overwritten by storing the specified type. For example, returns 5 00164 /// for i36 and 10 for x86_fp80. 00165 uint64_t getTypeStoreSize(const Type *Ty) const { 00166 return (getTypeSizeInBits(Ty)+7)/8; 00167 } 00168 00169 /// getTypeStoreSizeInBits - Return the maximum number of bits that may be 00170 /// overwritten by storing the specified type; always a multiple of 8. For 00171 /// example, returns 40 for i36 and 80 for x86_fp80. 00172 uint64_t getTypeStoreSizeInBits(const Type *Ty) const { 00173 return 8*getTypeStoreSize(Ty); 00174 } 00175 00176 /// getTypePaddedSize - Return the offset in bytes between successive objects 00177 /// of the specified type, including alignment padding. This is the amount 00178 /// that alloca reserves for this type. For example, returns 12 or 16 for 00179 /// x86_fp80, depending on alignment. 00180 uint64_t getTypePaddedSize(const Type* Ty) const { 00181 // Round up to the next alignment boundary. 00182 return RoundUpAlignment(getTypeStoreSize(Ty), getABITypeAlignment(Ty)); 00183 } 00184 00185 /// getTypePaddedSizeInBits - Return the offset in bits between successive 00186 /// objects of the specified type, including alignment padding; always a 00187 /// multiple of 8. This is the amount that alloca reserves for this type. 00188 /// For example, returns 96 or 128 for x86_fp80, depending on alignment. 00189 uint64_t getTypePaddedSizeInBits(const Type* Ty) const { 00190 return 8*getTypePaddedSize(Ty); 00191 } 00192 00193 /// getABITypeAlignment - Return the minimum ABI-required alignment for the 00194 /// specified type. 00195 unsigned char getABITypeAlignment(const Type *Ty) const; 00196 00197 /// getCallFrameTypeAlignment - Return the minimum ABI-required alignment 00198 /// for the specified type when it is part of a call frame. 00199 unsigned char getCallFrameTypeAlignment(const Type *Ty) const; 00200 00201 00202 /// getPrefTypeAlignment - Return the preferred stack/global alignment for 00203 /// the specified type. This is always at least as good as the ABI alignment. 00204 unsigned char getPrefTypeAlignment(const Type *Ty) const; 00205 00206 /// getPreferredTypeAlignmentShift - Return the preferred alignment for the 00207 /// specified type, returned as log2 of the value (a shift amount). 00208 /// 00209 unsigned char getPreferredTypeAlignmentShift(const Type *Ty) const; 00210 00211 /// getIntPtrType - Return an unsigned integer type that is the same size or 00212 /// greater to the host pointer size. 00213 /// 00214 const Type *getIntPtrType() const; 00215 00216 /// getIndexedOffset - return the offset from the beginning of the type for 00217 /// the specified indices. This is used to implement getelementptr. 00218 /// 00219 uint64_t getIndexedOffset(const Type *Ty, 00220 Value* const* Indices, unsigned NumIndices) const; 00221 00222 /// getStructLayout - Return a StructLayout object, indicating the alignment 00223 /// of the struct, its size, and the offsets of its fields. Note that this 00224 /// information is lazily cached. 00225 const StructLayout *getStructLayout(const StructType *Ty) const; 00226 00227 /// InvalidateStructLayoutInfo - TargetData speculatively caches StructLayout 00228 /// objects. If a TargetData object is alive when types are being refined and 00229 /// removed, this method must be called whenever a StructType is removed to 00230 /// avoid a dangling pointer in this cache. 00231 void InvalidateStructLayoutInfo(const StructType *Ty) const; 00232 00233 /// getPreferredAlignment - Return the preferred alignment of the specified 00234 /// global. This includes an explicitly requested alignment (if the global 00235 /// has one). 00236 unsigned getPreferredAlignment(const GlobalVariable *GV) const; 00237 00238 /// getPreferredAlignmentLog - Return the preferred alignment of the 00239 /// specified global, returned in log form. This includes an explicitly 00240 /// requested alignment (if the global has one). 00241 unsigned getPreferredAlignmentLog(const GlobalVariable *GV) const; 00242 00243 /// RoundUpAlignment - Round the specified value up to the next alignment 00244 /// boundary specified by Alignment. For example, 7 rounded up to an 00245 /// alignment boundary of 4 is 8. 8 rounded up to the alignment boundary of 4 00246 /// is 8 because it is already aligned. 00247 template <typename UIntTy> 00248 static UIntTy RoundUpAlignment(UIntTy Val, unsigned Alignment) { 00249 assert((Alignment & (Alignment-1)) == 0 && "Alignment must be power of 2!"); 00250 return (Val + (Alignment-1)) & ~UIntTy(Alignment-1); 00251 } 00252 00253 static char ID; // Pass identification, replacement for typeid 00254 }; 00255 00256 /// StructLayout - used to lazily calculate structure layout information for a 00257 /// target machine, based on the TargetData structure. 00258 /// 00259 class StructLayout { 00260 uint64_t StructSize; 00261 unsigned StructAlignment; 00262 unsigned NumElements; 00263 uint64_t MemberOffsets[1]; // variable sized array! 00264 public: 00265 00266 uint64_t getSizeInBytes() const { 00267 return StructSize; 00268 } 00269 00270 uint64_t getSizeInBits() const { 00271 return 8*StructSize; 00272 } 00273 00274 unsigned getAlignment() const { 00275 return StructAlignment; 00276 } 00277 00278 /// getElementContainingOffset - Given a valid offset into the structure, 00279 /// return the structure index that contains it. 00280 /// 00281 unsigned getElementContainingOffset(uint64_t Offset) const; 00282 00283 uint64_t getElementOffset(unsigned Idx) const { 00284 assert(Idx < NumElements && "Invalid element idx!"); 00285 return MemberOffsets[Idx]; 00286 } 00287 00288 uint64_t getElementOffsetInBits(unsigned Idx) const { 00289 return getElementOffset(Idx)*8; 00290 } 00291 00292 private: 00293 friend class TargetData; // Only TargetData can create this class 00294 StructLayout(const StructType *ST, const TargetData &TD); 00295 }; 00296 00297 } // End llvm namespace 00298 00299 #endif