blob: 26a30a7809798dbc643e7af5c65516eeeb1783cb [file] [log] [blame]
Chris Lattner53bbf072001-08-27 16:00:15 +00001//===-- TargetData.cpp - Data size & alignment routines --------------------==//
Misha Brukman10468d82005-04-21 22:55:34 +00002//
John Criswell482202a2003-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 Brukman10468d82005-04-21 22:55:34 +00007//
John Criswell482202a2003-10-20 19:43:21 +00008//===----------------------------------------------------------------------===//
Chris Lattner53bbf072001-08-27 16:00:15 +00009//
10// This file defines target properties related to datatype size/offset/alignment
Chris Lattner7140e462004-02-26 08:02:17 +000011// information.
Chris Lattner53bbf072001-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. Adve6cefc702001-09-18 12:58:33 +000019#include "llvm/Target/TargetData.h"
Chris Lattner42516ba2003-04-24 19:09:05 +000020#include "llvm/Module.h"
Chris Lattner53bbf072001-08-27 16:00:15 +000021#include "llvm/DerivedTypes.h"
Chris Lattnerca142372002-04-28 19:55:58 +000022#include "llvm/Constants.h"
Chris Lattner69193f92004-04-05 01:30:19 +000023#include "llvm/Support/GetElementPtrTypeIterator.h"
Reid Spencer7c16caa2004-09-01 22:55:40 +000024#include "llvm/Support/MathExtras.h"
Chris Lattner1e692e82007-02-10 19:43:18 +000025#include "llvm/Support/ManagedStatic.h"
Chris Lattnerfed6f0e2007-02-10 20:26:17 +000026#include "llvm/ADT/DenseMap.h"
Owen Anderson8d7774c2006-05-12 05:49:47 +000027#include "llvm/ADT/StringExtras.h"
Chris Lattner34340042005-03-13 19:04:41 +000028#include <algorithm>
Owen Anderson8d7774c2006-05-12 05:49:47 +000029#include <cstdlib>
Owen Anderson5fea9f02006-05-12 07:01:44 +000030#include <sstream>
Chris Lattnerbb661c12003-12-22 05:01:15 +000031using namespace llvm;
Brian Gaeke960707c2003-11-11 22:41:34 +000032
Misha Brukman7eb05a12003-08-18 14:43:39 +000033// Handle the Pass registration stuff necessary to use TargetData's.
Chris Lattner09cfdcb2002-09-25 23:46:55 +000034namespace {
35 // Register the default SparcV9 implementation...
36 RegisterPass<TargetData> X("targetdata", "Target Data Layout");
37}
38
Chris Lattner53bbf072001-08-27 16:00:15 +000039//===----------------------------------------------------------------------===//
Chris Lattner7140e462004-02-26 08:02:17 +000040// Support for StructLayout
Chris Lattner53bbf072001-08-27 16:00:15 +000041//===----------------------------------------------------------------------===//
42
Chris Lattner7140e462004-02-26 08:02:17 +000043StructLayout::StructLayout(const StructType *ST, const TargetData &TD) {
Chris Lattner53bbf072001-08-27 16:00:15 +000044 StructAlignment = 0;
45 StructSize = 0;
Chris Lattnere472f9c2007-02-10 20:15:41 +000046 NumElements = ST->getNumElements();
Chris Lattner53bbf072001-08-27 16:00:15 +000047
48 // Loop over each of the elements, placing them in memory...
Chris Lattnere472f9c2007-02-10 20:15:41 +000049 for (unsigned i = 0, e = NumElements; i != e; ++i) {
50 const Type *Ty = ST->getElementType(i);
Vikram S. Adve8b831742002-05-19 15:28:02 +000051 unsigned TyAlign;
52 uint64_t TySize;
Chris Lattner945e4372007-02-14 05:52:17 +000053 TyAlign = (unsigned) TD.getABITypeAlignment(Ty);
54 TySize = (unsigned) TD.getTypeSize(Ty);
Chris Lattner53bbf072001-08-27 16:00:15 +000055
Misha Brukman7eb05a12003-08-18 14:43:39 +000056 // Add padding if necessary to make the data element aligned properly...
Chris Lattner53bbf072001-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 Lattner7f74a562002-01-20 22:54:45 +000061 StructAlignment = std::max(TyAlign, StructAlignment);
Chris Lattner53bbf072001-08-27 16:00:15 +000062
Chris Lattnere472f9c2007-02-10 20:15:41 +000063 MemberOffsets[i] = StructSize;
Vikram S. Adve8b831742002-05-19 15:28:02 +000064 StructSize += TySize; // Consume space for this data item
Chris Lattner53bbf072001-08-27 16:00:15 +000065 }
66
Chris Lattner6532e422003-05-21 18:08:44 +000067 // Empty structures have alignment of 1 byte.
68 if (StructAlignment == 0) StructAlignment = 1;
69
Chris Lattner53bbf072001-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 Lattner53bbf072001-08-27 16:00:15 +000074}
75
Chris Lattner34340042005-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 Lattnere472f9c2007-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 Lattner34340042005-03-13 19:04:41 +000083 --SI;
84 assert(*SI <= Offset && "upper_bound didn't work");
Chris Lattnere472f9c2007-02-10 20:15:41 +000085 assert((SI == &MemberOffsets[0] || *(SI-1) < Offset) &&
86 (SI+1 == &MemberOffsets[NumElements] || *(SI+1) > Offset) &&
Chris Lattner34340042005-03-13 19:04:41 +000087 "Upper bound didn't work!");
Chris Lattnere472f9c2007-02-10 20:15:41 +000088 return SI-&MemberOffsets[0];
Chris Lattner34340042005-03-13 19:04:41 +000089}
90
Chris Lattner53bbf072001-08-27 16:00:15 +000091//===----------------------------------------------------------------------===//
Chris Lattner945e4372007-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 Lattner53bbf072001-08-27 16:00:15 +0000142// TargetData Class Implementation
143//===----------------------------------------------------------------------===//
144
Chris Lattner945e4372007-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 Lattner7f043b52006-06-16 18:11:26 +0000181void TargetData::init(const std::string &TargetDescription) {
Owen Anderson8d7774c2006-05-12 05:49:47 +0000182 std::string temp = TargetDescription;
183
184 LittleEndian = false;
Chris Lattner50ee0e42007-01-20 22:35:55 +0000185 PointerMemSize = 8;
Chris Lattner945e4372007-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 Anderson8d7774c2006-05-12 05:49:47 +0000200
Owen Anderson88812b52006-05-20 00:24:56 +0000201 while (!temp.empty()) {
Owen Anderson8d7774c2006-05-12 05:49:47 +0000202 std::string token = getToken(temp, "-");
203
Chris Lattner945e4372007-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 Anderson8d7774c2006-05-12 05:49:47 +0000212 case 'E':
Owen Andersond7c77b82006-05-12 06:06:55 +0000213 LittleEndian = false;
214 break;
Owen Anderson8d7774c2006-05-12 05:49:47 +0000215 case 'e':
Owen Andersond7c77b82006-05-12 06:06:55 +0000216 LittleEndian = true;
217 break;
Owen Anderson8d7774c2006-05-12 05:49:47 +0000218 case 'p':
Chris Lattner50ee0e42007-01-20 22:35:55 +0000219 PointerMemSize = atoi(getToken(token,":").c_str()) / 8;
Chris Lattner945e4372007-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 Andersond7c77b82006-05-12 06:06:55 +0000224 break;
Owen Anderson8d7774c2006-05-12 05:49:47 +0000225 case 'i':
Chris Lattner945e4372007-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 Andersond7c77b82006-05-12 06:06:55 +0000238 break;
Chris Lattner945e4372007-02-14 05:52:17 +0000239 }
Owen Anderson8d7774c2006-05-12 05:49:47 +0000240 default:
Owen Andersond7c77b82006-05-12 06:06:55 +0000241 break;
Owen Anderson8d7774c2006-05-12 05:49:47 +0000242 }
243 }
Owen Andersone52a2352007-01-20 23:07:13 +0000244
Reid Spencer3ac38e92007-01-26 08:11:39 +0000245 // Unless explicitly specified, the alignments for longs and doubles is
246 // capped by pointer size.
Chris Lattner945e4372007-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 Anderson8d7774c2006-05-12 05:49:47 +0000255}
256
Chris Lattnerf3b5b922006-06-16 18:22:52 +0000257TargetData::TargetData(const Module *M) {
Reid Spencer3ac38e92007-01-26 08:11:39 +0000258 init(M->getDataLayout());
Chris Lattner42516ba2003-04-24 19:09:05 +0000259}
260
Chris Lattner945e4372007-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 Lattner1e692e82007-02-10 19:43:18 +0000303/// LayoutInfo - The lazy cache of structure layout information maintained by
Chris Lattnere472f9c2007-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 Lattnera4de9ba2006-01-14 00:07:34 +0000307///
Chris Lattner1e692e82007-02-10 19:43:18 +0000308typedef std::pair<const TargetData*,const StructType*> LayoutKey;
Chris Lattnerfed6f0e2007-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 Lattner22206712007-02-10 20:18:06 +0000323static ManagedStatic<LayoutInfoTy> LayoutInfo;
Chris Lattner7140e462004-02-26 08:02:17 +0000324
325
Chris Lattner53bbf072001-08-27 16:00:15 +0000326TargetData::~TargetData() {
Chris Lattner1e692e82007-02-10 19:43:18 +0000327 if (LayoutInfo.isConstructed()) {
Chris Lattner7140e462004-02-26 08:02:17 +0000328 // Remove any layouts for this TD.
Chris Lattner22206712007-02-10 20:18:06 +0000329 LayoutInfoTy &TheMap = *LayoutInfo;
Chris Lattnerfed6f0e2007-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 Lattnere472f9c2007-02-10 20:15:41 +0000339 }
Chris Lattner7140e462004-02-26 08:02:17 +0000340 }
341}
342
Chris Lattnere472f9c2007-02-10 20:15:41 +0000343const StructLayout *TargetData::getStructLayout(const StructType *Ty) const {
Chris Lattner22206712007-02-10 20:18:06 +0000344 LayoutInfoTy &TheMap = *LayoutInfo;
Chris Lattnere472f9c2007-02-10 20:15:41 +0000345
Chris Lattnerfed6f0e2007-02-10 20:26:17 +0000346 StructLayout *&SL = TheMap[LayoutKey(this, Ty)];
347 if (SL) return SL;
Chris Lattnere472f9c2007-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 Lattnerfed6f0e2007-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 Lattnere472f9c2007-02-10 20:15:41 +0000359 new (L) StructLayout(Ty, *this);
360
Chris Lattnere472f9c2007-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 Lattner22206712007-02-10 20:18:06 +0000371 LayoutInfoTy::iterator I = LayoutInfo->find(LayoutKey(this, Ty));
Chris Lattnere472f9c2007-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 Lattner945e4372007-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 Anderson5fea9f02006-05-12 07:01:44 +0000407std::string TargetData::getStringRepresentation() const {
408 std::stringstream repr;
Chris Lattner945e4372007-02-14 05:52:17 +0000409
Owen Anderson5fea9f02006-05-12 07:01:44 +0000410 if (LittleEndian)
411 repr << "e";
412 else
413 repr << "E";
Chris Lattner945e4372007-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 Anderson5fea9f02006-05-12 07:01:44 +0000417 return repr.str();
418}
419
Chris Lattnera4de9ba2006-01-14 00:07:34 +0000420
Chris Lattner945e4372007-02-14 05:52:17 +0000421uint64_t TargetData::getTypeSize(const Type *Ty) const {
Chris Lattner6650d182001-12-13 00:46:11 +0000422 assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
Chris Lattner6b727592004-06-17 18:19:28 +0000423 switch (Ty->getTypeID()) {
Chris Lattner53bbf072001-08-27 16:00:15 +0000424 case Type::LabelTyID:
425 case Type::PointerTyID:
Chris Lattner945e4372007-02-14 05:52:17 +0000426 return getPointerSize();
Chris Lattner53bbf072001-08-27 16:00:15 +0000427 case Type::ArrayTyID: {
Chris Lattner18a08e72004-07-01 17:32:59 +0000428 const ArrayType *ATy = cast<ArrayType>(Ty);
Chris Lattner945e4372007-02-14 05:52:17 +0000429 uint64_t Size;
430 unsigned char Alignment;
431 Size = getTypeSize(ATy->getElementType());
432 Alignment = getABITypeAlignment(ATy->getElementType());
Brian Gaekef6d24712004-07-02 07:01:31 +0000433 unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment;
Chris Lattner945e4372007-02-14 05:52:17 +0000434 return AlignedSize*ATy->getNumElements();
Chris Lattnere58bf092004-12-01 17:14:28 +0000435 }
Chris Lattner53bbf072001-08-27 16:00:15 +0000436 case Type::StructTyID: {
437 // Get the layout annotation... which is lazily created on demand.
Chris Lattner945e4372007-02-14 05:52:17 +0000438 const StructLayout *Layout = getStructLayout(cast<StructType>(Ty));
439 return Layout->getSizeInBytes();
Chris Lattner53bbf072001-08-27 16:00:15 +0000440 }
Chris Lattner50ee0e42007-01-20 22:35:55 +0000441 case Type::IntegerTyID: {
442 unsigned BitWidth = cast<IntegerType>(Ty)->getBitWidth();
443 if (BitWidth <= 8) {
Chris Lattner945e4372007-02-14 05:52:17 +0000444 return 1;
Chris Lattner50ee0e42007-01-20 22:35:55 +0000445 } else if (BitWidth <= 16) {
Chris Lattner945e4372007-02-14 05:52:17 +0000446 return 2;
Chris Lattner50ee0e42007-01-20 22:35:55 +0000447 } else if (BitWidth <= 32) {
Chris Lattner945e4372007-02-14 05:52:17 +0000448 return 4;
Chris Lattner50ee0e42007-01-20 22:35:55 +0000449 } else if (BitWidth <= 64) {
Chris Lattner945e4372007-02-14 05:52:17 +0000450 return 8;
Chris Lattner50ee0e42007-01-20 22:35:55 +0000451 } else
452 assert(0 && "Integer types > 64 bits not supported.");
Chris Lattner945e4372007-02-14 05:52:17 +0000453 break;
Chris Lattner50ee0e42007-01-20 22:35:55 +0000454 }
455 case Type::VoidTyID:
Chris Lattner945e4372007-02-14 05:52:17 +0000456 return 1;
Chris Lattner50ee0e42007-01-20 22:35:55 +0000457 case Type::FloatTyID:
Chris Lattner945e4372007-02-14 05:52:17 +0000458 return 4;
Chris Lattner50ee0e42007-01-20 22:35:55 +0000459 case Type::DoubleTyID:
Chris Lattner945e4372007-02-14 05:52:17 +0000460 return 8;
Chris Lattner50ee0e42007-01-20 22:35:55 +0000461 case Type::PackedTyID: {
462 const PackedType *PTy = cast<PackedType>(Ty);
Chris Lattner945e4372007-02-14 05:52:17 +0000463 return PTy->getBitWidth() / 8;
Chris Lattner50ee0e42007-01-20 22:35:55 +0000464 }
Chris Lattner50ee0e42007-01-20 22:35:55 +0000465 default:
Chris Lattner945e4372007-02-14 05:52:17 +0000466 assert(0 && "TargetData::getTypeSize(): Unsupported type");
467 break;
Chris Lattner50ee0e42007-01-20 22:35:55 +0000468 }
Chris Lattner945e4372007-02-14 05:52:17 +0000469 return 0;
Chris Lattner53bbf072001-08-27 16:00:15 +0000470}
471
Reid Spencer22391632007-01-20 23:32:04 +0000472uint64_t TargetData::getTypeSizeInBits(const Type *Ty) const {
473 if (Ty->isInteger())
474 return cast<IntegerType>(Ty)->getBitWidth();
Chris Lattner945e4372007-02-14 05:52:17 +0000475 else
476 return getTypeSize(Ty) * 8;
Reid Spencer22391632007-01-20 23:32:04 +0000477}
478
Chris Lattner945e4372007-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 Lattner50ee0e42007-01-20 22:35:55 +0000549}
550
Chris Lattner945e4372007-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 Lattner53bbf072001-08-27 16:00:15 +0000557}
558
Evan Chengf5c96fa2007-01-24 07:03:39 +0000559unsigned char TargetData::getPreferredTypeAlignmentShift(const Type *Ty) const {
Chris Lattner945e4372007-02-14 05:52:17 +0000560 unsigned Align = (unsigned) getPrefTypeAlignment(Ty);
Chris Lattner0c2ab8a2004-08-17 19:13:00 +0000561 assert(!(Align & (Align-1)) && "Alignment is not a power of two!");
Chris Lattner6667bdb2005-08-02 19:26:06 +0000562 return Log2_32(Align);
Chris Lattner0c2ab8a2004-08-17 19:13:00 +0000563}
564
Chris Lattnerbb661c12003-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 Spencere63b6512006-12-31 05:55:36 +0000570 case 2: return Type::Int16Ty;
571 case 4: return Type::Int32Ty;
572 case 8: return Type::Int64Ty;
Chris Lattnerbb661c12003-12-22 05:01:15 +0000573 }
574}
575
576
Chris Lattner336e3962007-02-10 19:33:15 +0000577uint64_t TargetData::getIndexedOffset(const Type *ptrTy, Value* const* Indices,
578 unsigned NumIndices) const {
Vikram S. Adve71895b22002-08-04 20:52:39 +0000579 const Type *Ty = ptrTy;
580 assert(isa<PointerType>(Ty) && "Illegal argument for getIndexedOffset()");
Vikram S. Adve8b831742002-05-19 15:28:02 +0000581 uint64_t Result = 0;
Chris Lattner53bbf072001-08-27 16:00:15 +0000582
Chris Lattner336e3962007-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 Lattner69193f92004-04-05 01:30:19 +0000586 if (const StructType *STy = dyn_cast<StructType>(*TI)) {
Chris Lattner336e3962007-02-10 19:33:15 +0000587 assert(Indices[CurIDX]->getType() == Type::Int32Ty &&"Illegal struct idx");
588 unsigned FieldNo = cast<ConstantInt>(Indices[CurIDX])->getZExtValue();
Chris Lattner53bbf072001-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 Lattnerc473d8e2007-02-10 19:55:17 +0000594 Result += Layout->getElementOffset(FieldNo);
Vikram S. Adve71895b22002-08-04 20:52:39 +0000595
Chris Lattner53bbf072001-08-27 16:00:15 +0000596 // Update Ty to refer to current element
Chris Lattnerac6db752004-02-09 04:37:31 +0000597 Ty = STy->getElementType(FieldNo);
Chris Lattner69193f92004-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 Lattner336e3962007-02-10 19:33:15 +0000603 int64_t arrayIdx = cast<ConstantInt>(Indices[CurIDX])->getSExtValue();
Chris Lattner69193f92004-04-05 01:30:19 +0000604 Result += arrayIdx * (int64_t)getTypeSize(Ty);
Chris Lattner53bbf072001-08-27 16:00:15 +0000605 }
606 }
607
608 return Result;
609}
Brian Gaeke960707c2003-11-11 22:41:34 +0000610
Devang Patel71b99292006-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 Chengf5c96fa2007-01-24 07:03:39 +0000616 unsigned Alignment = getPreferredTypeAlignmentShift(ElemType);
Devang Patel71b99292006-10-24 20:32:14 +0000617 if (GV->getAlignment() > (1U << Alignment))
618 Alignment = Log2_32(GV->getAlignment());
619
620 if (GV->hasInitializer()) {
Devang Patel71b99292006-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}