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"
30 // Handle the Pass registration stuff necessary to use TargetData's.
32 // Register the default SparcV9 implementation...
33 RegisterPass<TargetData> X("targetdata", "Target Data Layout");
36 static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
37 uint64_t &Size, unsigned char &Alignment);
39 //===----------------------------------------------------------------------===//
40 // Support for StructLayout
41 //===----------------------------------------------------------------------===//
43 StructLayout::StructLayout(const StructType *ST, const TargetData &TD) {
47 // Loop over each of the elements, placing them in memory...
48 for (StructType::element_iterator TI = ST->element_begin(),
49 TE = ST->element_end(); TI != TE; ++TI) {
54 getTypeInfo(Ty, &TD, TySize, A);
57 // Add padding if necessary to make the data element aligned properly...
58 if (StructSize % TyAlign != 0)
59 StructSize = (StructSize/TyAlign + 1) * TyAlign; // Add padding...
61 // Keep track of maximum alignment constraint
62 StructAlignment = std::max(TyAlign, StructAlignment);
64 MemberOffsets.push_back(StructSize);
65 StructSize += TySize; // Consume space for this data item
68 // Empty structures have alignment of 1 byte.
69 if (StructAlignment == 0) StructAlignment = 1;
71 // Add padding to the end of the struct so that it could be put in an array
72 // and all array elements would be aligned correctly.
73 if (StructSize % StructAlignment != 0)
74 StructSize = (StructSize/StructAlignment + 1) * StructAlignment;
78 /// getElementContainingOffset - Given a valid offset into the structure,
79 /// return the structure index that contains it.
80 unsigned StructLayout::getElementContainingOffset(uint64_t Offset) const {
81 std::vector<uint64_t>::const_iterator SI =
82 std::upper_bound(MemberOffsets.begin(), MemberOffsets.end(),
84 assert(SI != MemberOffsets.begin() && "Offset not in structure type!");
86 assert(*SI <= Offset && "upper_bound didn't work");
87 assert((SI == MemberOffsets.begin() || *(SI-1) < Offset) &&
88 (SI+1 == MemberOffsets.end() || *(SI+1) > Offset) &&
89 "Upper bound didn't work!");
90 return SI-MemberOffsets.begin();
93 //===----------------------------------------------------------------------===//
94 // TargetData Class Implementation
95 //===----------------------------------------------------------------------===//
97 TargetData::TargetData(const std::string &TargetName,
98 bool isLittleEndian, unsigned char PtrSize,
99 unsigned char PtrAl, unsigned char DoubleAl,
100 unsigned char FloatAl, unsigned char LongAl,
101 unsigned char IntAl, unsigned char ShortAl,
102 unsigned char ByteAl, unsigned char BoolAl) {
104 // If this assert triggers, a pass "required" TargetData information, but the
105 // top level tool did not provide one for it. We do not want to default
106 // construct, or else we might end up using a bad endianness or pointer size!
108 assert(!TargetName.empty() &&
109 "ERROR: Tool did not specify a target data to use!");
111 LittleEndian = isLittleEndian;
112 PointerSize = PtrSize;
113 PointerAlignment = PtrAl;
114 DoubleAlignment = DoubleAl;
115 FloatAlignment = FloatAl;
116 LongAlignment = LongAl;
117 IntAlignment = IntAl;
118 ShortAlignment = ShortAl;
119 ByteAlignment = ByteAl;
120 BoolAlignment = BoolAl;
123 TargetData::TargetData(const std::string &TargetName,
124 const std::string &TargetDescription) {
125 std::string temp = TargetDescription;
127 LittleEndian = false;
129 PointerAlignment = 8;
138 while (temp.length() > 0) {
139 std::string token = getToken(temp, "-");
143 LittleEndian = false;
149 PointerSize = atoi(getToken(token,":").c_str()) / 8;
150 PointerAlignment = atoi(getToken(token,":").c_str()) / 8;
153 token = getToken(token,":"); //Ignore the size
154 DoubleAlignment = atoi(getToken(token,":").c_str()) / 8;
157 token = getToken(token, ":"); //Ignore the size
158 FloatAlignment = atoi(getToken(token, ":").c_str()) / 8;
161 token = getToken(token, ":"); //Ignore the size
162 LongAlignment = atoi(getToken(token, ":").c_str()) / 8;
165 token = getToken(token, ":"); //Ignore the size
166 IntAlignment = atoi(getToken(token, ":").c_str()) / 8;
169 token = getToken(token, ":"); //Ignore the size
170 ShortAlignment = atoi(getToken(token, ":").c_str()) / 8;
173 token = getToken(token, ":"); //Ignore the size
174 ByteAlignment = atoi(getToken(token, ":").c_str()) / 8;
177 token = getToken(token, ":"); //Ignore the size
178 BoolAlignment = atoi(getToken(token, ":").c_str()) / 8;
186 TargetData::TargetData(const std::string &ToolName, const Module *M) {
187 LittleEndian = M->getEndianness() != Module::BigEndian;
188 PointerSize = M->getPointerSize() != Module::Pointer64 ? 4 : 8;
189 PointerAlignment = PointerSize;
190 DoubleAlignment = PointerSize;
192 LongAlignment = PointerSize;
199 /// Layouts - The lazy cache of structure layout information maintained by
202 static std::map<std::pair<const TargetData*,const StructType*>,
203 StructLayout> *Layouts = 0;
206 TargetData::~TargetData() {
208 // Remove any layouts for this TD.
209 std::map<std::pair<const TargetData*,
210 const StructType*>, StructLayout>::iterator
211 I = Layouts->lower_bound(std::make_pair(this, (const StructType*)0));
212 while (I != Layouts->end() && I->first.first == this)
214 if (Layouts->empty()) {
221 const StructLayout *TargetData::getStructLayout(const StructType *Ty) const {
223 Layouts = new std::map<std::pair<const TargetData*,const StructType*>,
225 std::map<std::pair<const TargetData*,const StructType*>,
226 StructLayout>::iterator
227 I = Layouts->lower_bound(std::make_pair(this, Ty));
228 if (I != Layouts->end() && I->first.first == this && I->first.second == Ty)
231 return &Layouts->insert(I, std::make_pair(std::make_pair(this, Ty),
232 StructLayout(Ty, *this)))->second;
236 /// InvalidateStructLayoutInfo - TargetData speculatively caches StructLayout
237 /// objects. If a TargetData object is alive when types are being refined and
238 /// removed, this method must be called whenever a StructType is removed to
239 /// avoid a dangling pointer in this cache.
240 void TargetData::InvalidateStructLayoutInfo(const StructType *Ty) const {
241 if (!Layouts) return; // No cache.
243 std::map<std::pair<const TargetData*,const StructType*>,
244 StructLayout>::iterator I = Layouts->find(std::make_pair(this, Ty));
245 if (I != Layouts->end())
251 static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
252 uint64_t &Size, unsigned char &Alignment) {
253 assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
254 switch (Ty->getTypeID()) {
255 case Type::BoolTyID: Size = 1; Alignment = TD->getBoolAlignment(); return;
257 case Type::UByteTyID:
258 case Type::SByteTyID: Size = 1; Alignment = TD->getByteAlignment(); return;
259 case Type::UShortTyID:
260 case Type::ShortTyID: Size = 2; Alignment = TD->getShortAlignment(); return;
262 case Type::IntTyID: Size = 4; Alignment = TD->getIntAlignment(); return;
263 case Type::ULongTyID:
264 case Type::LongTyID: Size = 8; Alignment = TD->getLongAlignment(); return;
265 case Type::FloatTyID: Size = 4; Alignment = TD->getFloatAlignment(); return;
266 case Type::DoubleTyID: Size = 8; Alignment = TD->getDoubleAlignment(); return;
267 case Type::LabelTyID:
268 case Type::PointerTyID:
269 Size = TD->getPointerSize(); Alignment = TD->getPointerAlignment();
271 case Type::ArrayTyID: {
272 const ArrayType *ATy = cast<ArrayType>(Ty);
273 getTypeInfo(ATy->getElementType(), TD, Size, Alignment);
274 unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment;
275 Size = AlignedSize*ATy->getNumElements();
278 case Type::PackedTyID: {
279 const PackedType *PTy = cast<PackedType>(Ty);
280 getTypeInfo(PTy->getElementType(), TD, Size, Alignment);
281 unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment;
282 Size = AlignedSize*PTy->getNumElements();
283 // FIXME: The alignments of specific packed types are target dependent.
284 // For now, just set it to be equal to Size.
288 case Type::StructTyID: {
289 // Get the layout annotation... which is lazily created on demand.
290 const StructLayout *Layout = TD->getStructLayout(cast<StructType>(Ty));
291 Size = Layout->StructSize; Alignment = Layout->StructAlignment;
296 assert(0 && "Bad type for getTypeInfo!!!");
301 uint64_t TargetData::getTypeSize(const Type *Ty) const {
304 getTypeInfo(Ty, this, Size, Align);
308 unsigned char TargetData::getTypeAlignment(const Type *Ty) const {
311 getTypeInfo(Ty, this, Size, Align);
315 unsigned char TargetData::getTypeAlignmentShift(const Type *Ty) const {
316 unsigned Align = getTypeAlignment(Ty);
317 assert(!(Align & (Align-1)) && "Alignment is not a power of two!");
318 return Log2_32(Align);
321 /// getIntPtrType - Return an unsigned integer type that is the same size or
322 /// greater to the host pointer size.
323 const Type *TargetData::getIntPtrType() const {
324 switch (getPointerSize()) {
325 default: assert(0 && "Unknown pointer size!");
326 case 2: return Type::UShortTy;
327 case 4: return Type::UIntTy;
328 case 8: return Type::ULongTy;
333 uint64_t TargetData::getIndexedOffset(const Type *ptrTy,
334 const std::vector<Value*> &Idx) const {
335 const Type *Ty = ptrTy;
336 assert(isa<PointerType>(Ty) && "Illegal argument for getIndexedOffset()");
339 generic_gep_type_iterator<std::vector<Value*>::const_iterator>
340 TI = gep_type_begin(ptrTy, Idx.begin(), Idx.end());
341 for (unsigned CurIDX = 0; CurIDX != Idx.size(); ++CurIDX, ++TI) {
342 if (const StructType *STy = dyn_cast<StructType>(*TI)) {
343 assert(Idx[CurIDX]->getType() == Type::UIntTy && "Illegal struct idx");
344 unsigned FieldNo = cast<ConstantUInt>(Idx[CurIDX])->getValue();
346 // Get structure layout information...
347 const StructLayout *Layout = getStructLayout(STy);
349 // Add in the offset, as calculated by the structure layout info...
350 assert(FieldNo < Layout->MemberOffsets.size() &&"FieldNo out of range!");
351 Result += Layout->MemberOffsets[FieldNo];
353 // Update Ty to refer to current element
354 Ty = STy->getElementType(FieldNo);
356 // Update Ty to refer to current element
357 Ty = cast<SequentialType>(Ty)->getElementType();
359 // Get the array index and the size of each array element.
360 int64_t arrayIdx = cast<ConstantInt>(Idx[CurIDX])->getRawValue();
361 Result += arrayIdx * (int64_t)getTypeSize(Ty);