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