Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
14 | pmbaty | 1 | //===- llvm/DataLayout.h - Data size & alignment info -----------*- C++ -*-===// |
2 | // |
||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
||
4 | // See https://llvm.org/LICENSE.txt for license information. |
||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
||
6 | // |
||
7 | //===----------------------------------------------------------------------===// |
||
8 | // |
||
9 | // This file defines layout properties related to datatype size/offset/alignment |
||
10 | // information. It uses lazy annotations to cache information about how |
||
11 | // structure types are laid out and used. |
||
12 | // |
||
13 | // This structure should be created once, filled in if the defaults are not |
||
14 | // correct and then passed around by const&. None of the members functions |
||
15 | // require modification to the object. |
||
16 | // |
||
17 | //===----------------------------------------------------------------------===// |
||
18 | |||
19 | #ifndef LLVM_IR_DATALAYOUT_H |
||
20 | #define LLVM_IR_DATALAYOUT_H |
||
21 | |||
22 | #include "llvm/ADT/APInt.h" |
||
23 | #include "llvm/ADT/ArrayRef.h" |
||
24 | #include "llvm/ADT/STLExtras.h" |
||
25 | #include "llvm/ADT/SmallVector.h" |
||
26 | #include "llvm/ADT/StringRef.h" |
||
27 | #include "llvm/IR/DerivedTypes.h" |
||
28 | #include "llvm/IR/Type.h" |
||
29 | #include "llvm/Support/Alignment.h" |
||
30 | #include "llvm/Support/Casting.h" |
||
31 | #include "llvm/Support/Compiler.h" |
||
32 | #include "llvm/Support/ErrorHandling.h" |
||
33 | #include "llvm/Support/MathExtras.h" |
||
34 | #include "llvm/Support/TrailingObjects.h" |
||
35 | #include "llvm/Support/TypeSize.h" |
||
36 | #include <cassert> |
||
37 | #include <cstdint> |
||
38 | #include <string> |
||
39 | |||
40 | // This needs to be outside of the namespace, to avoid conflict with llvm-c |
||
41 | // decl. |
||
42 | using LLVMTargetDataRef = struct LLVMOpaqueTargetData *; |
||
43 | |||
44 | namespace llvm { |
||
45 | |||
46 | class GlobalVariable; |
||
47 | class LLVMContext; |
||
48 | class Module; |
||
49 | class StructLayout; |
||
50 | class Triple; |
||
51 | class Value; |
||
52 | |||
53 | /// Enum used to categorize the alignment types stored by LayoutAlignElem |
||
54 | enum AlignTypeEnum { |
||
55 | INVALID_ALIGN = 0, |
||
56 | INTEGER_ALIGN = 'i', |
||
57 | VECTOR_ALIGN = 'v', |
||
58 | FLOAT_ALIGN = 'f', |
||
59 | AGGREGATE_ALIGN = 'a' |
||
60 | }; |
||
61 | |||
62 | // FIXME: Currently the DataLayout string carries a "preferred alignment" |
||
63 | // for types. As the DataLayout is module/global, this should likely be |
||
64 | // sunk down to an FTTI element that is queried rather than a global |
||
65 | // preference. |
||
66 | |||
67 | /// Layout alignment element. |
||
68 | /// |
||
69 | /// Stores the alignment data associated with a given alignment type (integer, |
||
70 | /// vector, float) and type bit width. |
||
71 | /// |
||
72 | /// \note The unusual order of elements in the structure attempts to reduce |
||
73 | /// padding and make the structure slightly more cache friendly. |
||
74 | struct LayoutAlignElem { |
||
75 | /// Alignment type from \c AlignTypeEnum |
||
76 | unsigned AlignType : 8; |
||
77 | unsigned TypeBitWidth : 24; |
||
78 | Align ABIAlign; |
||
79 | Align PrefAlign; |
||
80 | |||
81 | static LayoutAlignElem get(AlignTypeEnum align_type, Align abi_align, |
||
82 | Align pref_align, uint32_t bit_width); |
||
83 | |||
84 | bool operator==(const LayoutAlignElem &rhs) const; |
||
85 | }; |
||
86 | |||
87 | /// Layout pointer alignment element. |
||
88 | /// |
||
89 | /// Stores the alignment data associated with a given pointer and address space. |
||
90 | /// |
||
91 | /// \note The unusual order of elements in the structure attempts to reduce |
||
92 | /// padding and make the structure slightly more cache friendly. |
||
93 | struct PointerAlignElem { |
||
94 | Align ABIAlign; |
||
95 | Align PrefAlign; |
||
96 | uint32_t TypeBitWidth; |
||
97 | uint32_t AddressSpace; |
||
98 | uint32_t IndexBitWidth; |
||
99 | |||
100 | /// Initializer |
||
101 | static PointerAlignElem getInBits(uint32_t AddressSpace, Align ABIAlign, |
||
102 | Align PrefAlign, uint32_t TypeBitWidth, |
||
103 | uint32_t IndexBitWidth); |
||
104 | |||
105 | bool operator==(const PointerAlignElem &rhs) const; |
||
106 | }; |
||
107 | |||
108 | /// A parsed version of the target data layout string in and methods for |
||
109 | /// querying it. |
||
110 | /// |
||
111 | /// The target data layout string is specified *by the target* - a frontend |
||
112 | /// generating LLVM IR is required to generate the right target data for the |
||
113 | /// target being codegen'd to. |
||
114 | class DataLayout { |
||
115 | public: |
||
116 | enum class FunctionPtrAlignType { |
||
117 | /// The function pointer alignment is independent of the function alignment. |
||
118 | Independent, |
||
119 | /// The function pointer alignment is a multiple of the function alignment. |
||
120 | MultipleOfFunctionAlign, |
||
121 | }; |
||
122 | private: |
||
123 | /// Defaults to false. |
||
124 | bool BigEndian; |
||
125 | |||
126 | unsigned AllocaAddrSpace; |
||
127 | MaybeAlign StackNaturalAlign; |
||
128 | unsigned ProgramAddrSpace; |
||
129 | unsigned DefaultGlobalsAddrSpace; |
||
130 | |||
131 | MaybeAlign FunctionPtrAlign; |
||
132 | FunctionPtrAlignType TheFunctionPtrAlignType; |
||
133 | |||
134 | enum ManglingModeT { |
||
135 | MM_None, |
||
136 | MM_ELF, |
||
137 | MM_MachO, |
||
138 | MM_WinCOFF, |
||
139 | MM_WinCOFFX86, |
||
140 | MM_GOFF, |
||
141 | MM_Mips, |
||
142 | MM_XCOFF |
||
143 | }; |
||
144 | ManglingModeT ManglingMode; |
||
145 | |||
146 | SmallVector<unsigned char, 8> LegalIntWidths; |
||
147 | |||
148 | /// Primitive type alignment data. This is sorted by type and bit |
||
149 | /// width during construction. |
||
150 | using AlignmentsTy = SmallVector<LayoutAlignElem, 16>; |
||
151 | AlignmentsTy Alignments; |
||
152 | |||
153 | AlignmentsTy::const_iterator |
||
154 | findAlignmentLowerBound(AlignTypeEnum AlignType, uint32_t BitWidth) const { |
||
155 | return const_cast<DataLayout *>(this)->findAlignmentLowerBound(AlignType, |
||
156 | BitWidth); |
||
157 | } |
||
158 | |||
159 | AlignmentsTy::iterator |
||
160 | findAlignmentLowerBound(AlignTypeEnum AlignType, uint32_t BitWidth); |
||
161 | |||
162 | /// The string representation used to create this DataLayout |
||
163 | std::string StringRepresentation; |
||
164 | |||
165 | using PointersTy = SmallVector<PointerAlignElem, 8>; |
||
166 | PointersTy Pointers; |
||
167 | |||
168 | const PointerAlignElem &getPointerAlignElem(uint32_t AddressSpace) const; |
||
169 | |||
170 | // The StructType -> StructLayout map. |
||
171 | mutable void *LayoutMap = nullptr; |
||
172 | |||
173 | /// Pointers in these address spaces are non-integral, and don't have a |
||
174 | /// well-defined bitwise representation. |
||
175 | SmallVector<unsigned, 8> NonIntegralAddressSpaces; |
||
176 | |||
177 | /// Attempts to set the alignment of the given type. Returns an error |
||
178 | /// description on failure. |
||
179 | Error setAlignment(AlignTypeEnum align_type, Align abi_align, |
||
180 | Align pref_align, uint32_t bit_width); |
||
181 | |||
182 | /// Attempts to set the alignment of a pointer in the given address space. |
||
183 | /// Returns an error description on failure. |
||
184 | Error setPointerAlignmentInBits(uint32_t AddrSpace, Align ABIAlign, |
||
185 | Align PrefAlign, uint32_t TypeBitWidth, |
||
186 | uint32_t IndexBitWidth); |
||
187 | |||
188 | /// Internal helper to get alignment for integer of given bitwidth. |
||
189 | Align getIntegerAlignment(uint32_t BitWidth, bool abi_or_pref) const; |
||
190 | |||
191 | /// Internal helper method that returns requested alignment for type. |
||
192 | Align getAlignment(Type *Ty, bool abi_or_pref) const; |
||
193 | |||
194 | /// Attempts to parse a target data specification string and reports an error |
||
195 | /// if the string is malformed. |
||
196 | Error parseSpecifier(StringRef Desc); |
||
197 | |||
198 | // Free all internal data structures. |
||
199 | void clear(); |
||
200 | |||
201 | public: |
||
202 | /// Constructs a DataLayout from a specification string. See reset(). |
||
203 | explicit DataLayout(StringRef LayoutDescription) { |
||
204 | reset(LayoutDescription); |
||
205 | } |
||
206 | |||
207 | /// Initialize target data from properties stored in the module. |
||
208 | explicit DataLayout(const Module *M); |
||
209 | |||
210 | DataLayout(const DataLayout &DL) { *this = DL; } |
||
211 | |||
212 | ~DataLayout(); // Not virtual, do not subclass this class |
||
213 | |||
214 | DataLayout &operator=(const DataLayout &DL) { |
||
215 | clear(); |
||
216 | StringRepresentation = DL.StringRepresentation; |
||
217 | BigEndian = DL.isBigEndian(); |
||
218 | AllocaAddrSpace = DL.AllocaAddrSpace; |
||
219 | StackNaturalAlign = DL.StackNaturalAlign; |
||
220 | FunctionPtrAlign = DL.FunctionPtrAlign; |
||
221 | TheFunctionPtrAlignType = DL.TheFunctionPtrAlignType; |
||
222 | ProgramAddrSpace = DL.ProgramAddrSpace; |
||
223 | DefaultGlobalsAddrSpace = DL.DefaultGlobalsAddrSpace; |
||
224 | ManglingMode = DL.ManglingMode; |
||
225 | LegalIntWidths = DL.LegalIntWidths; |
||
226 | Alignments = DL.Alignments; |
||
227 | Pointers = DL.Pointers; |
||
228 | NonIntegralAddressSpaces = DL.NonIntegralAddressSpaces; |
||
229 | return *this; |
||
230 | } |
||
231 | |||
232 | bool operator==(const DataLayout &Other) const; |
||
233 | bool operator!=(const DataLayout &Other) const { return !(*this == Other); } |
||
234 | |||
235 | void init(const Module *M); |
||
236 | |||
237 | /// Parse a data layout string (with fallback to default values). |
||
238 | void reset(StringRef LayoutDescription); |
||
239 | |||
240 | /// Parse a data layout string and return the layout. Return an error |
||
241 | /// description on failure. |
||
242 | static Expected<DataLayout> parse(StringRef LayoutDescription); |
||
243 | |||
244 | /// Layout endianness... |
||
245 | bool isLittleEndian() const { return !BigEndian; } |
||
246 | bool isBigEndian() const { return BigEndian; } |
||
247 | |||
248 | /// Returns the string representation of the DataLayout. |
||
249 | /// |
||
250 | /// This representation is in the same format accepted by the string |
||
251 | /// constructor above. This should not be used to compare two DataLayout as |
||
252 | /// different string can represent the same layout. |
||
253 | const std::string &getStringRepresentation() const { |
||
254 | return StringRepresentation; |
||
255 | } |
||
256 | |||
257 | /// Test if the DataLayout was constructed from an empty string. |
||
258 | bool isDefault() const { return StringRepresentation.empty(); } |
||
259 | |||
260 | /// Returns true if the specified type is known to be a native integer |
||
261 | /// type supported by the CPU. |
||
262 | /// |
||
263 | /// For example, i64 is not native on most 32-bit CPUs and i37 is not native |
||
264 | /// on any known one. This returns false if the integer width is not legal. |
||
265 | /// |
||
266 | /// The width is specified in bits. |
||
267 | bool isLegalInteger(uint64_t Width) const { |
||
268 | return llvm::is_contained(LegalIntWidths, Width); |
||
269 | } |
||
270 | |||
271 | bool isIllegalInteger(uint64_t Width) const { return !isLegalInteger(Width); } |
||
272 | |||
273 | /// Returns true if the given alignment exceeds the natural stack alignment. |
||
274 | bool exceedsNaturalStackAlignment(Align Alignment) const { |
||
275 | return StackNaturalAlign && (Alignment > *StackNaturalAlign); |
||
276 | } |
||
277 | |||
278 | Align getStackAlignment() const { |
||
279 | assert(StackNaturalAlign && "StackNaturalAlign must be defined"); |
||
280 | return *StackNaturalAlign; |
||
281 | } |
||
282 | |||
283 | unsigned getAllocaAddrSpace() const { return AllocaAddrSpace; } |
||
284 | |||
285 | /// Returns the alignment of function pointers, which may or may not be |
||
286 | /// related to the alignment of functions. |
||
287 | /// \see getFunctionPtrAlignType |
||
288 | MaybeAlign getFunctionPtrAlign() const { return FunctionPtrAlign; } |
||
289 | |||
290 | /// Return the type of function pointer alignment. |
||
291 | /// \see getFunctionPtrAlign |
||
292 | FunctionPtrAlignType getFunctionPtrAlignType() const { |
||
293 | return TheFunctionPtrAlignType; |
||
294 | } |
||
295 | |||
296 | unsigned getProgramAddressSpace() const { return ProgramAddrSpace; } |
||
297 | unsigned getDefaultGlobalsAddressSpace() const { |
||
298 | return DefaultGlobalsAddrSpace; |
||
299 | } |
||
300 | |||
301 | bool hasMicrosoftFastStdCallMangling() const { |
||
302 | return ManglingMode == MM_WinCOFFX86; |
||
303 | } |
||
304 | |||
305 | /// Returns true if symbols with leading question marks should not receive IR |
||
306 | /// mangling. True for Windows mangling modes. |
||
307 | bool doNotMangleLeadingQuestionMark() const { |
||
308 | return ManglingMode == MM_WinCOFF || ManglingMode == MM_WinCOFFX86; |
||
309 | } |
||
310 | |||
311 | bool hasLinkerPrivateGlobalPrefix() const { return ManglingMode == MM_MachO; } |
||
312 | |||
313 | StringRef getLinkerPrivateGlobalPrefix() const { |
||
314 | if (ManglingMode == MM_MachO) |
||
315 | return "l"; |
||
316 | return ""; |
||
317 | } |
||
318 | |||
319 | char getGlobalPrefix() const { |
||
320 | switch (ManglingMode) { |
||
321 | case MM_None: |
||
322 | case MM_ELF: |
||
323 | case MM_GOFF: |
||
324 | case MM_Mips: |
||
325 | case MM_WinCOFF: |
||
326 | case MM_XCOFF: |
||
327 | return '\0'; |
||
328 | case MM_MachO: |
||
329 | case MM_WinCOFFX86: |
||
330 | return '_'; |
||
331 | } |
||
332 | llvm_unreachable("invalid mangling mode"); |
||
333 | } |
||
334 | |||
335 | StringRef getPrivateGlobalPrefix() const { |
||
336 | switch (ManglingMode) { |
||
337 | case MM_None: |
||
338 | return ""; |
||
339 | case MM_ELF: |
||
340 | case MM_WinCOFF: |
||
341 | return ".L"; |
||
342 | case MM_GOFF: |
||
343 | return "@"; |
||
344 | case MM_Mips: |
||
345 | return "$"; |
||
346 | case MM_MachO: |
||
347 | case MM_WinCOFFX86: |
||
348 | return "L"; |
||
349 | case MM_XCOFF: |
||
350 | return "L.."; |
||
351 | } |
||
352 | llvm_unreachable("invalid mangling mode"); |
||
353 | } |
||
354 | |||
355 | static const char *getManglingComponent(const Triple &T); |
||
356 | |||
357 | /// Returns true if the specified type fits in a native integer type |
||
358 | /// supported by the CPU. |
||
359 | /// |
||
360 | /// For example, if the CPU only supports i32 as a native integer type, then |
||
361 | /// i27 fits in a legal integer type but i45 does not. |
||
362 | bool fitsInLegalInteger(unsigned Width) const { |
||
363 | for (unsigned LegalIntWidth : LegalIntWidths) |
||
364 | if (Width <= LegalIntWidth) |
||
365 | return true; |
||
366 | return false; |
||
367 | } |
||
368 | |||
369 | /// Layout pointer alignment |
||
370 | Align getPointerABIAlignment(unsigned AS) const; |
||
371 | |||
372 | /// Return target's alignment for stack-based pointers |
||
373 | /// FIXME: The defaults need to be removed once all of |
||
374 | /// the backends/clients are updated. |
||
375 | Align getPointerPrefAlignment(unsigned AS = 0) const; |
||
376 | |||
377 | /// Layout pointer size in bytes, rounded up to a whole |
||
378 | /// number of bytes. |
||
379 | /// FIXME: The defaults need to be removed once all of |
||
380 | /// the backends/clients are updated. |
||
381 | unsigned getPointerSize(unsigned AS = 0) const; |
||
382 | |||
383 | /// Returns the maximum index size over all address spaces. |
||
384 | unsigned getMaxIndexSize() const; |
||
385 | |||
386 | // Index size in bytes used for address calculation, |
||
387 | /// rounded up to a whole number of bytes. |
||
388 | unsigned getIndexSize(unsigned AS) const; |
||
389 | |||
390 | /// Return the address spaces containing non-integral pointers. Pointers in |
||
391 | /// this address space don't have a well-defined bitwise representation. |
||
392 | ArrayRef<unsigned> getNonIntegralAddressSpaces() const { |
||
393 | return NonIntegralAddressSpaces; |
||
394 | } |
||
395 | |||
396 | bool isNonIntegralAddressSpace(unsigned AddrSpace) const { |
||
397 | ArrayRef<unsigned> NonIntegralSpaces = getNonIntegralAddressSpaces(); |
||
398 | return is_contained(NonIntegralSpaces, AddrSpace); |
||
399 | } |
||
400 | |||
401 | bool isNonIntegralPointerType(PointerType *PT) const { |
||
402 | return isNonIntegralAddressSpace(PT->getAddressSpace()); |
||
403 | } |
||
404 | |||
405 | bool isNonIntegralPointerType(Type *Ty) const { |
||
406 | auto *PTy = dyn_cast<PointerType>(Ty); |
||
407 | return PTy && isNonIntegralPointerType(PTy); |
||
408 | } |
||
409 | |||
410 | /// Layout pointer size, in bits |
||
411 | /// FIXME: The defaults need to be removed once all of |
||
412 | /// the backends/clients are updated. |
||
413 | unsigned getPointerSizeInBits(unsigned AS = 0) const { |
||
414 | return getPointerAlignElem(AS).TypeBitWidth; |
||
415 | } |
||
416 | |||
417 | /// Returns the maximum index size over all address spaces. |
||
418 | unsigned getMaxIndexSizeInBits() const { |
||
419 | return getMaxIndexSize() * 8; |
||
420 | } |
||
421 | |||
422 | /// Size in bits of index used for address calculation in getelementptr. |
||
423 | unsigned getIndexSizeInBits(unsigned AS) const { |
||
424 | return getPointerAlignElem(AS).IndexBitWidth; |
||
425 | } |
||
426 | |||
427 | /// Layout pointer size, in bits, based on the type. If this function is |
||
428 | /// called with a pointer type, then the type size of the pointer is returned. |
||
429 | /// If this function is called with a vector of pointers, then the type size |
||
430 | /// of the pointer is returned. This should only be called with a pointer or |
||
431 | /// vector of pointers. |
||
432 | unsigned getPointerTypeSizeInBits(Type *) const; |
||
433 | |||
434 | /// Layout size of the index used in GEP calculation. |
||
435 | /// The function should be called with pointer or vector of pointers type. |
||
436 | unsigned getIndexTypeSizeInBits(Type *Ty) const; |
||
437 | |||
438 | unsigned getPointerTypeSize(Type *Ty) const { |
||
439 | return getPointerTypeSizeInBits(Ty) / 8; |
||
440 | } |
||
441 | |||
442 | /// Size examples: |
||
443 | /// |
||
444 | /// Type SizeInBits StoreSizeInBits AllocSizeInBits[*] |
||
445 | /// ---- ---------- --------------- --------------- |
||
446 | /// i1 1 8 8 |
||
447 | /// i8 8 8 8 |
||
448 | /// i19 19 24 32 |
||
449 | /// i32 32 32 32 |
||
450 | /// i100 100 104 128 |
||
451 | /// i128 128 128 128 |
||
452 | /// Float 32 32 32 |
||
453 | /// Double 64 64 64 |
||
454 | /// X86_FP80 80 80 96 |
||
455 | /// |
||
456 | /// [*] The alloc size depends on the alignment, and thus on the target. |
||
457 | /// These values are for x86-32 linux. |
||
458 | |||
459 | /// Returns the number of bits necessary to hold the specified type. |
||
460 | /// |
||
461 | /// If Ty is a scalable vector type, the scalable property will be set and |
||
462 | /// the runtime size will be a positive integer multiple of the base size. |
||
463 | /// |
||
464 | /// For example, returns 36 for i36 and 80 for x86_fp80. The type passed must |
||
465 | /// have a size (Type::isSized() must return true). |
||
466 | TypeSize getTypeSizeInBits(Type *Ty) const; |
||
467 | |||
468 | /// Returns the maximum number of bytes that may be overwritten by |
||
469 | /// storing the specified type. |
||
470 | /// |
||
471 | /// If Ty is a scalable vector type, the scalable property will be set and |
||
472 | /// the runtime size will be a positive integer multiple of the base size. |
||
473 | /// |
||
474 | /// For example, returns 5 for i36 and 10 for x86_fp80. |
||
475 | TypeSize getTypeStoreSize(Type *Ty) const { |
||
476 | TypeSize BaseSize = getTypeSizeInBits(Ty); |
||
477 | return {divideCeil(BaseSize.getKnownMinValue(), 8), BaseSize.isScalable()}; |
||
478 | } |
||
479 | |||
480 | /// Returns the maximum number of bits that may be overwritten by |
||
481 | /// storing the specified type; always a multiple of 8. |
||
482 | /// |
||
483 | /// If Ty is a scalable vector type, the scalable property will be set and |
||
484 | /// the runtime size will be a positive integer multiple of the base size. |
||
485 | /// |
||
486 | /// For example, returns 40 for i36 and 80 for x86_fp80. |
||
487 | TypeSize getTypeStoreSizeInBits(Type *Ty) const { |
||
488 | return 8 * getTypeStoreSize(Ty); |
||
489 | } |
||
490 | |||
491 | /// Returns true if no extra padding bits are needed when storing the |
||
492 | /// specified type. |
||
493 | /// |
||
494 | /// For example, returns false for i19 that has a 24-bit store size. |
||
495 | bool typeSizeEqualsStoreSize(Type *Ty) const { |
||
496 | return getTypeSizeInBits(Ty) == getTypeStoreSizeInBits(Ty); |
||
497 | } |
||
498 | |||
499 | /// Returns the offset in bytes between successive objects of the |
||
500 | /// specified type, including alignment padding. |
||
501 | /// |
||
502 | /// If Ty is a scalable vector type, the scalable property will be set and |
||
503 | /// the runtime size will be a positive integer multiple of the base size. |
||
504 | /// |
||
505 | /// This is the amount that alloca reserves for this type. For example, |
||
506 | /// returns 12 or 16 for x86_fp80, depending on alignment. |
||
507 | TypeSize getTypeAllocSize(Type *Ty) const { |
||
508 | // Round up to the next alignment boundary. |
||
509 | return alignTo(getTypeStoreSize(Ty), getABITypeAlign(Ty).value()); |
||
510 | } |
||
511 | |||
512 | /// Returns the offset in bits between successive objects of the |
||
513 | /// specified type, including alignment padding; always a multiple of 8. |
||
514 | /// |
||
515 | /// If Ty is a scalable vector type, the scalable property will be set and |
||
516 | /// the runtime size will be a positive integer multiple of the base size. |
||
517 | /// |
||
518 | /// This is the amount that alloca reserves for this type. For example, |
||
519 | /// returns 96 or 128 for x86_fp80, depending on alignment. |
||
520 | TypeSize getTypeAllocSizeInBits(Type *Ty) const { |
||
521 | return 8 * getTypeAllocSize(Ty); |
||
522 | } |
||
523 | |||
524 | /// Returns the minimum ABI-required alignment for the specified type. |
||
525 | /// FIXME: Deprecate this function once migration to Align is over. |
||
526 | LLVM_DEPRECATED("use getABITypeAlign instead", "getABITypeAlign") |
||
527 | uint64_t getABITypeAlignment(Type *Ty) const; |
||
528 | |||
529 | /// Returns the minimum ABI-required alignment for the specified type. |
||
530 | Align getABITypeAlign(Type *Ty) const; |
||
531 | |||
532 | /// Helper function to return `Alignment` if it's set or the result of |
||
533 | /// `getABITypeAlignment(Ty)`, in any case the result is a valid alignment. |
||
534 | inline Align getValueOrABITypeAlignment(MaybeAlign Alignment, |
||
535 | Type *Ty) const { |
||
536 | return Alignment ? *Alignment : getABITypeAlign(Ty); |
||
537 | } |
||
538 | |||
539 | /// Returns the minimum ABI-required alignment for an integer type of |
||
540 | /// the specified bitwidth. |
||
541 | Align getABIIntegerTypeAlignment(unsigned BitWidth) const { |
||
542 | return getIntegerAlignment(BitWidth, /* abi_or_pref */ true); |
||
543 | } |
||
544 | |||
545 | /// Returns the preferred stack/global alignment for the specified |
||
546 | /// type. |
||
547 | /// |
||
548 | /// This is always at least as good as the ABI alignment. |
||
549 | /// FIXME: Deprecate this function once migration to Align is over. |
||
550 | LLVM_DEPRECATED("use getPrefTypeAlign instead", "getPrefTypeAlign") |
||
551 | uint64_t getPrefTypeAlignment(Type *Ty) const; |
||
552 | |||
553 | /// Returns the preferred stack/global alignment for the specified |
||
554 | /// type. |
||
555 | /// |
||
556 | /// This is always at least as good as the ABI alignment. |
||
557 | Align getPrefTypeAlign(Type *Ty) const; |
||
558 | |||
559 | /// Returns an integer type with size at least as big as that of a |
||
560 | /// pointer in the given address space. |
||
561 | IntegerType *getIntPtrType(LLVMContext &C, unsigned AddressSpace = 0) const; |
||
562 | |||
563 | /// Returns an integer (vector of integer) type with size at least as |
||
564 | /// big as that of a pointer of the given pointer (vector of pointer) type. |
||
565 | Type *getIntPtrType(Type *) const; |
||
566 | |||
567 | /// Returns the smallest integer type with size at least as big as |
||
568 | /// Width bits. |
||
569 | Type *getSmallestLegalIntType(LLVMContext &C, unsigned Width = 0) const; |
||
570 | |||
571 | /// Returns the largest legal integer type, or null if none are set. |
||
572 | Type *getLargestLegalIntType(LLVMContext &C) const { |
||
573 | unsigned LargestSize = getLargestLegalIntTypeSizeInBits(); |
||
574 | return (LargestSize == 0) ? nullptr : Type::getIntNTy(C, LargestSize); |
||
575 | } |
||
576 | |||
577 | /// Returns the size of largest legal integer type size, or 0 if none |
||
578 | /// are set. |
||
579 | unsigned getLargestLegalIntTypeSizeInBits() const; |
||
580 | |||
581 | /// Returns the type of a GEP index. |
||
582 | /// If it was not specified explicitly, it will be the integer type of the |
||
583 | /// pointer width - IntPtrType. |
||
584 | Type *getIndexType(Type *PtrTy) const; |
||
585 | |||
586 | /// Returns the offset from the beginning of the type for the specified |
||
587 | /// indices. |
||
588 | /// |
||
589 | /// Note that this takes the element type, not the pointer type. |
||
590 | /// This is used to implement getelementptr. |
||
591 | int64_t getIndexedOffsetInType(Type *ElemTy, ArrayRef<Value *> Indices) const; |
||
592 | |||
593 | /// Get GEP indices to access Offset inside ElemTy. ElemTy is updated to be |
||
594 | /// the result element type and Offset to be the residual offset. |
||
595 | SmallVector<APInt> getGEPIndicesForOffset(Type *&ElemTy, APInt &Offset) const; |
||
596 | |||
597 | /// Get single GEP index to access Offset inside ElemTy. Returns std::nullopt |
||
598 | /// if index cannot be computed, e.g. because the type is not an aggregate. |
||
599 | /// ElemTy is updated to be the result element type and Offset to be the |
||
600 | /// residual offset. |
||
601 | std::optional<APInt> getGEPIndexForOffset(Type *&ElemTy, APInt &Offset) const; |
||
602 | |||
603 | /// Returns a StructLayout object, indicating the alignment of the |
||
604 | /// struct, its size, and the offsets of its fields. |
||
605 | /// |
||
606 | /// Note that this information is lazily cached. |
||
607 | const StructLayout *getStructLayout(StructType *Ty) const; |
||
608 | |||
609 | /// Returns the preferred alignment of the specified global. |
||
610 | /// |
||
611 | /// This includes an explicitly requested alignment (if the global has one). |
||
612 | Align getPreferredAlign(const GlobalVariable *GV) const; |
||
613 | }; |
||
614 | |||
615 | inline DataLayout *unwrap(LLVMTargetDataRef P) { |
||
616 | return reinterpret_cast<DataLayout *>(P); |
||
617 | } |
||
618 | |||
619 | inline LLVMTargetDataRef wrap(const DataLayout *P) { |
||
620 | return reinterpret_cast<LLVMTargetDataRef>(const_cast<DataLayout *>(P)); |
||
621 | } |
||
622 | |||
623 | /// Used to lazily calculate structure layout information for a target machine, |
||
624 | /// based on the DataLayout structure. |
||
625 | class StructLayout final : public TrailingObjects<StructLayout, uint64_t> { |
||
626 | uint64_t StructSize; |
||
627 | Align StructAlignment; |
||
628 | unsigned IsPadded : 1; |
||
629 | unsigned NumElements : 31; |
||
630 | |||
631 | public: |
||
632 | uint64_t getSizeInBytes() const { return StructSize; } |
||
633 | |||
634 | uint64_t getSizeInBits() const { return 8 * StructSize; } |
||
635 | |||
636 | Align getAlignment() const { return StructAlignment; } |
||
637 | |||
638 | /// Returns whether the struct has padding or not between its fields. |
||
639 | /// NB: Padding in nested element is not taken into account. |
||
640 | bool hasPadding() const { return IsPadded; } |
||
641 | |||
642 | /// Given a valid byte offset into the structure, returns the structure |
||
643 | /// index that contains it. |
||
644 | unsigned getElementContainingOffset(uint64_t Offset) const; |
||
645 | |||
646 | MutableArrayRef<uint64_t> getMemberOffsets() { |
||
647 | return llvm::MutableArrayRef(getTrailingObjects<uint64_t>(), |
||
648 | NumElements); |
||
649 | } |
||
650 | |||
651 | ArrayRef<uint64_t> getMemberOffsets() const { |
||
652 | return llvm::ArrayRef(getTrailingObjects<uint64_t>(), NumElements); |
||
653 | } |
||
654 | |||
655 | uint64_t getElementOffset(unsigned Idx) const { |
||
656 | assert(Idx < NumElements && "Invalid element idx!"); |
||
657 | return getMemberOffsets()[Idx]; |
||
658 | } |
||
659 | |||
660 | uint64_t getElementOffsetInBits(unsigned Idx) const { |
||
661 | return getElementOffset(Idx) * 8; |
||
662 | } |
||
663 | |||
664 | private: |
||
665 | friend class DataLayout; // Only DataLayout can create this class |
||
666 | |||
667 | StructLayout(StructType *ST, const DataLayout &DL); |
||
668 | |||
669 | size_t numTrailingObjects(OverloadToken<uint64_t>) const { |
||
670 | return NumElements; |
||
671 | } |
||
672 | }; |
||
673 | |||
674 | // The implementation of this method is provided inline as it is particularly |
||
675 | // well suited to constant folding when called on a specific Type subclass. |
||
676 | inline TypeSize DataLayout::getTypeSizeInBits(Type *Ty) const { |
||
677 | assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!"); |
||
678 | switch (Ty->getTypeID()) { |
||
679 | case Type::LabelTyID: |
||
680 | return TypeSize::Fixed(getPointerSizeInBits(0)); |
||
681 | case Type::PointerTyID: |
||
682 | return TypeSize::Fixed(getPointerSizeInBits(Ty->getPointerAddressSpace())); |
||
683 | case Type::ArrayTyID: { |
||
684 | ArrayType *ATy = cast<ArrayType>(Ty); |
||
685 | return ATy->getNumElements() * |
||
686 | getTypeAllocSizeInBits(ATy->getElementType()); |
||
687 | } |
||
688 | case Type::StructTyID: |
||
689 | // Get the layout annotation... which is lazily created on demand. |
||
690 | return TypeSize::Fixed( |
||
691 | getStructLayout(cast<StructType>(Ty))->getSizeInBits()); |
||
692 | case Type::IntegerTyID: |
||
693 | return TypeSize::Fixed(Ty->getIntegerBitWidth()); |
||
694 | case Type::HalfTyID: |
||
695 | case Type::BFloatTyID: |
||
696 | return TypeSize::Fixed(16); |
||
697 | case Type::FloatTyID: |
||
698 | return TypeSize::Fixed(32); |
||
699 | case Type::DoubleTyID: |
||
700 | case Type::X86_MMXTyID: |
||
701 | return TypeSize::Fixed(64); |
||
702 | case Type::PPC_FP128TyID: |
||
703 | case Type::FP128TyID: |
||
704 | return TypeSize::Fixed(128); |
||
705 | case Type::X86_AMXTyID: |
||
706 | return TypeSize::Fixed(8192); |
||
707 | // In memory objects this is always aligned to a higher boundary, but |
||
708 | // only 80 bits contain information. |
||
709 | case Type::X86_FP80TyID: |
||
710 | return TypeSize::Fixed(80); |
||
711 | case Type::FixedVectorTyID: |
||
712 | case Type::ScalableVectorTyID: { |
||
713 | VectorType *VTy = cast<VectorType>(Ty); |
||
714 | auto EltCnt = VTy->getElementCount(); |
||
715 | uint64_t MinBits = EltCnt.getKnownMinValue() * |
||
716 | getTypeSizeInBits(VTy->getElementType()).getFixedValue(); |
||
717 | return TypeSize(MinBits, EltCnt.isScalable()); |
||
718 | } |
||
719 | case Type::TargetExtTyID: { |
||
720 | Type *LayoutTy = cast<TargetExtType>(Ty)->getLayoutType(); |
||
721 | return getTypeSizeInBits(LayoutTy); |
||
722 | } |
||
723 | default: |
||
724 | llvm_unreachable("DataLayout::getTypeSizeInBits(): Unsupported type"); |
||
725 | } |
||
726 | } |
||
727 | |||
728 | } // end namespace llvm |
||
729 | |||
730 | #endif // LLVM_IR_DATALAYOUT_H |