blob: 26a30a7809798dbc643e7af5c65516eeeb1783cb [file] [log] [blame]
Chris Lattnere7fb3602001-08-27 16:00:15 +00001//===-- TargetData.cpp - Data size & alignment routines --------------------==//
Misha Brukmanf976c852005-04-21 22:55:34 +00002//
John Criswellb576c942003-10-20 19:43:21 +00003// The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
Misha Brukmanf976c852005-04-21 22:55:34 +00007//
John Criswellb576c942003-10-20 19:43:21 +00008//===----------------------------------------------------------------------===//
Chris Lattnere7fb3602001-08-27 16:00:15 +00009//
10// This file defines target properties related to datatype size/offset/alignment
Chris Lattner0e7ac162004-02-26 08:02:17 +000011// information.
Chris Lattnere7fb3602001-08-27 16:00:15 +000012//
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
Vikram S. Adve0799fc42001-09-18 12:58:33 +000019#include "llvm/Target/TargetData.h"
Chris Lattner53a0c382003-04-24 19:09:05 +000020#include "llvm/Module.h"
Chris Lattnere7fb3602001-08-27 16:00:15 +000021#include "llvm/DerivedTypes.h"
Chris Lattner31bcdb82002-04-28 19:55:58 +000022#include "llvm/Constants.h"
Chris Lattner28977af2004-04-05 01:30:19 +000023#include "llvm/Support/GetElementPtrTypeIterator.h"
Reid Spencer551ccae2004-09-01 22:55:40 +000024#include "llvm/Support/MathExtras.h"
Chris Lattnerec6478b2007-02-10 19:43:18 +000025#include "llvm/Support/ManagedStatic.h"
Chris Lattnerf6ca09a2007-02-10 20:26:17 +000026#include "llvm/ADT/DenseMap.h"
Owen Anderson8f60c562006-05-12 05:49:47 +000027#include "llvm/ADT/StringExtras.h"
Chris Lattnere7ea48c2005-03-13 19:04:41 +000028#include <algorithm>
Owen Anderson8f60c562006-05-12 05:49:47 +000029#include <cstdlib>
Owen Anderson2577c222006-05-12 07:01:44 +000030#include <sstream>
Chris Lattnerf0453282003-12-22 05:01:15 +000031using namespace llvm;
Brian Gaeked0fde302003-11-11 22:41:34 +000032
Misha Brukman5560c9d2003-08-18 14:43:39 +000033// Handle the Pass registration stuff necessary to use TargetData's.
Chris Lattneraa31ad02002-09-25 23:46:55 +000034namespace {
35 // Register the default SparcV9 implementation...
36 RegisterPass<TargetData> X("targetdata", "Target Data Layout");
37}
38
Chris Lattnere7fb3602001-08-27 16:00:15 +000039//===----------------------------------------------------------------------===//
Chris Lattner0e7ac162004-02-26 08:02:17 +000040// Support for StructLayout
Chris Lattnere7fb3602001-08-27 16:00:15 +000041//===----------------------------------------------------------------------===//
42
Chris Lattner0e7ac162004-02-26 08:02:17 +000043StructLayout::StructLayout(const StructType *ST, const TargetData &TD) {
Chris Lattnere7fb3602001-08-27 16:00:15 +000044 StructAlignment = 0;
45 StructSize = 0;
Chris Lattner9182e3f2007-02-10 20:15:41 +000046 NumElements = ST->getNumElements();
Chris Lattnere7fb3602001-08-27 16:00:15 +000047
48 // Loop over each of the elements, placing them in memory...
Chris Lattner9182e3f2007-02-10 20:15:41 +000049 for (unsigned i = 0, e = NumElements; i != e; ++i) {
50 const Type *Ty = ST->getElementType(i);
Vikram S. Advef66723f2002-05-19 15:28:02 +000051 unsigned TyAlign;
52 uint64_t TySize;
Chris Lattnerd2b7cec2007-02-14 05:52:17 +000053 TyAlign = (unsigned) TD.getABITypeAlignment(Ty);
54 TySize = (unsigned) TD.getTypeSize(Ty);
Chris Lattnere7fb3602001-08-27 16:00:15 +000055
Misha Brukman5560c9d2003-08-18 14:43:39 +000056 // Add padding if necessary to make the data element aligned properly...
Chris Lattnere7fb3602001-08-27 16:00:15 +000057 if (StructSize % TyAlign != 0)
58 StructSize = (StructSize/TyAlign + 1) * TyAlign; // Add padding...
59
60 // Keep track of maximum alignment constraint
Chris Lattner697954c2002-01-20 22:54:45 +000061 StructAlignment = std::max(TyAlign, StructAlignment);
Chris Lattnere7fb3602001-08-27 16:00:15 +000062
Chris Lattner9182e3f2007-02-10 20:15:41 +000063 MemberOffsets[i] = StructSize;
Vikram S. Advef66723f2002-05-19 15:28:02 +000064 StructSize += TySize; // Consume space for this data item
Chris Lattnere7fb3602001-08-27 16:00:15 +000065 }
66
Chris Lattner4e840d42003-05-21 18:08:44 +000067 // Empty structures have alignment of 1 byte.
68 if (StructAlignment == 0) StructAlignment = 1;
69
Chris Lattnere7fb3602001-08-27 16:00:15 +000070 // Add padding to the end of the struct so that it could be put in an array
71 // and all array elements would be aligned correctly.
72 if (StructSize % StructAlignment != 0)
73 StructSize = (StructSize/StructAlignment + 1) * StructAlignment;
Chris Lattnere7fb3602001-08-27 16:00:15 +000074}
75
Chris Lattnere7ea48c2005-03-13 19:04:41 +000076
77/// getElementContainingOffset - Given a valid offset into the structure,
78/// return the structure index that contains it.
79unsigned StructLayout::getElementContainingOffset(uint64_t Offset) const {
Chris Lattner9182e3f2007-02-10 20:15:41 +000080 const uint64_t *SI =
81 std::upper_bound(&MemberOffsets[0], &MemberOffsets[NumElements], Offset);
82 assert(SI != &MemberOffsets[0] && "Offset not in structure type!");
Chris Lattnere7ea48c2005-03-13 19:04:41 +000083 --SI;
84 assert(*SI <= Offset && "upper_bound didn't work");
Chris Lattner9182e3f2007-02-10 20:15:41 +000085 assert((SI == &MemberOffsets[0] || *(SI-1) < Offset) &&
86 (SI+1 == &MemberOffsets[NumElements] || *(SI+1) > Offset) &&
Chris Lattnere7ea48c2005-03-13 19:04:41 +000087 "Upper bound didn't work!");
Chris Lattner9182e3f2007-02-10 20:15:41 +000088 return SI-&MemberOffsets[0];
Chris Lattnere7ea48c2005-03-13 19:04:41 +000089}
90
Chris Lattnere7fb3602001-08-27 16:00:15 +000091//===----------------------------------------------------------------------===//
Chris Lattnerd2b7cec2007-02-14 05:52:17 +000092// TargetAlignElem, TargetAlign support
93//===----------------------------------------------------------------------===//
94
95TargetAlignElem
96TargetAlignElem::get(AlignTypeEnum align_type, unsigned char abi_align,
97 unsigned char pref_align, short bit_width)
98{
99 TargetAlignElem retval;
100 retval.AlignType = align_type;
101 retval.ABIAlign = abi_align;
102 retval.PrefAlign = pref_align;
103 retval.TypeBitWidth = bit_width;
104 return retval;
105}
106
107bool
108TargetAlignElem::operator<(const TargetAlignElem &rhs) const
109{
110 return ((AlignType < rhs.AlignType)
111 || (AlignType == rhs.AlignType && TypeBitWidth < rhs.TypeBitWidth));
112}
113
114bool
115TargetAlignElem::operator==(const TargetAlignElem &rhs) const
116{
117 return (AlignType == rhs.AlignType
118 && ABIAlign == rhs.ABIAlign
119 && PrefAlign == rhs.PrefAlign
120 && TypeBitWidth == rhs.TypeBitWidth);
121}
122
123std::ostream &
124TargetAlignElem::dump(std::ostream &os) const
125{
126 return os << AlignType
127 << TypeBitWidth
128 << ":" << (int) (ABIAlign * 8)
129 << ":" << (int) (PrefAlign * 8);
130}
131
132std::ostream &
133llvm::operator<<(std::ostream &os, const TargetAlignElem &elem)
134{
135 return elem.dump(os);
136}
137
138const TargetAlignElem TargetData::InvalidAlignmentElem =
139 TargetAlignElem::get((AlignTypeEnum) -1, 0, 0, 0);
140
141//===----------------------------------------------------------------------===//
Chris Lattnere7fb3602001-08-27 16:00:15 +0000142// TargetData Class Implementation
143//===----------------------------------------------------------------------===//
144
Chris Lattnerd2b7cec2007-02-14 05:52:17 +0000145/*!
146 A TargetDescription string consists of a sequence of hyphen-delimited
147 specifiers for target endianness, pointer size and alignments, and various
148 primitive type sizes and alignments. A typical string looks something like:
149 <br>
150 "E-p:32:32:32-i1:8:8-i8:8:8-i32:32:32-i64:32:64-f32:32:32-f64:32:64"
151 <br>
152 (note: this string is not fully specified and is only an example.)
153 \p
154 Alignments come in two flavors: ABI and preferred. ABI alignment (abi_align,
155 below) dictates how a type will be aligned within an aggregate and when used
156 as an argument. Preferred alignment (pref_align, below) determines a type's
157 alignment when emitted as a global.
158 \p
159 Specifier string details:
160 <br><br>
161 <i>[E|e]</i>: Endianness. "E" specifies a big-endian target data model, "e"
162 specifies a little-endian target data model.
163 <br><br>
164 <i>p:<size>:<abi_align>:<pref_align></i>: Pointer size, ABI and preferred
165 alignment.
166 <br><br>
167 <i><type><size>:<abi_align>:<pref_align></i>: Numeric type alignment. Type is
168 one of <i>i|f|v|a</i>, corresponding to integer, floating point, vector (aka
169 packed) or aggregate. Size indicates the size, e.g., 32 or 64 bits.
170 \p
171 The default string, fully specified is:
172 <br><br>
173 "E-p:64:64:64-a0:0:0-f32:32:32-f64:0:64"
174 "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:0:64"
175 "-v64:64:64-v128:128:128"
176 <br><br>
177 Note that in the case of aggregates, 0 is the default ABI and preferred
178 alignment. This is a special case, where the aggregate's computed worst-case
179 alignment will be used.
180 */
Chris Lattneracbc07a2006-06-16 18:11:26 +0000181void TargetData::init(const std::string &TargetDescription) {
Owen Anderson8f60c562006-05-12 05:49:47 +0000182 std::string temp = TargetDescription;
183
184 LittleEndian = false;
Chris Lattner58092e32007-01-20 22:35:55 +0000185 PointerMemSize = 8;
Chris Lattnerd2b7cec2007-02-14 05:52:17 +0000186 PointerABIAlign = 8;
187 PointerPrefAlign = PointerABIAlign;
188
189 // Default alignments
190 setAlignment(INTEGER_ALIGN, 1, 1, 1); // Bool
191 setAlignment(INTEGER_ALIGN, 1, 1, 8); // Byte
192 setAlignment(INTEGER_ALIGN, 2, 2, 16); // short
193 setAlignment(INTEGER_ALIGN, 4, 4, 32); // int
194 setAlignment(INTEGER_ALIGN, 0, 8, 64); // long
195 setAlignment(FLOAT_ALIGN, 4, 4, 32); // float
196 setAlignment(FLOAT_ALIGN, 0, 8, 64); // double
197 setAlignment(PACKED_ALIGN, 8, 8, 64); // v2i32
198 setAlignment(PACKED_ALIGN, 16, 16, 128); // v16i8, v8i16, v4i32, ...
199 setAlignment(AGGREGATE_ALIGN, 0, 0, 0); // struct, union, class, ...
Owen Anderson8f60c562006-05-12 05:49:47 +0000200
Owen Andersond988b322006-05-20 00:24:56 +0000201 while (!temp.empty()) {
Owen Anderson8f60c562006-05-12 05:49:47 +0000202 std::string token = getToken(temp, "-");
203
Chris Lattnerd2b7cec2007-02-14 05:52:17 +0000204 std::string arg0 = getToken(token, ":");
205 const char *p = arg0.c_str();
206 AlignTypeEnum align_type;
207 short size;
208 unsigned char abi_align;
209 unsigned char pref_align;
210
211 switch(*p) {
Owen Anderson8f60c562006-05-12 05:49:47 +0000212 case 'E':
Owen Anderson571a13f2006-05-12 06:06:55 +0000213 LittleEndian = false;
214 break;
Owen Anderson8f60c562006-05-12 05:49:47 +0000215 case 'e':
Owen Anderson571a13f2006-05-12 06:06:55 +0000216 LittleEndian = true;
217 break;
Owen Anderson8f60c562006-05-12 05:49:47 +0000218 case 'p':
Chris Lattner58092e32007-01-20 22:35:55 +0000219 PointerMemSize = atoi(getToken(token,":").c_str()) / 8;
Chris Lattnerd2b7cec2007-02-14 05:52:17 +0000220 PointerABIAlign = atoi(getToken(token,":").c_str()) / 8;
221 PointerPrefAlign = atoi(getToken(token,":").c_str()) / 8;
222 if (PointerPrefAlign == 0)
223 PointerPrefAlign = PointerABIAlign;
Owen Anderson571a13f2006-05-12 06:06:55 +0000224 break;
Owen Anderson8f60c562006-05-12 05:49:47 +0000225 case 'i':
Chris Lattnerd2b7cec2007-02-14 05:52:17 +0000226 case 'v':
227 case 'f':
228 case 'a': {
229 align_type = (*p == 'i' ? INTEGER_ALIGN :
230 (*p == 'f' ? FLOAT_ALIGN :
231 (*p == 'v' ? PACKED_ALIGN : AGGREGATE_ALIGN)));
232 size = (short) atoi(++p);
233 abi_align = atoi(getToken(token, ":").c_str()) / 8;
234 pref_align = atoi(getToken(token, ":").c_str()) / 8;
235 if (pref_align == 0)
236 pref_align = abi_align;
237 setAlignment(align_type, abi_align, pref_align, size);
Owen Anderson571a13f2006-05-12 06:06:55 +0000238 break;
Chris Lattnerd2b7cec2007-02-14 05:52:17 +0000239 }
Owen Anderson8f60c562006-05-12 05:49:47 +0000240 default:
Owen Anderson571a13f2006-05-12 06:06:55 +0000241 break;
Owen Anderson8f60c562006-05-12 05:49:47 +0000242 }
243 }
Owen Anderson1027a532007-01-20 23:07:13 +0000244
Reid Spencer26f23852007-01-26 08:11:39 +0000245 // Unless explicitly specified, the alignments for longs and doubles is
246 // capped by pointer size.
Chris Lattnerd2b7cec2007-02-14 05:52:17 +0000247 // FIXME: Is this still necessary?
248 const TargetAlignElem &long_align = getAlignment(INTEGER_ALIGN, 64);
249 if (long_align.ABIAlign == 0)
250 setAlignment(INTEGER_ALIGN, PointerMemSize, PointerMemSize, 64);
251
252 const TargetAlignElem &double_align = getAlignment(FLOAT_ALIGN, 64);
253 if (double_align.ABIAlign == 0)
254 setAlignment(FLOAT_ALIGN, PointerMemSize, PointerMemSize, 64);
Owen Anderson8f60c562006-05-12 05:49:47 +0000255}
256
Chris Lattner1790d442006-06-16 18:22:52 +0000257TargetData::TargetData(const Module *M) {
Reid Spencer26f23852007-01-26 08:11:39 +0000258 init(M->getDataLayout());
Chris Lattner53a0c382003-04-24 19:09:05 +0000259}
260
Chris Lattnerd2b7cec2007-02-14 05:52:17 +0000261void
262TargetData::setAlignment(AlignTypeEnum align_type, unsigned char abi_align,
263 unsigned char pref_align, short bit_width) {
264 TargetAlignElem elt = TargetAlignElem::get(align_type, abi_align,
265 pref_align, bit_width);
266 std::pair<align_iterator, align_iterator> ins_result =
267 std::equal_range(Alignments.begin(), Alignments.end(), elt);
268 align_iterator I = ins_result.first;
269 if (I->AlignType == align_type && I->TypeBitWidth == bit_width) {
270 // Update the abi, preferred alignments.
271 I->ABIAlign = abi_align;
272 I->PrefAlign = pref_align;
273 } else
274 Alignments.insert(I, elt);
275
276#if 0
277 // Keep around for debugging and testing...
278 align_iterator E = ins_result.second;
279
280 cerr << "setAlignment(" << elt << ")\n";
281 cerr << "I = " << (I - Alignments.begin())
282 << ", E = " << (E - Alignments.begin()) << "\n";
283 std::copy(Alignments.begin(), Alignments.end(),
284 std::ostream_iterator<TargetAlignElem>(*cerr, "\n"));
285 cerr << "=====\n";
286#endif
287}
288
289const TargetAlignElem &
290TargetData::getAlignment(AlignTypeEnum align_type, short bit_width) const
291{
292 std::pair<align_const_iterator, align_const_iterator> find_result =
293 std::equal_range(Alignments.begin(), Alignments.end(),
294 TargetAlignElem::get(align_type, 0, 0,
295 bit_width));
296 align_const_iterator I = find_result.first;
297
298 // Note: This may not be reasonable if variable-width integer sizes are
299 // passed, at which point, more sophisticated searching will need to be done.
300 return *I;
301}
302
Chris Lattnerec6478b2007-02-10 19:43:18 +0000303/// LayoutInfo - The lazy cache of structure layout information maintained by
Chris Lattner9182e3f2007-02-10 20:15:41 +0000304/// TargetData. Note that the struct types must have been free'd before
305/// llvm_shutdown is called (and thus this is deallocated) because all the
306/// targets with cached elements should have been destroyed.
Chris Lattner8dff24f2006-01-14 00:07:34 +0000307///
Chris Lattnerec6478b2007-02-10 19:43:18 +0000308typedef std::pair<const TargetData*,const StructType*> LayoutKey;
Chris Lattnerf6ca09a2007-02-10 20:26:17 +0000309
310struct DenseMapLayoutKeyInfo {
311 static inline LayoutKey getEmptyKey() { return LayoutKey(0, 0); }
312 static inline LayoutKey getTombstoneKey() {
313 return LayoutKey((TargetData*)(intptr_t)-1, 0);
314 }
315 static unsigned getHashValue(const LayoutKey &Val) {
316 return DenseMapKeyInfo<void*>::getHashValue(Val.first) ^
317 DenseMapKeyInfo<void*>::getHashValue(Val.second);
318 }
319 static bool isPod() { return true; }
320};
321
322typedef DenseMap<LayoutKey, StructLayout*, DenseMapLayoutKeyInfo> LayoutInfoTy;
Chris Lattnera12bd032007-02-10 20:18:06 +0000323static ManagedStatic<LayoutInfoTy> LayoutInfo;
Chris Lattner0e7ac162004-02-26 08:02:17 +0000324
325
Chris Lattnere7fb3602001-08-27 16:00:15 +0000326TargetData::~TargetData() {
Chris Lattnerec6478b2007-02-10 19:43:18 +0000327 if (LayoutInfo.isConstructed()) {
Chris Lattner0e7ac162004-02-26 08:02:17 +0000328 // Remove any layouts for this TD.
Chris Lattnera12bd032007-02-10 20:18:06 +0000329 LayoutInfoTy &TheMap = *LayoutInfo;
Chris Lattnerf6ca09a2007-02-10 20:26:17 +0000330 for (LayoutInfoTy::iterator I = TheMap.begin(), E = TheMap.end();
331 I != E; ) {
332 if (I->first.first == this) {
333 I->second->~StructLayout();
334 free(I->second);
335 TheMap.erase(I++);
336 } else {
337 ++I;
338 }
Chris Lattner9182e3f2007-02-10 20:15:41 +0000339 }
Chris Lattner0e7ac162004-02-26 08:02:17 +0000340 }
341}
342
Chris Lattner9182e3f2007-02-10 20:15:41 +0000343const StructLayout *TargetData::getStructLayout(const StructType *Ty) const {
Chris Lattnera12bd032007-02-10 20:18:06 +0000344 LayoutInfoTy &TheMap = *LayoutInfo;
Chris Lattner9182e3f2007-02-10 20:15:41 +0000345
Chris Lattnerf6ca09a2007-02-10 20:26:17 +0000346 StructLayout *&SL = TheMap[LayoutKey(this, Ty)];
347 if (SL) return SL;
Chris Lattner9182e3f2007-02-10 20:15:41 +0000348
349 // Otherwise, create the struct layout. Because it is variable length, we
350 // malloc it, then use placement new.
351 unsigned NumElts = Ty->getNumElements();
352 StructLayout *L =
353 (StructLayout *)malloc(sizeof(StructLayout)+(NumElts-1)*sizeof(uint64_t));
Chris Lattnerf6ca09a2007-02-10 20:26:17 +0000354
355 // Set SL before calling StructLayout's ctor. The ctor could cause other
356 // entries to be added to TheMap, invalidating our reference.
357 SL = L;
358
Chris Lattner9182e3f2007-02-10 20:15:41 +0000359 new (L) StructLayout(Ty, *this);
360
Chris Lattner9182e3f2007-02-10 20:15:41 +0000361 return L;
362}
363
364/// InvalidateStructLayoutInfo - TargetData speculatively caches StructLayout
365/// objects. If a TargetData object is alive when types are being refined and
366/// removed, this method must be called whenever a StructType is removed to
367/// avoid a dangling pointer in this cache.
368void TargetData::InvalidateStructLayoutInfo(const StructType *Ty) const {
369 if (!LayoutInfo.isConstructed()) return; // No cache.
370
Chris Lattnera12bd032007-02-10 20:18:06 +0000371 LayoutInfoTy::iterator I = LayoutInfo->find(LayoutKey(this, Ty));
Chris Lattner9182e3f2007-02-10 20:15:41 +0000372 if (I != LayoutInfo->end()) {
373 I->second->~StructLayout();
374 free(I->second);
375 LayoutInfo->erase(I);
376 }
377}
378
379
Chris Lattnerd2b7cec2007-02-14 05:52:17 +0000380struct hyphen_delimited :
381 public std::iterator<std::output_iterator_tag, void, void, void, void>
382{
383 std::ostream &o;
384
385 hyphen_delimited(std::ostream &os) :
386 o(os)
387 { }
388
389 hyphen_delimited &operator=(const TargetAlignElem &elem)
390 {
391 o << "-" << elem;
392 return *this;
393 }
394
395 hyphen_delimited &operator*()
396 {
397 return *this;
398 }
399
400 hyphen_delimited &operator++()
401 {
402 return *this;
403 }
404};
405
406
Owen Anderson2577c222006-05-12 07:01:44 +0000407std::string TargetData::getStringRepresentation() const {
408 std::stringstream repr;
Chris Lattnerd2b7cec2007-02-14 05:52:17 +0000409
Owen Anderson2577c222006-05-12 07:01:44 +0000410 if (LittleEndian)
411 repr << "e";
412 else
413 repr << "E";
Chris Lattnerd2b7cec2007-02-14 05:52:17 +0000414 repr << "-p:" << (PointerMemSize * 8) << ":" << (PointerABIAlign * 8)
415 << ":" << (PointerPrefAlign * 8);
416 std::copy(Alignments.begin(), Alignments.end(), hyphen_delimited(repr));
Owen Anderson2577c222006-05-12 07:01:44 +0000417 return repr.str();
418}
419
Chris Lattner8dff24f2006-01-14 00:07:34 +0000420
Chris Lattnerd2b7cec2007-02-14 05:52:17 +0000421uint64_t TargetData::getTypeSize(const Type *Ty) const {
Chris Lattnerf59ce922001-12-13 00:46:11 +0000422 assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
Chris Lattnerf70c22b2004-06-17 18:19:28 +0000423 switch (Ty->getTypeID()) {
Chris Lattnere7fb3602001-08-27 16:00:15 +0000424 case Type::LabelTyID:
425 case Type::PointerTyID:
Chris Lattnerd2b7cec2007-02-14 05:52:17 +0000426 return getPointerSize();
Chris Lattnere7fb3602001-08-27 16:00:15 +0000427 case Type::ArrayTyID: {
Chris Lattner59b00672004-07-01 17:32:59 +0000428 const ArrayType *ATy = cast<ArrayType>(Ty);
Chris Lattnerd2b7cec2007-02-14 05:52:17 +0000429 uint64_t Size;
430 unsigned char Alignment;
431 Size = getTypeSize(ATy->getElementType());
432 Alignment = getABITypeAlignment(ATy->getElementType());
Brian Gaekee0e35892004-07-02 07:01:31 +0000433 unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment;
Chris Lattnerd2b7cec2007-02-14 05:52:17 +0000434 return AlignedSize*ATy->getNumElements();
Chris Lattner527efc62004-12-01 17:14:28 +0000435 }
Chris Lattnere7fb3602001-08-27 16:00:15 +0000436 case Type::StructTyID: {
437 // Get the layout annotation... which is lazily created on demand.
Chris Lattnerd2b7cec2007-02-14 05:52:17 +0000438 const StructLayout *Layout = getStructLayout(cast<StructType>(Ty));
439 return Layout->getSizeInBytes();
Chris Lattnere7fb3602001-08-27 16:00:15 +0000440 }
Chris Lattner58092e32007-01-20 22:35:55 +0000441 case Type::IntegerTyID: {
442 unsigned BitWidth = cast<IntegerType>(Ty)->getBitWidth();
443 if (BitWidth <= 8) {
Chris Lattnerd2b7cec2007-02-14 05:52:17 +0000444 return 1;
Chris Lattner58092e32007-01-20 22:35:55 +0000445 } else if (BitWidth <= 16) {
Chris Lattnerd2b7cec2007-02-14 05:52:17 +0000446 return 2;
Chris Lattner58092e32007-01-20 22:35:55 +0000447 } else if (BitWidth <= 32) {
Chris Lattnerd2b7cec2007-02-14 05:52:17 +0000448 return 4;
Chris Lattner58092e32007-01-20 22:35:55 +0000449 } else if (BitWidth <= 64) {
Chris Lattnerd2b7cec2007-02-14 05:52:17 +0000450 return 8;
Chris Lattner58092e32007-01-20 22:35:55 +0000451 } else
452 assert(0 && "Integer types > 64 bits not supported.");
Chris Lattnerd2b7cec2007-02-14 05:52:17 +0000453 break;
Chris Lattner58092e32007-01-20 22:35:55 +0000454 }
455 case Type::VoidTyID:
Chris Lattnerd2b7cec2007-02-14 05:52:17 +0000456 return 1;
Chris Lattner58092e32007-01-20 22:35:55 +0000457 case Type::FloatTyID:
Chris Lattnerd2b7cec2007-02-14 05:52:17 +0000458 return 4;
Chris Lattner58092e32007-01-20 22:35:55 +0000459 case Type::DoubleTyID:
Chris Lattnerd2b7cec2007-02-14 05:52:17 +0000460 return 8;
Chris Lattner58092e32007-01-20 22:35:55 +0000461 case Type::PackedTyID: {
462 const PackedType *PTy = cast<PackedType>(Ty);
Chris Lattnerd2b7cec2007-02-14 05:52:17 +0000463 return PTy->getBitWidth() / 8;
Chris Lattner58092e32007-01-20 22:35:55 +0000464 }
Chris Lattner58092e32007-01-20 22:35:55 +0000465 default:
Chris Lattnerd2b7cec2007-02-14 05:52:17 +0000466 assert(0 && "TargetData::getTypeSize(): Unsupported type");
467 break;
Chris Lattner58092e32007-01-20 22:35:55 +0000468 }
Chris Lattnerd2b7cec2007-02-14 05:52:17 +0000469 return 0;
Chris Lattnere7fb3602001-08-27 16:00:15 +0000470}
471
Reid Spencer7c292432007-01-20 23:32:04 +0000472uint64_t TargetData::getTypeSizeInBits(const Type *Ty) const {
473 if (Ty->isInteger())
474 return cast<IntegerType>(Ty)->getBitWidth();
Chris Lattnerd2b7cec2007-02-14 05:52:17 +0000475 else
476 return getTypeSize(Ty) * 8;
Reid Spencer7c292432007-01-20 23:32:04 +0000477}
478
Chris Lattnerd2b7cec2007-02-14 05:52:17 +0000479
480/*!
481 \param abi_or_pref Flag that determines which alignment is returned. true
482 returns the ABI alignment, false returns the preferred alignment.
483 \param Ty The underlying type for which alignment is determined.
484
485 Get the ABI (\a abi_or_pref == true) or preferred alignment (\a abi_or_pref
486 == false) for the requested type \a Ty.
487 */
488unsigned char TargetData::getAlignment(const Type *Ty, bool abi_or_pref) const
489{
490 int AlignType = -1;
491
492 assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
493 switch (Ty->getTypeID()) {
494 /* Early escape for the non-numeric types */
495 case Type::LabelTyID:
496 case Type::PointerTyID:
497 return (abi_or_pref
498 ? getPointerABIAlignment()
499 : getPointerPrefAlignment());
500 case Type::ArrayTyID: {
501 const ArrayType *ATy = cast<ArrayType>(Ty);
502 return (abi_or_pref
503 ? getABITypeAlignment(ATy->getElementType())
504 : getPrefTypeAlignment(ATy->getElementType()));
505 }
506 case Type::StructTyID: {
507 // Get the layout annotation... which is lazily created on demand.
508 const StructLayout *Layout = getStructLayout(cast<StructType>(Ty));
509 const TargetAlignElem &elem = getAlignment(AGGREGATE_ALIGN, 0);
510 assert(validAlignment(elem)
511 && "Aggregate alignment return invalid in getAlignment");
512 if (abi_or_pref) {
513 return (elem.ABIAlign < Layout->getAlignment()
514 ? Layout->StructAlignment
515 : elem.ABIAlign);
516 } else {
517 return (elem.PrefAlign < Layout->getAlignment()
518 ? Layout->StructAlignment
519 : elem.PrefAlign);
520 }
521 }
522 case Type::IntegerTyID:
523 case Type::VoidTyID:
524 AlignType = INTEGER_ALIGN;
525 break;
526 case Type::FloatTyID:
527 case Type::DoubleTyID:
528 AlignType = FLOAT_ALIGN;
529 break;
530 case Type::PackedTyID:
531 AlignType = PACKED_ALIGN;
532 break;
533 default:
534 assert(0 && "Bad type for getAlignment!!!");
535 break;
536 }
537
538 const TargetAlignElem &elem = getAlignment((AlignTypeEnum) AlignType,
539 getTypeSize(Ty) * 8);
540 if (validAlignment(elem))
541 return (abi_or_pref ? elem.ABIAlign : elem.PrefAlign);
542 else {
543 cerr << "TargetData::getAlignment: align type " << AlignType
544 << " size " << getTypeSize(Ty) << " not found in Alignments.\n";
545 abort();
546 /*NOTREACHED*/
547 return 0;
548 }
Chris Lattner58092e32007-01-20 22:35:55 +0000549}
550
Chris Lattnerd2b7cec2007-02-14 05:52:17 +0000551unsigned char TargetData::getABITypeAlignment(const Type *Ty) const {
552 return getAlignment(Ty, true);
553}
554
555unsigned char TargetData::getPrefTypeAlignment(const Type *Ty) const {
556 return getAlignment(Ty, false);
Chris Lattnere7fb3602001-08-27 16:00:15 +0000557}
558
Evan Chengde268f72007-01-24 07:03:39 +0000559unsigned char TargetData::getPreferredTypeAlignmentShift(const Type *Ty) const {
Chris Lattnerd2b7cec2007-02-14 05:52:17 +0000560 unsigned Align = (unsigned) getPrefTypeAlignment(Ty);
Chris Lattnerd2b0bb42004-08-17 19:13:00 +0000561 assert(!(Align & (Align-1)) && "Alignment is not a power of two!");
Chris Lattner0561b3f2005-08-02 19:26:06 +0000562 return Log2_32(Align);
Chris Lattnerd2b0bb42004-08-17 19:13:00 +0000563}
564
Chris Lattnerf0453282003-12-22 05:01:15 +0000565/// getIntPtrType - Return an unsigned integer type that is the same size or
566/// greater to the host pointer size.
567const Type *TargetData::getIntPtrType() const {
568 switch (getPointerSize()) {
569 default: assert(0 && "Unknown pointer size!");
Reid Spencer47857812006-12-31 05:55:36 +0000570 case 2: return Type::Int16Ty;
571 case 4: return Type::Int32Ty;
572 case 8: return Type::Int64Ty;
Chris Lattnerf0453282003-12-22 05:01:15 +0000573 }
574}
575
576
Chris Lattnerddce8d22007-02-10 19:33:15 +0000577uint64_t TargetData::getIndexedOffset(const Type *ptrTy, Value* const* Indices,
578 unsigned NumIndices) const {
Vikram S. Adveed0030e2002-08-04 20:52:39 +0000579 const Type *Ty = ptrTy;
580 assert(isa<PointerType>(Ty) && "Illegal argument for getIndexedOffset()");
Vikram S. Advef66723f2002-05-19 15:28:02 +0000581 uint64_t Result = 0;
Chris Lattnere7fb3602001-08-27 16:00:15 +0000582
Chris Lattnerddce8d22007-02-10 19:33:15 +0000583 generic_gep_type_iterator<Value* const*>
584 TI = gep_type_begin(ptrTy, Indices, Indices+NumIndices);
585 for (unsigned CurIDX = 0; CurIDX != NumIndices; ++CurIDX, ++TI) {
Chris Lattner28977af2004-04-05 01:30:19 +0000586 if (const StructType *STy = dyn_cast<StructType>(*TI)) {
Chris Lattnerddce8d22007-02-10 19:33:15 +0000587 assert(Indices[CurIDX]->getType() == Type::Int32Ty &&"Illegal struct idx");
588 unsigned FieldNo = cast<ConstantInt>(Indices[CurIDX])->getZExtValue();
Chris Lattnere7fb3602001-08-27 16:00:15 +0000589
590 // Get structure layout information...
591 const StructLayout *Layout = getStructLayout(STy);
592
593 // Add in the offset, as calculated by the structure layout info...
Chris Lattnerb1919e22007-02-10 19:55:17 +0000594 Result += Layout->getElementOffset(FieldNo);
Vikram S. Adveed0030e2002-08-04 20:52:39 +0000595
Chris Lattnere7fb3602001-08-27 16:00:15 +0000596 // Update Ty to refer to current element
Chris Lattnerd21cd802004-02-09 04:37:31 +0000597 Ty = STy->getElementType(FieldNo);
Chris Lattner28977af2004-04-05 01:30:19 +0000598 } else {
599 // Update Ty to refer to current element
600 Ty = cast<SequentialType>(Ty)->getElementType();
601
602 // Get the array index and the size of each array element.
Chris Lattnerddce8d22007-02-10 19:33:15 +0000603 int64_t arrayIdx = cast<ConstantInt>(Indices[CurIDX])->getSExtValue();
Chris Lattner28977af2004-04-05 01:30:19 +0000604 Result += arrayIdx * (int64_t)getTypeSize(Ty);
Chris Lattnere7fb3602001-08-27 16:00:15 +0000605 }
606 }
607
608 return Result;
609}
Brian Gaeked0fde302003-11-11 22:41:34 +0000610
Devang Patelf9c197e2006-10-24 20:32:14 +0000611/// getPreferredAlignmentLog - Return the preferred alignment of the
612/// specified global, returned in log form. This includes an explicitly
613/// requested alignment (if the global has one).
614unsigned TargetData::getPreferredAlignmentLog(const GlobalVariable *GV) const {
615 const Type *ElemType = GV->getType()->getElementType();
Evan Chengde268f72007-01-24 07:03:39 +0000616 unsigned Alignment = getPreferredTypeAlignmentShift(ElemType);
Devang Patelf9c197e2006-10-24 20:32:14 +0000617 if (GV->getAlignment() > (1U << Alignment))
618 Alignment = Log2_32(GV->getAlignment());
619
620 if (GV->hasInitializer()) {
Devang Patelf9c197e2006-10-24 20:32:14 +0000621 if (Alignment < 4) {
622 // If the global is not external, see if it is large. If so, give it a
623 // larger alignment.
624 if (getTypeSize(ElemType) > 128)
625 Alignment = 4; // 16-byte alignment.
626 }
627 }
628 return Alignment;
629}