blob: c5b986eb7284a6832c44f82562f93b21a461168d [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"
Owen Anderson8f60c562006-05-12 05:49:47 +000026#include "llvm/ADT/StringExtras.h"
Chris Lattnere7ea48c2005-03-13 19:04:41 +000027#include <algorithm>
Owen Anderson8f60c562006-05-12 05:49:47 +000028#include <cstdlib>
Owen Anderson2577c222006-05-12 07:01:44 +000029#include <sstream>
Chris Lattnerf0453282003-12-22 05:01:15 +000030using namespace llvm;
Brian Gaeked0fde302003-11-11 22:41:34 +000031
Misha Brukman5560c9d2003-08-18 14:43:39 +000032// Handle the Pass registration stuff necessary to use TargetData's.
Chris Lattneraa31ad02002-09-25 23:46:55 +000033namespace {
34 // Register the default SparcV9 implementation...
35 RegisterPass<TargetData> X("targetdata", "Target Data Layout");
36}
37
Chris Lattner58092e32007-01-20 22:35:55 +000038static inline void getTypeInfoABI(const Type *Ty, const TargetData *TD,
39 uint64_t &Size, unsigned char &Alignment);
40
41static inline void getTypeInfoPref(const Type *Ty, const TargetData *TD,
42 uint64_t &Size, unsigned char &Alignment);
Chris Lattnere7fb3602001-08-27 16:00:15 +000043
44//===----------------------------------------------------------------------===//
Chris Lattner0e7ac162004-02-26 08:02:17 +000045// Support for StructLayout
Chris Lattnere7fb3602001-08-27 16:00:15 +000046//===----------------------------------------------------------------------===//
47
Chris Lattner0e7ac162004-02-26 08:02:17 +000048StructLayout::StructLayout(const StructType *ST, const TargetData &TD) {
Chris Lattnere7fb3602001-08-27 16:00:15 +000049 StructAlignment = 0;
50 StructSize = 0;
Chris Lattner9182e3f2007-02-10 20:15:41 +000051 NumElements = ST->getNumElements();
Chris Lattnere7fb3602001-08-27 16:00:15 +000052
53 // Loop over each of the elements, placing them in memory...
Chris Lattner9182e3f2007-02-10 20:15:41 +000054 for (unsigned i = 0, e = NumElements; i != e; ++i) {
55 const Type *Ty = ST->getElementType(i);
Chris Lattnere7fb3602001-08-27 16:00:15 +000056 unsigned char A;
Vikram S. Advef66723f2002-05-19 15:28:02 +000057 unsigned TyAlign;
58 uint64_t TySize;
Chris Lattner58092e32007-01-20 22:35:55 +000059 getTypeInfoABI(Ty, &TD, TySize, A);
Andrew Lenharth38ecbf12006-12-08 18:06:16 +000060 TyAlign = ST->isPacked() ? 1 : A;
Chris Lattnere7fb3602001-08-27 16:00:15 +000061
Misha Brukman5560c9d2003-08-18 14:43:39 +000062 // Add padding if necessary to make the data element aligned properly...
Chris Lattnere7fb3602001-08-27 16:00:15 +000063 if (StructSize % TyAlign != 0)
64 StructSize = (StructSize/TyAlign + 1) * TyAlign; // Add padding...
65
66 // Keep track of maximum alignment constraint
Chris Lattner697954c2002-01-20 22:54:45 +000067 StructAlignment = std::max(TyAlign, StructAlignment);
Chris Lattnere7fb3602001-08-27 16:00:15 +000068
Chris Lattner9182e3f2007-02-10 20:15:41 +000069 MemberOffsets[i] = StructSize;
Vikram S. Advef66723f2002-05-19 15:28:02 +000070 StructSize += TySize; // Consume space for this data item
Chris Lattnere7fb3602001-08-27 16:00:15 +000071 }
72
Chris Lattner4e840d42003-05-21 18:08:44 +000073 // Empty structures have alignment of 1 byte.
74 if (StructAlignment == 0) StructAlignment = 1;
75
Chris Lattnere7fb3602001-08-27 16:00:15 +000076 // Add padding to the end of the struct so that it could be put in an array
77 // and all array elements would be aligned correctly.
78 if (StructSize % StructAlignment != 0)
79 StructSize = (StructSize/StructAlignment + 1) * StructAlignment;
Chris Lattnere7fb3602001-08-27 16:00:15 +000080}
81
Chris Lattnere7ea48c2005-03-13 19:04:41 +000082
83/// getElementContainingOffset - Given a valid offset into the structure,
84/// return the structure index that contains it.
85unsigned StructLayout::getElementContainingOffset(uint64_t Offset) const {
Chris Lattner9182e3f2007-02-10 20:15:41 +000086 const uint64_t *SI =
87 std::upper_bound(&MemberOffsets[0], &MemberOffsets[NumElements], Offset);
88 assert(SI != &MemberOffsets[0] && "Offset not in structure type!");
Chris Lattnere7ea48c2005-03-13 19:04:41 +000089 --SI;
90 assert(*SI <= Offset && "upper_bound didn't work");
Chris Lattner9182e3f2007-02-10 20:15:41 +000091 assert((SI == &MemberOffsets[0] || *(SI-1) < Offset) &&
92 (SI+1 == &MemberOffsets[NumElements] || *(SI+1) > Offset) &&
Chris Lattnere7ea48c2005-03-13 19:04:41 +000093 "Upper bound didn't work!");
Chris Lattner9182e3f2007-02-10 20:15:41 +000094 return SI-&MemberOffsets[0];
Chris Lattnere7ea48c2005-03-13 19:04:41 +000095}
96
Chris Lattnere7fb3602001-08-27 16:00:15 +000097//===----------------------------------------------------------------------===//
98// TargetData Class Implementation
99//===----------------------------------------------------------------------===//
100
Chris Lattneracbc07a2006-06-16 18:11:26 +0000101void TargetData::init(const std::string &TargetDescription) {
Owen Anderson8f60c562006-05-12 05:49:47 +0000102 std::string temp = TargetDescription;
103
104 LittleEndian = false;
Chris Lattner58092e32007-01-20 22:35:55 +0000105 PointerMemSize = 8;
106 PointerABIAlignment = 8;
Owen Anderson1027a532007-01-20 23:07:13 +0000107 DoubleABIAlignment = 0;
Chris Lattner58092e32007-01-20 22:35:55 +0000108 FloatABIAlignment = 4;
Owen Anderson1027a532007-01-20 23:07:13 +0000109 LongABIAlignment = 0;
Chris Lattner58092e32007-01-20 22:35:55 +0000110 IntABIAlignment = 4;
111 ShortABIAlignment = 2;
112 ByteABIAlignment = 1;
113 BoolABIAlignment = 1;
114 BoolPrefAlignment = BoolABIAlignment;
115 BytePrefAlignment = ByteABIAlignment;
116 ShortPrefAlignment = ShortABIAlignment;
117 IntPrefAlignment = IntABIAlignment;
Owen Anderson1027a532007-01-20 23:07:13 +0000118 LongPrefAlignment = 8;
Chris Lattner58092e32007-01-20 22:35:55 +0000119 FloatPrefAlignment = FloatABIAlignment;
Owen Anderson1027a532007-01-20 23:07:13 +0000120 DoublePrefAlignment = 8;
Chris Lattner58092e32007-01-20 22:35:55 +0000121 PointerPrefAlignment = PointerABIAlignment;
122 AggMinPrefAlignment = 0;
Owen Anderson8f60c562006-05-12 05:49:47 +0000123
Owen Andersond988b322006-05-20 00:24:56 +0000124 while (!temp.empty()) {
Owen Anderson8f60c562006-05-12 05:49:47 +0000125 std::string token = getToken(temp, "-");
126
Owen Anderson84cc6db2006-05-17 21:56:02 +0000127 char signal = getToken(token, ":")[0];
128
129 switch(signal) {
Owen Anderson8f60c562006-05-12 05:49:47 +0000130 case 'E':
Owen Anderson571a13f2006-05-12 06:06:55 +0000131 LittleEndian = false;
132 break;
Owen Anderson8f60c562006-05-12 05:49:47 +0000133 case 'e':
Owen Anderson571a13f2006-05-12 06:06:55 +0000134 LittleEndian = true;
135 break;
Owen Anderson8f60c562006-05-12 05:49:47 +0000136 case 'p':
Chris Lattner58092e32007-01-20 22:35:55 +0000137 PointerMemSize = atoi(getToken(token,":").c_str()) / 8;
138 PointerABIAlignment = atoi(getToken(token,":").c_str()) / 8;
139 PointerPrefAlignment = atoi(getToken(token,":").c_str()) / 8;
140 if (PointerPrefAlignment == 0)
141 PointerPrefAlignment = PointerABIAlignment;
Owen Anderson571a13f2006-05-12 06:06:55 +0000142 break;
Owen Anderson8f60c562006-05-12 05:49:47 +0000143 case 'd':
Chris Lattner58092e32007-01-20 22:35:55 +0000144 DoubleABIAlignment = atoi(getToken(token,":").c_str()) / 8;
145 DoublePrefAlignment = atoi(getToken(token,":").c_str()) / 8;
146 if (DoublePrefAlignment == 0)
147 DoublePrefAlignment = DoubleABIAlignment;
Owen Anderson571a13f2006-05-12 06:06:55 +0000148 break;
Owen Anderson8f60c562006-05-12 05:49:47 +0000149 case 'f':
Chris Lattner58092e32007-01-20 22:35:55 +0000150 FloatABIAlignment = atoi(getToken(token, ":").c_str()) / 8;
151 FloatPrefAlignment = atoi(getToken(token,":").c_str()) / 8;
152 if (FloatPrefAlignment == 0)
153 FloatPrefAlignment = FloatABIAlignment;
Owen Anderson571a13f2006-05-12 06:06:55 +0000154 break;
Owen Anderson8f60c562006-05-12 05:49:47 +0000155 case 'l':
Chris Lattner58092e32007-01-20 22:35:55 +0000156 LongABIAlignment = atoi(getToken(token, ":").c_str()) / 8;
157 LongPrefAlignment = atoi(getToken(token,":").c_str()) / 8;
158 if (LongPrefAlignment == 0)
159 LongPrefAlignment = LongABIAlignment;
Owen Anderson571a13f2006-05-12 06:06:55 +0000160 break;
Owen Anderson8f60c562006-05-12 05:49:47 +0000161 case 'i':
Chris Lattner58092e32007-01-20 22:35:55 +0000162 IntABIAlignment = atoi(getToken(token, ":").c_str()) / 8;
163 IntPrefAlignment = atoi(getToken(token,":").c_str()) / 8;
164 if (IntPrefAlignment == 0)
165 IntPrefAlignment = IntABIAlignment;
Owen Anderson571a13f2006-05-12 06:06:55 +0000166 break;
Owen Anderson8f60c562006-05-12 05:49:47 +0000167 case 's':
Chris Lattner58092e32007-01-20 22:35:55 +0000168 ShortABIAlignment = atoi(getToken(token, ":").c_str()) / 8;
169 ShortPrefAlignment = atoi(getToken(token,":").c_str()) / 8;
170 if (ShortPrefAlignment == 0)
171 ShortPrefAlignment = ShortABIAlignment;
Owen Anderson571a13f2006-05-12 06:06:55 +0000172 break;
Owen Anderson8f60c562006-05-12 05:49:47 +0000173 case 'b':
Chris Lattner58092e32007-01-20 22:35:55 +0000174 ByteABIAlignment = atoi(getToken(token, ":").c_str()) / 8;
175 BytePrefAlignment = atoi(getToken(token,":").c_str()) / 8;
176 if (BytePrefAlignment == 0)
177 BytePrefAlignment = ByteABIAlignment;
Owen Anderson571a13f2006-05-12 06:06:55 +0000178 break;
Owen Anderson8f60c562006-05-12 05:49:47 +0000179 case 'B':
Chris Lattner58092e32007-01-20 22:35:55 +0000180 BoolABIAlignment = atoi(getToken(token, ":").c_str()) / 8;
181 BoolPrefAlignment = atoi(getToken(token,":").c_str()) / 8;
182 if (BoolPrefAlignment == 0)
183 BoolPrefAlignment = BoolABIAlignment;
184 break;
185 case 'A':
186 AggMinPrefAlignment = atoi(getToken(token,":").c_str()) / 8;
Owen Anderson571a13f2006-05-12 06:06:55 +0000187 break;
Owen Anderson8f60c562006-05-12 05:49:47 +0000188 default:
Owen Anderson571a13f2006-05-12 06:06:55 +0000189 break;
Owen Anderson8f60c562006-05-12 05:49:47 +0000190 }
191 }
Owen Anderson1027a532007-01-20 23:07:13 +0000192
Reid Spencer26f23852007-01-26 08:11:39 +0000193 // Unless explicitly specified, the alignments for longs and doubles is
194 // capped by pointer size.
Owen Anderson1027a532007-01-20 23:07:13 +0000195 if (LongABIAlignment == 0)
196 LongABIAlignment = LongPrefAlignment = PointerMemSize;
197 if (DoubleABIAlignment == 0)
198 DoubleABIAlignment = DoublePrefAlignment = PointerMemSize;
Owen Anderson8f60c562006-05-12 05:49:47 +0000199}
200
Chris Lattner1790d442006-06-16 18:22:52 +0000201TargetData::TargetData(const Module *M) {
Reid Spencer26f23852007-01-26 08:11:39 +0000202 init(M->getDataLayout());
Chris Lattner53a0c382003-04-24 19:09:05 +0000203}
204
Chris Lattnerec6478b2007-02-10 19:43:18 +0000205/// LayoutInfo - The lazy cache of structure layout information maintained by
Chris Lattner9182e3f2007-02-10 20:15:41 +0000206/// TargetData. Note that the struct types must have been free'd before
207/// llvm_shutdown is called (and thus this is deallocated) because all the
208/// targets with cached elements should have been destroyed.
Chris Lattner8dff24f2006-01-14 00:07:34 +0000209///
Chris Lattnerec6478b2007-02-10 19:43:18 +0000210typedef std::pair<const TargetData*,const StructType*> LayoutKey;
Chris Lattner9182e3f2007-02-10 20:15:41 +0000211static ManagedStatic<std::map<LayoutKey, StructLayout*> > LayoutInfo;
Chris Lattner0e7ac162004-02-26 08:02:17 +0000212
213
Chris Lattnere7fb3602001-08-27 16:00:15 +0000214TargetData::~TargetData() {
Chris Lattnerec6478b2007-02-10 19:43:18 +0000215 if (LayoutInfo.isConstructed()) {
Chris Lattner0e7ac162004-02-26 08:02:17 +0000216 // Remove any layouts for this TD.
Chris Lattner9182e3f2007-02-10 20:15:41 +0000217 std::map<LayoutKey, StructLayout*> &TheMap = *LayoutInfo;
218 std::map<LayoutKey, StructLayout*>::iterator
Chris Lattnerec6478b2007-02-10 19:43:18 +0000219 I = TheMap.lower_bound(LayoutKey(this, (const StructType*)0));
220
Chris Lattner9182e3f2007-02-10 20:15:41 +0000221 for (std::map<LayoutKey, StructLayout*>::iterator E = TheMap.end();
222 I != E && I->first.first == this; ) {
223 I->second->~StructLayout();
224 free(I->second);
Chris Lattnerec6478b2007-02-10 19:43:18 +0000225 TheMap.erase(I++);
Chris Lattner9182e3f2007-02-10 20:15:41 +0000226 }
Chris Lattner0e7ac162004-02-26 08:02:17 +0000227 }
228}
229
Chris Lattner9182e3f2007-02-10 20:15:41 +0000230const StructLayout *TargetData::getStructLayout(const StructType *Ty) const {
231 std::map<LayoutKey, StructLayout*> &TheMap = *LayoutInfo;
232
233 std::map<LayoutKey, StructLayout*>::iterator
234 I = TheMap.lower_bound(LayoutKey(this, Ty));
235 if (I != TheMap.end() && I->first.first == this && I->first.second == Ty)
236 return I->second;
237
238 // Otherwise, create the struct layout. Because it is variable length, we
239 // malloc it, then use placement new.
240 unsigned NumElts = Ty->getNumElements();
241 StructLayout *L =
242 (StructLayout *)malloc(sizeof(StructLayout)+(NumElts-1)*sizeof(uint64_t));
243 new (L) StructLayout(Ty, *this);
244
245 TheMap.insert(I, std::make_pair(LayoutKey(this, Ty), L));
246 return L;
247}
248
249/// InvalidateStructLayoutInfo - TargetData speculatively caches StructLayout
250/// objects. If a TargetData object is alive when types are being refined and
251/// removed, this method must be called whenever a StructType is removed to
252/// avoid a dangling pointer in this cache.
253void TargetData::InvalidateStructLayoutInfo(const StructType *Ty) const {
254 if (!LayoutInfo.isConstructed()) return; // No cache.
255
256 std::map<LayoutKey, StructLayout*>::iterator I =
257 LayoutInfo->find(LayoutKey(this, Ty));
258 if (I != LayoutInfo->end()) {
259 I->second->~StructLayout();
260 free(I->second);
261 LayoutInfo->erase(I);
262 }
263}
264
265
Owen Anderson2577c222006-05-12 07:01:44 +0000266std::string TargetData::getStringRepresentation() const {
267 std::stringstream repr;
268
269 if (LittleEndian)
270 repr << "e";
271 else
272 repr << "E";
273
Chris Lattner58092e32007-01-20 22:35:55 +0000274 repr << "-p:" << (PointerMemSize * 8) << ":" << (PointerABIAlignment * 8);
275 repr << "-d:" << (DoubleABIAlignment * 8) << ":"
276 << (DoublePrefAlignment * 8);
277 repr << "-f:" << (FloatABIAlignment * 8) << ":"
278 << (FloatPrefAlignment * 8);
279 repr << "-l:" << (LongABIAlignment * 8) << ":"
280 << (LongPrefAlignment * 8);
281 repr << "-i:" << (IntABIAlignment * 8) << ":"
282 << (IntPrefAlignment * 8);
283 repr << "-s:" << (ShortABIAlignment * 8) << ":"
284 << (ShortPrefAlignment * 8);
285 repr << "-b:" << (ByteABIAlignment * 8) << ":"
286 << (BytePrefAlignment * 8);
287 repr << "-B:" << (BoolABIAlignment * 8) << ":"
288 << (BoolPrefAlignment * 8);
289 repr << "-A:" << (AggMinPrefAlignment * 8);
Owen Anderson2577c222006-05-12 07:01:44 +0000290
291 return repr.str();
292}
293
Chris Lattner8dff24f2006-01-14 00:07:34 +0000294
Chris Lattner58092e32007-01-20 22:35:55 +0000295static inline void getTypeInfoABI(const Type *Ty, const TargetData *TD,
296 uint64_t &Size, unsigned char &Alignment) {
Chris Lattnerf59ce922001-12-13 00:46:11 +0000297 assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
Chris Lattnerf70c22b2004-06-17 18:19:28 +0000298 switch (Ty->getTypeID()) {
Reid Spencera54b7cb2007-01-12 07:05:14 +0000299 case Type::IntegerTyID: {
300 unsigned BitWidth = cast<IntegerType>(Ty)->getBitWidth();
301 if (BitWidth <= 8) {
Chris Lattner58092e32007-01-20 22:35:55 +0000302 Size = 1; Alignment = TD->getByteABIAlignment();
Reid Spencera54b7cb2007-01-12 07:05:14 +0000303 } else if (BitWidth <= 16) {
Chris Lattner58092e32007-01-20 22:35:55 +0000304 Size = 2; Alignment = TD->getShortABIAlignment();
Reid Spencera54b7cb2007-01-12 07:05:14 +0000305 } else if (BitWidth <= 32) {
Chris Lattner58092e32007-01-20 22:35:55 +0000306 Size = 4; Alignment = TD->getIntABIAlignment();
Reid Spencera54b7cb2007-01-12 07:05:14 +0000307 } else if (BitWidth <= 64) {
Chris Lattner58092e32007-01-20 22:35:55 +0000308 Size = 8; Alignment = TD->getLongABIAlignment();
Reid Spencerd2a988c2007-02-05 23:51:43 +0000309 } else {
310 Size = ((BitWidth + 7) / 8) & ~1;
311 Alignment = TD->getLongABIAlignment();
312 }
Reid Spencera54b7cb2007-01-12 07:05:14 +0000313 return;
314 }
Chris Lattner58092e32007-01-20 22:35:55 +0000315 case Type::VoidTyID: Size = 1; Alignment = TD->getByteABIAlignment(); return;
316 case Type::FloatTyID: Size = 4; Alignment = TD->getFloatABIAlignment(); return;
317 case Type::DoubleTyID: Size = 8; Alignment = TD->getDoubleABIAlignment(); return;
Chris Lattnere7fb3602001-08-27 16:00:15 +0000318 case Type::LabelTyID:
319 case Type::PointerTyID:
Chris Lattner58092e32007-01-20 22:35:55 +0000320 Size = TD->getPointerSize(); Alignment = TD->getPointerABIAlignment();
Chris Lattnere7fb3602001-08-27 16:00:15 +0000321 return;
322 case Type::ArrayTyID: {
Chris Lattner59b00672004-07-01 17:32:59 +0000323 const ArrayType *ATy = cast<ArrayType>(Ty);
Chris Lattner58092e32007-01-20 22:35:55 +0000324 getTypeInfoABI(ATy->getElementType(), TD, Size, Alignment);
Brian Gaekee0e35892004-07-02 07:01:31 +0000325 unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment;
Chris Lattner59b00672004-07-01 17:32:59 +0000326 Size = AlignedSize*ATy->getNumElements();
Chris Lattnere7fb3602001-08-27 16:00:15 +0000327 return;
328 }
Chris Lattner527efc62004-12-01 17:14:28 +0000329 case Type::PackedTyID: {
330 const PackedType *PTy = cast<PackedType>(Ty);
Chris Lattner58092e32007-01-20 22:35:55 +0000331 getTypeInfoABI(PTy->getElementType(), TD, Size, Alignment);
Chris Lattner527efc62004-12-01 17:14:28 +0000332 unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment;
333 Size = AlignedSize*PTy->getNumElements();
Evan Chenge668bda2006-03-31 22:33:42 +0000334 // FIXME: The alignments of specific packed types are target dependent.
335 // For now, just set it to be equal to Size.
Chris Lattner0aab36f2006-04-03 23:14:49 +0000336 Alignment = Size;
Chris Lattner527efc62004-12-01 17:14:28 +0000337 return;
338 }
Chris Lattnere7fb3602001-08-27 16:00:15 +0000339 case Type::StructTyID: {
340 // Get the layout annotation... which is lazily created on demand.
Chris Lattner59b00672004-07-01 17:32:59 +0000341 const StructLayout *Layout = TD->getStructLayout(cast<StructType>(Ty));
Chris Lattnerb0c39a32007-02-10 19:59:22 +0000342 Size = Layout->getSizeInBytes(); Alignment = Layout->getAlignment();
Chris Lattnere7fb3602001-08-27 16:00:15 +0000343 return;
344 }
Misha Brukmanf976c852005-04-21 22:55:34 +0000345
Chris Lattnere7fb3602001-08-27 16:00:15 +0000346 default:
347 assert(0 && "Bad type for getTypeInfo!!!");
348 return;
349 }
350}
351
Chris Lattner58092e32007-01-20 22:35:55 +0000352static inline void getTypeInfoPref(const Type *Ty, const TargetData *TD,
353 uint64_t &Size, unsigned char &Alignment) {
354 assert(Ty->isSized() && "Cannot getTypeInfoPref() on a type that is unsized!");
355 switch (Ty->getTypeID()) {
356 case Type::IntegerTyID: {
357 unsigned BitWidth = cast<IntegerType>(Ty)->getBitWidth();
358 if (BitWidth <= 8) {
359 Size = 1; Alignment = TD->getBytePrefAlignment();
360 } else if (BitWidth <= 16) {
361 Size = 2; Alignment = TD->getShortPrefAlignment();
362 } else if (BitWidth <= 32) {
363 Size = 4; Alignment = TD->getIntPrefAlignment();
364 } else if (BitWidth <= 64) {
365 Size = 8; Alignment = TD->getLongPrefAlignment();
366 } else
367 assert(0 && "Integer types > 64 bits not supported.");
368 return;
369 }
370 case Type::VoidTyID:
371 Size = 1; Alignment = TD->getBytePrefAlignment();
372 return;
373 case Type::FloatTyID:
374 Size = 4; Alignment = TD->getFloatPrefAlignment();
375 return;
376 case Type::DoubleTyID:
377 Size = 8; Alignment = TD->getDoublePrefAlignment();
378 return;
379 case Type::LabelTyID:
380 case Type::PointerTyID:
381 Size = TD->getPointerSize(); Alignment = TD->getPointerPrefAlignment();
382 return;
383 case Type::ArrayTyID: {
384 const ArrayType *ATy = cast<ArrayType>(Ty);
385 getTypeInfoPref(ATy->getElementType(), TD, Size, Alignment);
386 unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment;
387 Size = AlignedSize*ATy->getNumElements();
388 return;
389 }
390 case Type::PackedTyID: {
391 const PackedType *PTy = cast<PackedType>(Ty);
392 getTypeInfoPref(PTy->getElementType(), TD, Size, Alignment);
393 unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment;
394 Size = AlignedSize*PTy->getNumElements();
395 // FIXME: The alignments of specific packed types are target dependent.
396 // For now, just set it to be equal to Size.
397 Alignment = Size;
398 return;
399 }
400 case Type::StructTyID: {
401 // Get the layout annotation... which is lazily created on demand;
402 // enforce minimum aggregate alignment.
403 const StructLayout *Layout = TD->getStructLayout(cast<StructType>(Ty));
Chris Lattnerb0c39a32007-02-10 19:59:22 +0000404 Size = Layout->getSizeInBytes();
405 Alignment = std::max(Layout->getAlignment(),
406 (const unsigned int)TD->getAggMinPrefAlignment());
Chris Lattner58092e32007-01-20 22:35:55 +0000407 return;
408 }
409
410 default:
411 assert(0 && "Bad type for getTypeInfoPref!!!");
412 return;
413 }
414}
415
416
Vikram S. Advef66723f2002-05-19 15:28:02 +0000417uint64_t TargetData::getTypeSize(const Type *Ty) const {
418 uint64_t Size;
419 unsigned char Align;
Chris Lattner58092e32007-01-20 22:35:55 +0000420 getTypeInfoABI(Ty, this, Size, Align);
Chris Lattnere7fb3602001-08-27 16:00:15 +0000421 return Size;
422}
423
Reid Spencer7c292432007-01-20 23:32:04 +0000424uint64_t TargetData::getTypeSizeInBits(const Type *Ty) const {
425 if (Ty->isInteger())
426 return cast<IntegerType>(Ty)->getBitWidth();
427
428 uint64_t Size;
429 unsigned char Align;
430 getTypeInfoABI(Ty, this, Size, Align);
431 return Size * 8;
432}
433
Chris Lattner58092e32007-01-20 22:35:55 +0000434unsigned char TargetData::getTypeAlignmentABI(const Type *Ty) const {
Vikram S. Advef66723f2002-05-19 15:28:02 +0000435 uint64_t Size;
436 unsigned char Align;
Chris Lattner58092e32007-01-20 22:35:55 +0000437 getTypeInfoABI(Ty, this, Size, Align);
438 return Align;
439}
440
441unsigned char TargetData::getTypeAlignmentPref(const Type *Ty) const {
442 uint64_t Size;
443 unsigned char Align;
444 getTypeInfoPref(Ty, this, Size, Align);
Chris Lattnere7fb3602001-08-27 16:00:15 +0000445 return Align;
446}
447
Evan Chengde268f72007-01-24 07:03:39 +0000448unsigned char TargetData::getPreferredTypeAlignmentShift(const Type *Ty) const {
Evan Cheng778900a2007-01-22 23:08:19 +0000449 unsigned Align = getTypeAlignmentPref(Ty);
Chris Lattnerd2b0bb42004-08-17 19:13:00 +0000450 assert(!(Align & (Align-1)) && "Alignment is not a power of two!");
Chris Lattner0561b3f2005-08-02 19:26:06 +0000451 return Log2_32(Align);
Chris Lattnerd2b0bb42004-08-17 19:13:00 +0000452}
453
Chris Lattnerf0453282003-12-22 05:01:15 +0000454/// getIntPtrType - Return an unsigned integer type that is the same size or
455/// greater to the host pointer size.
456const Type *TargetData::getIntPtrType() const {
457 switch (getPointerSize()) {
458 default: assert(0 && "Unknown pointer size!");
Reid Spencer47857812006-12-31 05:55:36 +0000459 case 2: return Type::Int16Ty;
460 case 4: return Type::Int32Ty;
461 case 8: return Type::Int64Ty;
Chris Lattnerf0453282003-12-22 05:01:15 +0000462 }
463}
464
465
Chris Lattnerddce8d22007-02-10 19:33:15 +0000466uint64_t TargetData::getIndexedOffset(const Type *ptrTy, Value* const* Indices,
467 unsigned NumIndices) const {
Vikram S. Adveed0030e2002-08-04 20:52:39 +0000468 const Type *Ty = ptrTy;
469 assert(isa<PointerType>(Ty) && "Illegal argument for getIndexedOffset()");
Vikram S. Advef66723f2002-05-19 15:28:02 +0000470 uint64_t Result = 0;
Chris Lattnere7fb3602001-08-27 16:00:15 +0000471
Chris Lattnerddce8d22007-02-10 19:33:15 +0000472 generic_gep_type_iterator<Value* const*>
473 TI = gep_type_begin(ptrTy, Indices, Indices+NumIndices);
474 for (unsigned CurIDX = 0; CurIDX != NumIndices; ++CurIDX, ++TI) {
Chris Lattner28977af2004-04-05 01:30:19 +0000475 if (const StructType *STy = dyn_cast<StructType>(*TI)) {
Chris Lattnerddce8d22007-02-10 19:33:15 +0000476 assert(Indices[CurIDX]->getType() == Type::Int32Ty &&"Illegal struct idx");
477 unsigned FieldNo = cast<ConstantInt>(Indices[CurIDX])->getZExtValue();
Chris Lattnere7fb3602001-08-27 16:00:15 +0000478
479 // Get structure layout information...
480 const StructLayout *Layout = getStructLayout(STy);
481
482 // Add in the offset, as calculated by the structure layout info...
Chris Lattnerb1919e22007-02-10 19:55:17 +0000483 Result += Layout->getElementOffset(FieldNo);
Vikram S. Adveed0030e2002-08-04 20:52:39 +0000484
Chris Lattnere7fb3602001-08-27 16:00:15 +0000485 // Update Ty to refer to current element
Chris Lattnerd21cd802004-02-09 04:37:31 +0000486 Ty = STy->getElementType(FieldNo);
Chris Lattner28977af2004-04-05 01:30:19 +0000487 } else {
488 // Update Ty to refer to current element
489 Ty = cast<SequentialType>(Ty)->getElementType();
490
491 // Get the array index and the size of each array element.
Chris Lattnerddce8d22007-02-10 19:33:15 +0000492 int64_t arrayIdx = cast<ConstantInt>(Indices[CurIDX])->getSExtValue();
Chris Lattner28977af2004-04-05 01:30:19 +0000493 Result += arrayIdx * (int64_t)getTypeSize(Ty);
Chris Lattnere7fb3602001-08-27 16:00:15 +0000494 }
495 }
496
497 return Result;
498}
Brian Gaeked0fde302003-11-11 22:41:34 +0000499
Devang Patelf9c197e2006-10-24 20:32:14 +0000500/// getPreferredAlignmentLog - Return the preferred alignment of the
501/// specified global, returned in log form. This includes an explicitly
502/// requested alignment (if the global has one).
503unsigned TargetData::getPreferredAlignmentLog(const GlobalVariable *GV) const {
504 const Type *ElemType = GV->getType()->getElementType();
Evan Chengde268f72007-01-24 07:03:39 +0000505 unsigned Alignment = getPreferredTypeAlignmentShift(ElemType);
Devang Patelf9c197e2006-10-24 20:32:14 +0000506 if (GV->getAlignment() > (1U << Alignment))
507 Alignment = Log2_32(GV->getAlignment());
508
509 if (GV->hasInitializer()) {
Devang Patelf9c197e2006-10-24 20:32:14 +0000510 if (Alignment < 4) {
511 // If the global is not external, see if it is large. If so, give it a
512 // larger alignment.
513 if (getTypeSize(ElemType) > 128)
514 Alignment = 4; // 16-byte alignment.
515 }
516 }
517 return Alignment;
518}
519