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