TargetData.h revision 8d730fbde54b7ac9809fc12852c2a8d30f5bec3d
1//===-- llvm/Target/TargetData.h - Data size & alignment info ---*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines target properties related to datatype size/offset/alignment 11// information. It uses lazy annotations to cache information about how 12// structure types are laid out and used. 13// 14// This structure should be created once, filled in if the defaults are not 15// correct and then passed around by const&. None of the members functions 16// require modification to the object. 17// 18//===----------------------------------------------------------------------===// 19 20#ifndef LLVM_TARGET_TARGETDATA_H 21#define LLVM_TARGET_TARGETDATA_H 22 23#include "llvm/Pass.h" 24#include "llvm/Support/DataTypes.h" 25#include "llvm/ADT/SmallVector.h" 26#include <string> 27 28namespace llvm { 29 30class Value; 31class Type; 32class IntegerType; 33class StructType; 34class StructLayout; 35class GlobalVariable; 36 37/// Enum used to categorize the alignment types stored by TargetAlignElem 38enum AlignTypeEnum { 39 INTEGER_ALIGN = 'i', ///< Integer type alignment 40 VECTOR_ALIGN = 'v', ///< Vector type alignment 41 FLOAT_ALIGN = 'f', ///< Floating point type alignment 42 AGGREGATE_ALIGN = 'a', ///< Aggregate alignment 43 STACK_ALIGN = 's' ///< Stack objects alignment 44}; 45/// Target alignment element. 46/// 47/// Stores the alignment data associated with a given alignment type (pointer, 48/// integer, vector, float) and type bit width. 49/// 50/// @note The unusual order of elements in the structure attempts to reduce 51/// padding and make the structure slightly more cache friendly. 52struct TargetAlignElem { 53 AlignTypeEnum AlignType : 8; //< Alignment type (AlignTypeEnum) 54 unsigned char ABIAlign; //< ABI alignment for this type/bitw 55 unsigned char PrefAlign; //< Pref. alignment for this type/bitw 56 uint32_t TypeBitWidth; //< Type bit width 57 58 /// Initializer 59 static TargetAlignElem get(AlignTypeEnum align_type, unsigned char abi_align, 60 unsigned char pref_align, uint32_t bit_width); 61 /// Equality predicate 62 bool operator==(const TargetAlignElem &rhs) const; 63 /// output stream operator 64 std::ostream &dump(std::ostream &os) const; 65}; 66 67class TargetData : public ImmutablePass { 68private: 69 bool LittleEndian; ///< Defaults to false 70 unsigned char PointerMemSize; ///< Pointer size in bytes 71 unsigned char PointerABIAlign; ///< Pointer ABI alignment 72 unsigned char PointerPrefAlign; ///< Pointer preferred alignment 73 74 //! Where the primitive type alignment data is stored. 75 /*! 76 @sa init(). 77 @note Could support multiple size pointer alignments, e.g., 32-bit pointers 78 vs. 64-bit pointers by extending TargetAlignment, but for now, we don't. 79 */ 80 SmallVector<TargetAlignElem, 16> Alignments; 81 //! Alignment iterator shorthand 82 typedef SmallVector<TargetAlignElem, 16>::iterator align_iterator; 83 //! Constant alignment iterator shorthand 84 typedef SmallVector<TargetAlignElem, 16>::const_iterator align_const_iterator; 85 //! Invalid alignment. 86 /*! 87 This member is a signal that a requested alignment type and bit width were 88 not found in the SmallVector. 89 */ 90 static const TargetAlignElem InvalidAlignmentElem; 91 92 //! Set/initialize target alignments 93 void setAlignment(AlignTypeEnum align_type, unsigned char abi_align, 94 unsigned char pref_align, uint32_t bit_width); 95 unsigned getAlignmentInfo(AlignTypeEnum align_type, uint32_t bit_width, 96 bool ABIAlign, const Type *Ty) const; 97 //! Internal helper method that returns requested alignment for type. 98 unsigned char getAlignment(const Type *Ty, bool abi_or_pref) const; 99 100 /// Valid alignment predicate. 101 /// 102 /// Predicate that tests a TargetAlignElem reference returned by get() against 103 /// InvalidAlignmentElem. 104 inline bool validAlignment(const TargetAlignElem &align) const { 105 return (&align != &InvalidAlignmentElem); 106 } 107 108public: 109 /// Default ctor. 110 /// 111 /// @note This has to exist, because this is a pass, but it should never be 112 /// used. 113 TargetData() : ImmutablePass(&ID) { 114 assert(0 && "ERROR: Bad TargetData ctor used. " 115 "Tool did not specify a TargetData to use?"); 116 abort(); 117 } 118 119 /// Constructs a TargetData from a specification string. See init(). 120 explicit TargetData(const std::string &TargetDescription) 121 : ImmutablePass(&ID) { 122 init(TargetDescription); 123 } 124 125 /// Initialize target data from properties stored in the module. 126 explicit TargetData(const Module *M); 127 128 TargetData(const TargetData &TD) : 129 ImmutablePass(&ID), 130 LittleEndian(TD.isLittleEndian()), 131 PointerMemSize(TD.PointerMemSize), 132 PointerABIAlign(TD.PointerABIAlign), 133 PointerPrefAlign(TD.PointerPrefAlign), 134 Alignments(TD.Alignments) 135 { } 136 137 ~TargetData(); // Not virtual, do not subclass this class 138 139 //! Parse a target data layout string and initialize TargetData alignments. 140 void init(const std::string &TargetDescription); 141 142 /// Target endianness... 143 bool isLittleEndian() const { return LittleEndian; } 144 bool isBigEndian() const { return !LittleEndian; } 145 146 /// getStringRepresentation - Return the string representation of the 147 /// TargetData. This representation is in the same format accepted by the 148 /// string constructor above. 149 std::string getStringRepresentation() const; 150 /// Target pointer alignment 151 unsigned char getPointerABIAlignment() const { return PointerABIAlign; } 152 /// Return target's alignment for stack-based pointers 153 unsigned char getPointerPrefAlignment() const { return PointerPrefAlign; } 154 /// Target pointer size 155 unsigned char getPointerSize() const { return PointerMemSize; } 156 /// Target pointer size, in bits 157 unsigned char getPointerSizeInBits() const { return 8*PointerMemSize; } 158 159 /// Size examples: 160 /// 161 /// Type SizeInBits StoreSizeInBits AllocSizeInBits[*] 162 /// ---- ---------- --------------- --------------- 163 /// i1 1 8 8 164 /// i8 8 8 8 165 /// i19 19 24 32 166 /// i32 32 32 32 167 /// i100 100 104 128 168 /// i128 128 128 128 169 /// Float 32 32 32 170 /// Double 64 64 64 171 /// X86_FP80 80 80 96 172 /// 173 /// [*] The alloc size depends on the alignment, and thus on the target. 174 /// These values are for x86-32 linux. 175 176 /// getTypeSizeInBits - Return the number of bits necessary to hold the 177 /// specified type. For example, returns 36 for i36 and 80 for x86_fp80. 178 uint64_t getTypeSizeInBits(const Type* Ty) const; 179 180 /// getTypeStoreSize - Return the maximum number of bytes that may be 181 /// overwritten by storing the specified type. For example, returns 5 182 /// for i36 and 10 for x86_fp80. 183 uint64_t getTypeStoreSize(const Type *Ty) const { 184 return (getTypeSizeInBits(Ty)+7)/8; 185 } 186 187 /// getTypeStoreSizeInBits - Return the maximum number of bits that may be 188 /// overwritten by storing the specified type; always a multiple of 8. For 189 /// example, returns 40 for i36 and 80 for x86_fp80. 190 uint64_t getTypeStoreSizeInBits(const Type *Ty) const { 191 return 8*getTypeStoreSize(Ty); 192 } 193 194 /// getTypeAllocSize - Return the offset in bytes between successive objects 195 /// of the specified type, including alignment padding. This is the amount 196 /// that alloca reserves for this type. For example, returns 12 or 16 for 197 /// x86_fp80, depending on alignment. 198 uint64_t getTypeAllocSize(const Type* Ty) const { 199 // Round up to the next alignment boundary. 200 return RoundUpAlignment(getTypeStoreSize(Ty), getABITypeAlignment(Ty)); 201 } 202 203 /// getTypeAllocSizeInBits - Return the offset in bits between successive 204 /// objects of the specified type, including alignment padding; always a 205 /// multiple of 8. This is the amount that alloca reserves for this type. 206 /// For example, returns 96 or 128 for x86_fp80, depending on alignment. 207 uint64_t getTypeAllocSizeInBits(const Type* Ty) const { 208 return 8*getTypeAllocSize(Ty); 209 } 210 211 /// getABITypeAlignment - Return the minimum ABI-required alignment for the 212 /// specified type. 213 unsigned char getABITypeAlignment(const Type *Ty) const; 214 215 /// getCallFrameTypeAlignment - Return the minimum ABI-required alignment 216 /// for the specified type when it is part of a call frame. 217 unsigned char getCallFrameTypeAlignment(const Type *Ty) const; 218 219 220 /// getPrefTypeAlignment - Return the preferred stack/global alignment for 221 /// the specified type. This is always at least as good as the ABI alignment. 222 unsigned char getPrefTypeAlignment(const Type *Ty) const; 223 224 /// getPreferredTypeAlignmentShift - Return the preferred alignment for the 225 /// specified type, returned as log2 of the value (a shift amount). 226 /// 227 unsigned char getPreferredTypeAlignmentShift(const Type *Ty) const; 228 229 /// getIntPtrType - Return an unsigned integer type that is the same size or 230 /// greater to the host pointer size. 231 /// 232 const IntegerType *getIntPtrType() const; 233 234 /// getIndexedOffset - return the offset from the beginning of the type for 235 /// the specified indices. This is used to implement getelementptr. 236 /// 237 uint64_t getIndexedOffset(const Type *Ty, 238 Value* const* Indices, unsigned NumIndices) const; 239 240 /// getStructLayout - Return a StructLayout object, indicating the alignment 241 /// of the struct, its size, and the offsets of its fields. Note that this 242 /// information is lazily cached. 243 const StructLayout *getStructLayout(const StructType *Ty) const; 244 245 /// InvalidateStructLayoutInfo - TargetData speculatively caches StructLayout 246 /// objects. If a TargetData object is alive when types are being refined and 247 /// removed, this method must be called whenever a StructType is removed to 248 /// avoid a dangling pointer in this cache. 249 void InvalidateStructLayoutInfo(const StructType *Ty) const; 250 251 /// getPreferredAlignment - Return the preferred alignment of the specified 252 /// global. This includes an explicitly requested alignment (if the global 253 /// has one). 254 unsigned getPreferredAlignment(const GlobalVariable *GV) const; 255 256 /// getPreferredAlignmentLog - Return the preferred alignment of the 257 /// specified global, returned in log form. This includes an explicitly 258 /// requested alignment (if the global has one). 259 unsigned getPreferredAlignmentLog(const GlobalVariable *GV) const; 260 261 /// RoundUpAlignment - Round the specified value up to the next alignment 262 /// boundary specified by Alignment. For example, 7 rounded up to an 263 /// alignment boundary of 4 is 8. 8 rounded up to the alignment boundary of 4 264 /// is 8 because it is already aligned. 265 template <typename UIntTy> 266 static UIntTy RoundUpAlignment(UIntTy Val, unsigned Alignment) { 267 assert((Alignment & (Alignment-1)) == 0 && "Alignment must be power of 2!"); 268 return (Val + (Alignment-1)) & ~UIntTy(Alignment-1); 269 } 270 271 static char ID; // Pass identification, replacement for typeid 272}; 273 274/// StructLayout - used to lazily calculate structure layout information for a 275/// target machine, based on the TargetData structure. 276/// 277class StructLayout { 278 uint64_t StructSize; 279 unsigned StructAlignment; 280 unsigned NumElements; 281 uint64_t MemberOffsets[1]; // variable sized array! 282public: 283 284 uint64_t getSizeInBytes() const { 285 return StructSize; 286 } 287 288 uint64_t getSizeInBits() const { 289 return 8*StructSize; 290 } 291 292 unsigned getAlignment() const { 293 return StructAlignment; 294 } 295 296 /// getElementContainingOffset - Given a valid offset into the structure, 297 /// return the structure index that contains it. 298 /// 299 unsigned getElementContainingOffset(uint64_t Offset) const; 300 301 uint64_t getElementOffset(unsigned Idx) const { 302 assert(Idx < NumElements && "Invalid element idx!"); 303 return MemberOffsets[Idx]; 304 } 305 306 uint64_t getElementOffsetInBits(unsigned Idx) const { 307 return getElementOffset(Idx)*8; 308 } 309 310private: 311 friend class TargetData; // Only TargetData can create this class 312 StructLayout(const StructType *ST, const TargetData &TD); 313}; 314 315} // End llvm namespace 316 317#endif 318