1 //===-- TargetData.cpp - Data size & alignment routines --------------------==//
3 // The LLVM Compiler Infrastructure
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.
8 //===----------------------------------------------------------------------===//
10 // This file defines target properties related to datatype size/offset/alignment
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.
17 //===----------------------------------------------------------------------===//
19 #include "llvm/Target/TargetData.h"
20 #include "llvm/Module.h"
21 #include "llvm/DerivedTypes.h"
22 #include "llvm/Constants.h"
23 #include "llvm/Support/GetElementPtrTypeIterator.h"
24 #include "llvm/Support/MathExtras.h"
25 #include "llvm/ADT/StringExtras.h"
31 // Handle the Pass registration stuff necessary to use TargetData's.
33 // Register the default SparcV9 implementation...
34 RegisterPass<TargetData> X("targetdata", "Target Data Layout");
37 static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
38 uint64_t &Size, unsigned char &Alignment);
40 //===----------------------------------------------------------------------===//
41 // Support for StructLayout
42 //===----------------------------------------------------------------------===//
44 StructLayout::StructLayout(const StructType *ST, const TargetData &TD) {
48 // Loop over each of the elements, placing them in memory...
49 for (StructType::element_iterator TI = ST->element_begin(),
50 TE = ST->element_end(); TI != TE; ++TI) {
55 getTypeInfo(Ty, &TD, TySize, A);
58 // Add padding if necessary to make the data element aligned properly...
59 if (StructSize % TyAlign != 0)
60 StructSize = (StructSize/TyAlign + 1) * TyAlign; // Add padding...
62 // Keep track of maximum alignment constraint
63 StructAlignment = std::max(TyAlign, StructAlignment);
65 MemberOffsets.push_back(StructSize);
66 StructSize += TySize; // Consume space for this data item
69 // Empty structures have alignment of 1 byte.
70 if (StructAlignment == 0) StructAlignment = 1;
72 // Add padding to the end of the struct so that it could be put in an array
73 // and all array elements would be aligned correctly.
74 if (StructSize % StructAlignment != 0)
75 StructSize = (StructSize/StructAlignment + 1) * StructAlignment;
79 /// getElementContainingOffset - Given a valid offset into the structure,
80 /// return the structure index that contains it.
81 unsigned StructLayout::getElementContainingOffset(uint64_t Offset) const {
82 std::vector<uint64_t>::const_iterator SI =
83 std::upper_bound(MemberOffsets.begin(), MemberOffsets.end(),
85 assert(SI != MemberOffsets.begin() && "Offset not in structure type!");
87 assert(*SI <= Offset && "upper_bound didn't work");
88 assert((SI == MemberOffsets.begin() || *(SI-1) < Offset) &&
89 (SI+1 == MemberOffsets.end() || *(SI+1) > Offset) &&
90 "Upper bound didn't work!");
91 return SI-MemberOffsets.begin();
94 //===----------------------------------------------------------------------===//
95 // TargetData Class Implementation
96 //===----------------------------------------------------------------------===//
98 TargetData::TargetData(const std::string &TargetName,
99 bool isLittleEndian, unsigned char PtrSize,
100 unsigned char PtrAl, unsigned char DoubleAl,
101 unsigned char FloatAl, unsigned char LongAl,
102 unsigned char IntAl, unsigned char ShortAl,
103 unsigned char ByteAl, unsigned char BoolAl) {
105 // If this assert triggers, a pass "required" TargetData information, but the
106 // top level tool did not provide one for it. We do not want to default
107 // construct, or else we might end up using a bad endianness or pointer size!
109 assert(!TargetName.empty() &&
110 "ERROR: Tool did not specify a target data to use!");
112 LittleEndian = isLittleEndian;
113 PointerSize = PtrSize;
114 PointerAlignment = PtrAl;
115 DoubleAlignment = DoubleAl;
116 FloatAlignment = FloatAl;
117 LongAlignment = LongAl;
118 IntAlignment = IntAl;
119 ShortAlignment = ShortAl;
120 ByteAlignment = ByteAl;
121 BoolAlignment = BoolAl;
124 TargetData::TargetData(const std::string &TargetName,
125 const std::string &TargetDescription) {
126 std::string temp = TargetDescription;
128 LittleEndian = false;
130 PointerAlignment = 8;
139 while (temp.length() > 0) {
140 std::string token = getToken(temp, "-");
142 char signal = getToken(token, ":")[0];
146 LittleEndian = false;
152 PointerSize = atoi(getToken(token,":").c_str()) / 8;
153 PointerAlignment = atoi(getToken(token,":").c_str()) / 8;
156 token = getToken(token,":"); //Ignore the size
157 DoubleAlignment = atoi(getToken(token,":").c_str()) / 8;
160 token = getToken(token, ":"); //Ignore the size
161 FloatAlignment = atoi(getToken(token, ":").c_str()) / 8;
164 token = getToken(token, ":"); //Ignore the size
165 LongAlignment = atoi(getToken(token, ":").c_str()) / 8;
168 token = getToken(token, ":"); //Ignore the size
169 IntAlignment = atoi(getToken(token, ":").c_str()) / 8;
172 token = getToken(token, ":"); //Ignore the size
173 ShortAlignment = atoi(getToken(token, ":").c_str()) / 8;
176 token = getToken(token, ":"); //Ignore the size
177 ByteAlignment = atoi(getToken(token, ":").c_str()) / 8;
180 token = getToken(token, ":"); //Ignore the size
181 BoolAlignment = atoi(getToken(token, ":").c_str()) / 8;
189 TargetData::TargetData(const std::string &ToolName, const Module *M) {
190 LittleEndian = M->getEndianness() != Module::BigEndian;
191 PointerSize = M->getPointerSize() != Module::Pointer64 ? 4 : 8;
192 PointerAlignment = PointerSize;
193 DoubleAlignment = PointerSize;
195 LongAlignment = PointerSize;
202 /// Layouts - The lazy cache of structure layout information maintained by
205 static std::map<std::pair<const TargetData*,const StructType*>,
206 StructLayout> *Layouts = 0;
209 TargetData::~TargetData() {
211 // Remove any layouts for this TD.
212 std::map<std::pair<const TargetData*,
213 const StructType*>, StructLayout>::iterator
214 I = Layouts->lower_bound(std::make_pair(this, (const StructType*)0));
215 while (I != Layouts->end() && I->first.first == this)
217 if (Layouts->empty()) {
224 std::string TargetData::getStringRepresentation() const {
225 std::stringstream repr;
232 repr << "-p:" << (PointerSize * 8) << ":" << (PointerAlignment * 8);
233 repr << "-d:64:" << (DoubleAlignment * 8);
234 repr << "-f:32:" << (FloatAlignment * 8);
235 repr << "-l:64:" << (LongAlignment * 8);
236 repr << "-i:32:" << (IntAlignment * 8);
237 repr << "-s:16:" << (ShortAlignment * 8);
238 repr << "-b:8:" << (ByteAlignment * 8);
239 repr << "-B:8:" << (BoolAlignment * 8);
244 const StructLayout *TargetData::getStructLayout(const StructType *Ty) const {
246 Layouts = new std::map<std::pair<const TargetData*,const StructType*>,
248 std::map<std::pair<const TargetData*,const StructType*>,
249 StructLayout>::iterator
250 I = Layouts->lower_bound(std::make_pair(this, Ty));
251 if (I != Layouts->end() && I->first.first == this && I->first.second == Ty)
254 return &Layouts->insert(I, std::make_pair(std::make_pair(this, Ty),
255 StructLayout(Ty, *this)))->second;
259 /// InvalidateStructLayoutInfo - TargetData speculatively caches StructLayout
260 /// objects. If a TargetData object is alive when types are being refined and
261 /// removed, this method must be called whenever a StructType is removed to
262 /// avoid a dangling pointer in this cache.
263 void TargetData::InvalidateStructLayoutInfo(const StructType *Ty) const {
264 if (!Layouts) return; // No cache.
266 std::map<std::pair<const TargetData*,const StructType*>,
267 StructLayout>::iterator I = Layouts->find(std::make_pair(this, Ty));
268 if (I != Layouts->end())
274 static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
275 uint64_t &Size, unsigned char &Alignment) {
276 assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
277 switch (Ty->getTypeID()) {
278 case Type::BoolTyID: Size = 1; Alignment = TD->getBoolAlignment(); return;
280 case Type::UByteTyID:
281 case Type::SByteTyID: Size = 1; Alignment = TD->getByteAlignment(); return;
282 case Type::UShortTyID:
283 case Type::ShortTyID: Size = 2; Alignment = TD->getShortAlignment(); return;
285 case Type::IntTyID: Size = 4; Alignment = TD->getIntAlignment(); return;
286 case Type::ULongTyID:
287 case Type::LongTyID: Size = 8; Alignment = TD->getLongAlignment(); return;
288 case Type::FloatTyID: Size = 4; Alignment = TD->getFloatAlignment(); return;
289 case Type::DoubleTyID: Size = 8; Alignment = TD->getDoubleAlignment(); return;
290 case Type::LabelTyID:
291 case Type::PointerTyID:
292 Size = TD->getPointerSize(); Alignment = TD->getPointerAlignment();
294 case Type::ArrayTyID: {
295 const ArrayType *ATy = cast<ArrayType>(Ty);
296 getTypeInfo(ATy->getElementType(), TD, Size, Alignment);
297 unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment;
298 Size = AlignedSize*ATy->getNumElements();
301 case Type::PackedTyID: {
302 const PackedType *PTy = cast<PackedType>(Ty);
303 getTypeInfo(PTy->getElementType(), TD, Size, Alignment);
304 unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment;
305 Size = AlignedSize*PTy->getNumElements();
306 // FIXME: The alignments of specific packed types are target dependent.
307 // For now, just set it to be equal to Size.
311 case Type::StructTyID: {
312 // Get the layout annotation... which is lazily created on demand.
313 const StructLayout *Layout = TD->getStructLayout(cast<StructType>(Ty));
314 Size = Layout->StructSize; Alignment = Layout->StructAlignment;
319 assert(0 && "Bad type for getTypeInfo!!!");
324 uint64_t TargetData::getTypeSize(const Type *Ty) const {
327 getTypeInfo(Ty, this, Size, Align);
331 unsigned char TargetData::getTypeAlignment(const Type *Ty) const {
334 getTypeInfo(Ty, this, Size, Align);
338 unsigned char TargetData::getTypeAlignmentShift(const Type *Ty) const {
339 unsigned Align = getTypeAlignment(Ty);
340 assert(!(Align & (Align-1)) && "Alignment is not a power of two!");
341 return Log2_32(Align);
344 /// getIntPtrType - Return an unsigned integer type that is the same size or
345 /// greater to the host pointer size.
346 const Type *TargetData::getIntPtrType() const {
347 switch (getPointerSize()) {
348 default: assert(0 && "Unknown pointer size!");
349 case 2: return Type::UShortTy;
350 case 4: return Type::UIntTy;
351 case 8: return Type::ULongTy;
356 uint64_t TargetData::getIndexedOffset(const Type *ptrTy,
357 const std::vector<Value*> &Idx) const {
358 const Type *Ty = ptrTy;
359 assert(isa<PointerType>(Ty) && "Illegal argument for getIndexedOffset()");
362 generic_gep_type_iterator<std::vector<Value*>::const_iterator>
363 TI = gep_type_begin(ptrTy, Idx.begin(), Idx.end());
364 for (unsigned CurIDX = 0; CurIDX != Idx.size(); ++CurIDX, ++TI) {
365 if (const StructType *STy = dyn_cast<StructType>(*TI)) {
366 assert(Idx[CurIDX]->getType() == Type::UIntTy && "Illegal struct idx");
367 unsigned FieldNo = cast<ConstantUInt>(Idx[CurIDX])->getValue();
369 // Get structure layout information...
370 const StructLayout *Layout = getStructLayout(STy);
372 // Add in the offset, as calculated by the structure layout info...
373 assert(FieldNo < Layout->MemberOffsets.size() &&"FieldNo out of range!");
374 Result += Layout->MemberOffsets[FieldNo];
376 // Update Ty to refer to current element
377 Ty = STy->getElementType(FieldNo);
379 // Update Ty to refer to current element
380 Ty = cast<SequentialType>(Ty)->getElementType();
382 // Get the array index and the size of each array element.
383 int64_t arrayIdx = cast<ConstantInt>(Idx[CurIDX])->getRawValue();
384 Result += arrayIdx * (int64_t)getTypeSize(Ty);