]>
Commit | Line | Data |
---|---|---|
970d7e83 | 1 | //===--------- llvm/DataLayout.h - Data size & alignment info ---*- C++ -*-===// |
223e47cc LB |
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 | // | |
970d7e83 | 10 | // This file defines layout properties related to datatype size/offset/alignment |
223e47cc LB |
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 | ||
970d7e83 LB |
20 | #ifndef LLVM_IR_DATALAYOUT_H |
21 | #define LLVM_IR_DATALAYOUT_H | |
223e47cc | 22 | |
970d7e83 | 23 | #include "llvm/ADT/DenseMap.h" |
223e47cc | 24 | #include "llvm/ADT/SmallVector.h" |
1a4d82fc JJ |
25 | #include "llvm/IR/DerivedTypes.h" |
26 | #include "llvm/IR/Type.h" | |
970d7e83 | 27 | #include "llvm/Pass.h" |
223e47cc LB |
28 | #include "llvm/Support/DataTypes.h" |
29 | ||
85aaf69f SL |
30 | // This needs to be outside of the namespace, to avoid conflict with llvm-c |
31 | // decl. | |
1a4d82fc JJ |
32 | typedef struct LLVMOpaqueTargetData *LLVMTargetDataRef; |
33 | ||
223e47cc LB |
34 | namespace llvm { |
35 | ||
36 | class Value; | |
37 | class Type; | |
38 | class IntegerType; | |
39 | class StructType; | |
40 | class StructLayout; | |
1a4d82fc | 41 | class Triple; |
223e47cc LB |
42 | class GlobalVariable; |
43 | class LLVMContext; | |
44 | template<typename T> | |
45 | class ArrayRef; | |
46 | ||
970d7e83 | 47 | /// Enum used to categorize the alignment types stored by LayoutAlignElem |
223e47cc | 48 | enum AlignTypeEnum { |
85aaf69f SL |
49 | INVALID_ALIGN = 0, |
50 | INTEGER_ALIGN = 'i', | |
51 | VECTOR_ALIGN = 'v', | |
52 | FLOAT_ALIGN = 'f', | |
53 | AGGREGATE_ALIGN = 'a' | |
223e47cc LB |
54 | }; |
55 | ||
85aaf69f | 56 | /// \brief Layout alignment element. |
223e47cc | 57 | /// |
970d7e83 LB |
58 | /// Stores the alignment data associated with a given alignment type (integer, |
59 | /// vector, float) and type bit width. | |
223e47cc | 60 | /// |
85aaf69f | 61 | /// \note The unusual order of elements in the structure attempts to reduce |
223e47cc | 62 | /// padding and make the structure slightly more cache friendly. |
970d7e83 | 63 | struct LayoutAlignElem { |
85aaf69f SL |
64 | /// \brief Alignment type from \c AlignTypeEnum |
65 | unsigned AlignType : 8; | |
66 | unsigned TypeBitWidth : 24; | |
67 | unsigned ABIAlign : 16; | |
68 | unsigned PrefAlign : 16; | |
223e47cc | 69 | |
970d7e83 | 70 | static LayoutAlignElem get(AlignTypeEnum align_type, unsigned abi_align, |
223e47cc | 71 | unsigned pref_align, uint32_t bit_width); |
970d7e83 | 72 | bool operator==(const LayoutAlignElem &rhs) const; |
223e47cc LB |
73 | }; |
74 | ||
85aaf69f | 75 | /// \brief Layout pointer alignment element. |
970d7e83 LB |
76 | /// |
77 | /// Stores the alignment data associated with a given pointer and address space. | |
78 | /// | |
85aaf69f | 79 | /// \note The unusual order of elements in the structure attempts to reduce |
970d7e83 LB |
80 | /// padding and make the structure slightly more cache friendly. |
81 | struct PointerAlignElem { | |
85aaf69f SL |
82 | unsigned ABIAlign; |
83 | unsigned PrefAlign; | |
84 | uint32_t TypeByteWidth; | |
85 | uint32_t AddressSpace; | |
970d7e83 LB |
86 | |
87 | /// Initializer | |
1a4d82fc | 88 | static PointerAlignElem get(uint32_t AddressSpace, unsigned ABIAlign, |
85aaf69f | 89 | unsigned PrefAlign, uint32_t TypeByteWidth); |
970d7e83 LB |
90 | bool operator==(const PointerAlignElem &rhs) const; |
91 | }; | |
92 | ||
85aaf69f SL |
93 | /// \brief A parsed version of the target data layout string in and methods for |
94 | /// querying it. | |
95 | /// | |
96 | /// The target data layout string is specified *by the target* - a frontend | |
97 | /// generating LLVM IR is required to generate the right target data for the | |
98 | /// target being codegen'd to. | |
1a4d82fc | 99 | class DataLayout { |
223e47cc | 100 | private: |
85aaf69f SL |
101 | /// Defaults to false. |
102 | bool BigEndian; | |
103 | ||
104 | unsigned StackNaturalAlign; | |
105 | ||
106 | enum ManglingModeT { MM_None, MM_ELF, MM_MachO, MM_WINCOFF, MM_Mips }; | |
1a4d82fc JJ |
107 | ManglingModeT ManglingMode; |
108 | ||
85aaf69f | 109 | SmallVector<unsigned char, 8> LegalIntWidths; |
223e47cc | 110 | |
85aaf69f | 111 | /// \brief Primitive type alignment data. |
970d7e83 | 112 | SmallVector<LayoutAlignElem, 16> Alignments; |
85aaf69f | 113 | |
1a4d82fc JJ |
114 | typedef SmallVector<PointerAlignElem, 8> PointersTy; |
115 | PointersTy Pointers; | |
116 | ||
117 | PointersTy::const_iterator | |
118 | findPointerLowerBound(uint32_t AddressSpace) const { | |
119 | return const_cast<DataLayout *>(this)->findPointerLowerBound(AddressSpace); | |
120 | } | |
121 | ||
122 | PointersTy::iterator findPointerLowerBound(uint32_t AddressSpace); | |
223e47cc | 123 | |
85aaf69f SL |
124 | /// This member is a signal that a requested alignment type and bit width were |
125 | /// not found in the SmallVector. | |
970d7e83 LB |
126 | static const LayoutAlignElem InvalidAlignmentElem; |
127 | ||
85aaf69f SL |
128 | /// This member is a signal that a requested pointer type and bit width were |
129 | /// not found in the DenseSet. | |
970d7e83 | 130 | static const PointerAlignElem InvalidPointerElem; |
223e47cc LB |
131 | |
132 | // The StructType -> StructLayout map. | |
133 | mutable void *LayoutMap; | |
134 | ||
223e47cc LB |
135 | void setAlignment(AlignTypeEnum align_type, unsigned abi_align, |
136 | unsigned pref_align, uint32_t bit_width); | |
137 | unsigned getAlignmentInfo(AlignTypeEnum align_type, uint32_t bit_width, | |
138 | bool ABIAlign, Type *Ty) const; | |
1a4d82fc JJ |
139 | void setPointerAlignment(uint32_t AddrSpace, unsigned ABIAlign, |
140 | unsigned PrefAlign, uint32_t TypeByteWidth); | |
970d7e83 | 141 | |
85aaf69f | 142 | /// Internal helper method that returns requested alignment for type. |
223e47cc LB |
143 | unsigned getAlignment(Type *Ty, bool abi_or_pref) const; |
144 | ||
85aaf69f | 145 | /// \brief Valid alignment predicate. |
223e47cc | 146 | /// |
970d7e83 | 147 | /// Predicate that tests a LayoutAlignElem reference returned by get() against |
223e47cc | 148 | /// InvalidAlignmentElem. |
970d7e83 | 149 | bool validAlignment(const LayoutAlignElem &align) const { |
223e47cc LB |
150 | return &align != &InvalidAlignmentElem; |
151 | } | |
152 | ||
85aaf69f | 153 | /// \brief Valid pointer predicate. |
970d7e83 | 154 | /// |
85aaf69f SL |
155 | /// Predicate that tests a PointerAlignElem reference returned by get() |
156 | /// against \c InvalidPointerElem. | |
970d7e83 LB |
157 | bool validPointer(const PointerAlignElem &align) const { |
158 | return &align != &InvalidPointerElem; | |
159 | } | |
160 | ||
161 | /// Parses a target data specification string. Assert if the string is | |
162 | /// malformed. | |
163 | void parseSpecifier(StringRef LayoutDescription); | |
223e47cc | 164 | |
1a4d82fc JJ |
165 | // Free all internal data structures. |
166 | void clear(); | |
167 | ||
223e47cc | 168 | public: |
1a4d82fc JJ |
169 | /// Constructs a DataLayout from a specification string. See reset(). |
170 | explicit DataLayout(StringRef LayoutDescription) : LayoutMap(nullptr) { | |
171 | reset(LayoutDescription); | |
223e47cc LB |
172 | } |
173 | ||
223e47cc | 174 | /// Initialize target data from properties stored in the module. |
970d7e83 | 175 | explicit DataLayout(const Module *M); |
223e47cc | 176 | |
1a4d82fc | 177 | void init(const Module *M); |
223e47cc | 178 | |
1a4d82fc | 179 | DataLayout(const DataLayout &DL) : LayoutMap(nullptr) { *this = DL; } |
970d7e83 | 180 | |
1a4d82fc JJ |
181 | DataLayout &operator=(const DataLayout &DL) { |
182 | clear(); | |
85aaf69f | 183 | BigEndian = DL.isBigEndian(); |
1a4d82fc JJ |
184 | StackNaturalAlign = DL.StackNaturalAlign; |
185 | ManglingMode = DL.ManglingMode; | |
186 | LegalIntWidths = DL.LegalIntWidths; | |
187 | Alignments = DL.Alignments; | |
188 | Pointers = DL.Pointers; | |
189 | return *this; | |
190 | } | |
223e47cc | 191 | |
1a4d82fc JJ |
192 | bool operator==(const DataLayout &Other) const; |
193 | bool operator!=(const DataLayout &Other) const { return !(*this == Other); } | |
194 | ||
85aaf69f | 195 | ~DataLayout(); // Not virtual, do not subclass this class |
1a4d82fc JJ |
196 | |
197 | /// Parse a data layout string (with fallback to default values). | |
198 | void reset(StringRef LayoutDescription); | |
970d7e83 LB |
199 | |
200 | /// Layout endianness... | |
85aaf69f SL |
201 | bool isLittleEndian() const { return !BigEndian; } |
202 | bool isBigEndian() const { return BigEndian; } | |
223e47cc | 203 | |
85aaf69f SL |
204 | /// \brief Returns the string representation of the DataLayout. |
205 | /// | |
206 | /// This representation is in the same format accepted by the string | |
207 | /// constructor above. | |
223e47cc LB |
208 | std::string getStringRepresentation() const; |
209 | ||
85aaf69f SL |
210 | /// \brief Returns true if the specified type is known to be a native integer |
211 | /// type supported by the CPU. | |
223e47cc | 212 | /// |
85aaf69f SL |
213 | /// For example, i64 is not native on most 32-bit CPUs and i37 is not native |
214 | /// on any known one. This returns false if the integer width is not legal. | |
223e47cc | 215 | /// |
85aaf69f | 216 | /// The width is specified in bits. |
223e47cc | 217 | bool isLegalInteger(unsigned Width) const { |
1a4d82fc JJ |
218 | for (unsigned LegalIntWidth : LegalIntWidths) |
219 | if (LegalIntWidth == Width) | |
223e47cc LB |
220 | return true; |
221 | return false; | |
222 | } | |
223 | ||
85aaf69f | 224 | bool isIllegalInteger(unsigned Width) const { return !isLegalInteger(Width); } |
223e47cc LB |
225 | |
226 | /// Returns true if the given alignment exceeds the natural stack alignment. | |
227 | bool exceedsNaturalStackAlignment(unsigned Align) const { | |
228 | return (StackNaturalAlign != 0) && (Align > StackNaturalAlign); | |
229 | } | |
230 | ||
85aaf69f SL |
231 | unsigned getStackAlignment() const { return StackNaturalAlign; } |
232 | ||
1a4d82fc JJ |
233 | bool hasMicrosoftFastStdCallMangling() const { |
234 | return ManglingMode == MM_WINCOFF; | |
235 | } | |
236 | ||
85aaf69f | 237 | bool hasLinkerPrivateGlobalPrefix() const { return ManglingMode == MM_MachO; } |
1a4d82fc JJ |
238 | |
239 | const char *getLinkerPrivateGlobalPrefix() const { | |
240 | if (ManglingMode == MM_MachO) | |
241 | return "l"; | |
242 | return getPrivateGlobalPrefix(); | |
243 | } | |
244 | ||
245 | char getGlobalPrefix() const { | |
246 | switch (ManglingMode) { | |
247 | case MM_None: | |
248 | case MM_ELF: | |
249 | case MM_Mips: | |
250 | return '\0'; | |
251 | case MM_MachO: | |
252 | case MM_WINCOFF: | |
253 | return '_'; | |
254 | } | |
255 | llvm_unreachable("invalid mangling mode"); | |
256 | } | |
257 | ||
258 | const char *getPrivateGlobalPrefix() const { | |
259 | switch (ManglingMode) { | |
260 | case MM_None: | |
261 | return ""; | |
262 | case MM_ELF: | |
263 | return ".L"; | |
264 | case MM_Mips: | |
265 | return "$"; | |
266 | case MM_MachO: | |
267 | case MM_WINCOFF: | |
268 | return "L"; | |
269 | } | |
270 | llvm_unreachable("invalid mangling mode"); | |
271 | } | |
272 | ||
273 | static const char *getManglingComponent(const Triple &T); | |
274 | ||
85aaf69f SL |
275 | /// \brief Returns true if the specified type fits in a native integer type |
276 | /// supported by the CPU. | |
277 | /// | |
278 | /// For example, if the CPU only supports i32 as a native integer type, then | |
279 | /// i27 fits in a legal integer type but i45 does not. | |
223e47cc | 280 | bool fitsInLegalInteger(unsigned Width) const { |
1a4d82fc JJ |
281 | for (unsigned LegalIntWidth : LegalIntWidths) |
282 | if (Width <= LegalIntWidth) | |
223e47cc LB |
283 | return true; |
284 | return false; | |
285 | } | |
286 | ||
970d7e83 LB |
287 | /// Layout pointer alignment |
288 | /// FIXME: The defaults need to be removed once all of | |
289 | /// the backends/clients are updated. | |
1a4d82fc JJ |
290 | unsigned getPointerABIAlignment(unsigned AS = 0) const; |
291 | ||
223e47cc | 292 | /// Return target's alignment for stack-based pointers |
970d7e83 LB |
293 | /// FIXME: The defaults need to be removed once all of |
294 | /// the backends/clients are updated. | |
1a4d82fc JJ |
295 | unsigned getPointerPrefAlignment(unsigned AS = 0) const; |
296 | ||
970d7e83 LB |
297 | /// Layout pointer size |
298 | /// FIXME: The defaults need to be removed once all of | |
299 | /// the backends/clients are updated. | |
1a4d82fc JJ |
300 | unsigned getPointerSize(unsigned AS = 0) const; |
301 | ||
970d7e83 LB |
302 | /// Layout pointer size, in bits |
303 | /// FIXME: The defaults need to be removed once all of | |
304 | /// the backends/clients are updated. | |
1a4d82fc | 305 | unsigned getPointerSizeInBits(unsigned AS = 0) const { |
970d7e83 LB |
306 | return getPointerSize(AS) * 8; |
307 | } | |
1a4d82fc JJ |
308 | |
309 | /// Layout pointer size, in bits, based on the type. If this function is | |
310 | /// called with a pointer type, then the type size of the pointer is returned. | |
311 | /// If this function is called with a vector of pointers, then the type size | |
312 | /// of the pointer is returned. This should only be called with a pointer or | |
313 | /// vector of pointers. | |
314 | unsigned getPointerTypeSizeInBits(Type *) const; | |
315 | ||
316 | unsigned getPointerTypeSize(Type *Ty) const { | |
317 | return getPointerTypeSizeInBits(Ty) / 8; | |
318 | } | |
319 | ||
223e47cc LB |
320 | /// Size examples: |
321 | /// | |
322 | /// Type SizeInBits StoreSizeInBits AllocSizeInBits[*] | |
323 | /// ---- ---------- --------------- --------------- | |
324 | /// i1 1 8 8 | |
325 | /// i8 8 8 8 | |
326 | /// i19 19 24 32 | |
327 | /// i32 32 32 32 | |
328 | /// i100 100 104 128 | |
329 | /// i128 128 128 128 | |
330 | /// Float 32 32 32 | |
331 | /// Double 64 64 64 | |
332 | /// X86_FP80 80 80 96 | |
333 | /// | |
334 | /// [*] The alloc size depends on the alignment, and thus on the target. | |
335 | /// These values are for x86-32 linux. | |
336 | ||
85aaf69f SL |
337 | /// \brief Returns the number of bits necessary to hold the specified type. |
338 | /// | |
339 | /// For example, returns 36 for i36 and 80 for x86_fp80. The type passed must | |
340 | /// have a size (Type::isSized() must return true). | |
970d7e83 | 341 | uint64_t getTypeSizeInBits(Type *Ty) const; |
223e47cc | 342 | |
85aaf69f SL |
343 | /// \brief Returns the maximum number of bytes that may be overwritten by |
344 | /// storing the specified type. | |
345 | /// | |
346 | /// For example, returns 5 for i36 and 10 for x86_fp80. | |
223e47cc | 347 | uint64_t getTypeStoreSize(Type *Ty) const { |
85aaf69f | 348 | return (getTypeSizeInBits(Ty) + 7) / 8; |
223e47cc LB |
349 | } |
350 | ||
85aaf69f SL |
351 | /// \brief Returns the maximum number of bits that may be overwritten by |
352 | /// storing the specified type; always a multiple of 8. | |
353 | /// | |
354 | /// For example, returns 40 for i36 and 80 for x86_fp80. | |
223e47cc | 355 | uint64_t getTypeStoreSizeInBits(Type *Ty) const { |
85aaf69f | 356 | return 8 * getTypeStoreSize(Ty); |
223e47cc LB |
357 | } |
358 | ||
85aaf69f SL |
359 | /// \brief Returns the offset in bytes between successive objects of the |
360 | /// specified type, including alignment padding. | |
361 | /// | |
362 | /// This is the amount that alloca reserves for this type. For example, | |
363 | /// returns 12 or 16 for x86_fp80, depending on alignment. | |
970d7e83 | 364 | uint64_t getTypeAllocSize(Type *Ty) const { |
223e47cc | 365 | // Round up to the next alignment boundary. |
85aaf69f | 366 | return RoundUpToAlignment(getTypeStoreSize(Ty), getABITypeAlignment(Ty)); |
223e47cc LB |
367 | } |
368 | ||
85aaf69f SL |
369 | /// \brief Returns the offset in bits between successive objects of the |
370 | /// specified type, including alignment padding; always a multiple of 8. | |
371 | /// | |
372 | /// This is the amount that alloca reserves for this type. For example, | |
373 | /// returns 96 or 128 for x86_fp80, depending on alignment. | |
970d7e83 | 374 | uint64_t getTypeAllocSizeInBits(Type *Ty) const { |
85aaf69f | 375 | return 8 * getTypeAllocSize(Ty); |
223e47cc LB |
376 | } |
377 | ||
85aaf69f | 378 | /// \brief Returns the minimum ABI-required alignment for the specified type. |
223e47cc LB |
379 | unsigned getABITypeAlignment(Type *Ty) const; |
380 | ||
85aaf69f SL |
381 | /// \brief Returns the minimum ABI-required alignment for an integer type of |
382 | /// the specified bitwidth. | |
223e47cc LB |
383 | unsigned getABIIntegerTypeAlignment(unsigned BitWidth) const; |
384 | ||
85aaf69f SL |
385 | /// \brief Returns the preferred stack/global alignment for the specified |
386 | /// type. | |
387 | /// | |
388 | /// This is always at least as good as the ABI alignment. | |
223e47cc LB |
389 | unsigned getPrefTypeAlignment(Type *Ty) const; |
390 | ||
85aaf69f SL |
391 | /// \brief Returns the preferred alignment for the specified type, returned as |
392 | /// log2 of the value (a shift amount). | |
223e47cc LB |
393 | unsigned getPreferredTypeAlignmentShift(Type *Ty) const; |
394 | ||
85aaf69f SL |
395 | /// \brief Returns an integer type with size at least as big as that of a |
396 | /// pointer in the given address space. | |
970d7e83 LB |
397 | IntegerType *getIntPtrType(LLVMContext &C, unsigned AddressSpace = 0) const; |
398 | ||
85aaf69f SL |
399 | /// \brief Returns an integer (vector of integer) type with size at least as |
400 | /// big as that of a pointer of the given pointer (vector of pointer) type. | |
970d7e83 | 401 | Type *getIntPtrType(Type *) const; |
223e47cc | 402 | |
85aaf69f SL |
403 | /// \brief Returns the smallest integer type with size at least as big as |
404 | /// Width bits. | |
1a4d82fc JJ |
405 | Type *getSmallestLegalIntType(LLVMContext &C, unsigned Width = 0) const; |
406 | ||
85aaf69f | 407 | /// \brief Returns the largest legal integer type, or null if none are set. |
1a4d82fc JJ |
408 | Type *getLargestLegalIntType(LLVMContext &C) const { |
409 | unsigned LargestSize = getLargestLegalIntTypeSize(); | |
410 | return (LargestSize == 0) ? nullptr : Type::getIntNTy(C, LargestSize); | |
411 | } | |
412 | ||
85aaf69f SL |
413 | /// \brief Returns the size of largest legal integer type size, or 0 if none |
414 | /// are set. | |
1a4d82fc JJ |
415 | unsigned getLargestLegalIntTypeSize() const; |
416 | ||
85aaf69f SL |
417 | /// \brief Returns the offset from the beginning of the type for the specified |
418 | /// indices. | |
419 | /// | |
420 | /// This is used to implement getelementptr. | |
223e47cc LB |
421 | uint64_t getIndexedOffset(Type *Ty, ArrayRef<Value *> Indices) const; |
422 | ||
85aaf69f SL |
423 | /// \brief Returns a StructLayout object, indicating the alignment of the |
424 | /// struct, its size, and the offsets of its fields. | |
425 | /// | |
426 | /// Note that this information is lazily cached. | |
223e47cc LB |
427 | const StructLayout *getStructLayout(StructType *Ty) const; |
428 | ||
85aaf69f SL |
429 | /// \brief Returns the preferred alignment of the specified global. |
430 | /// | |
431 | /// This includes an explicitly requested alignment (if the global has one). | |
223e47cc LB |
432 | unsigned getPreferredAlignment(const GlobalVariable *GV) const; |
433 | ||
85aaf69f SL |
434 | /// \brief Returns the preferred alignment of the specified global, returned |
435 | /// in log form. | |
436 | /// | |
437 | /// This includes an explicitly requested alignment (if the global has one). | |
223e47cc | 438 | unsigned getPreferredAlignmentLog(const GlobalVariable *GV) const; |
1a4d82fc JJ |
439 | }; |
440 | ||
441 | inline DataLayout *unwrap(LLVMTargetDataRef P) { | |
85aaf69f | 442 | return reinterpret_cast<DataLayout *>(P); |
1a4d82fc JJ |
443 | } |
444 | ||
445 | inline LLVMTargetDataRef wrap(const DataLayout *P) { | |
85aaf69f | 446 | return reinterpret_cast<LLVMTargetDataRef>(const_cast<DataLayout *>(P)); |
1a4d82fc JJ |
447 | } |
448 | ||
449 | class DataLayoutPass : public ImmutablePass { | |
450 | DataLayout DL; | |
451 | ||
452 | public: | |
453 | /// This has to exist, because this is a pass, but it should never be used. | |
454 | DataLayoutPass(); | |
455 | ~DataLayoutPass(); | |
456 | ||
457 | const DataLayout &getDataLayout() const { return DL; } | |
223e47cc LB |
458 | |
459 | static char ID; // Pass identification, replacement for typeid | |
1a4d82fc JJ |
460 | |
461 | bool doFinalization(Module &M) override; | |
462 | bool doInitialization(Module &M) override; | |
223e47cc LB |
463 | }; |
464 | ||
85aaf69f SL |
465 | /// Used to lazily calculate structure layout information for a target machine, |
466 | /// based on the DataLayout structure. | |
223e47cc LB |
467 | class StructLayout { |
468 | uint64_t StructSize; | |
469 | unsigned StructAlignment; | |
470 | unsigned NumElements; | |
85aaf69f | 471 | uint64_t MemberOffsets[1]; // variable sized array! |
223e47cc | 472 | public: |
85aaf69f | 473 | uint64_t getSizeInBytes() const { return StructSize; } |
223e47cc | 474 | |
85aaf69f | 475 | uint64_t getSizeInBits() const { return 8 * StructSize; } |
223e47cc | 476 | |
85aaf69f | 477 | unsigned getAlignment() const { return StructAlignment; } |
223e47cc | 478 | |
85aaf69f SL |
479 | /// \brief Given a valid byte offset into the structure, returns the structure |
480 | /// index that contains it. | |
223e47cc LB |
481 | unsigned getElementContainingOffset(uint64_t Offset) const; |
482 | ||
483 | uint64_t getElementOffset(unsigned Idx) const { | |
484 | assert(Idx < NumElements && "Invalid element idx!"); | |
485 | return MemberOffsets[Idx]; | |
486 | } | |
487 | ||
488 | uint64_t getElementOffsetInBits(unsigned Idx) const { | |
85aaf69f | 489 | return getElementOffset(Idx) * 8; |
223e47cc LB |
490 | } |
491 | ||
492 | private: | |
85aaf69f | 493 | friend class DataLayout; // Only DataLayout can create this class |
1a4d82fc | 494 | StructLayout(StructType *ST, const DataLayout &DL); |
223e47cc LB |
495 | }; |
496 | ||
1a4d82fc JJ |
497 | // The implementation of this method is provided inline as it is particularly |
498 | // well suited to constant folding when called on a specific Type subclass. | |
499 | inline uint64_t DataLayout::getTypeSizeInBits(Type *Ty) const { | |
500 | assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!"); | |
501 | switch (Ty->getTypeID()) { | |
502 | case Type::LabelTyID: | |
503 | return getPointerSizeInBits(0); | |
504 | case Type::PointerTyID: | |
505 | return getPointerSizeInBits(Ty->getPointerAddressSpace()); | |
506 | case Type::ArrayTyID: { | |
507 | ArrayType *ATy = cast<ArrayType>(Ty); | |
508 | return ATy->getNumElements() * | |
509 | getTypeAllocSizeInBits(ATy->getElementType()); | |
510 | } | |
511 | case Type::StructTyID: | |
512 | // Get the layout annotation... which is lazily created on demand. | |
513 | return getStructLayout(cast<StructType>(Ty))->getSizeInBits(); | |
514 | case Type::IntegerTyID: | |
515 | return Ty->getIntegerBitWidth(); | |
516 | case Type::HalfTyID: | |
517 | return 16; | |
518 | case Type::FloatTyID: | |
519 | return 32; | |
520 | case Type::DoubleTyID: | |
521 | case Type::X86_MMXTyID: | |
522 | return 64; | |
523 | case Type::PPC_FP128TyID: | |
524 | case Type::FP128TyID: | |
525 | return 128; | |
85aaf69f | 526 | // In memory objects this is always aligned to a higher boundary, but |
1a4d82fc JJ |
527 | // only 80 bits contain information. |
528 | case Type::X86_FP80TyID: | |
529 | return 80; | |
530 | case Type::VectorTyID: { | |
531 | VectorType *VTy = cast<VectorType>(Ty); | |
532 | return VTy->getNumElements() * getTypeSizeInBits(VTy->getElementType()); | |
533 | } | |
534 | default: | |
535 | llvm_unreachable("DataLayout::getTypeSizeInBits(): Unsupported type"); | |
536 | } | |
537 | } | |
538 | ||
223e47cc LB |
539 | } // End llvm namespace |
540 | ||
541 | #endif |