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 assert(!TargetName.empty() &&
127 "ERROR: Tool did not specify a target data to use!");
130 std::string temp = TargetDescription;
132 LittleEndian = false;
134 PointerAlignment = 8;
143 while (!temp.empty()) {
144 std::string token = getToken(temp, "-");
146 char signal = getToken(token, ":")[0];
150 LittleEndian = false;
156 PointerSize = atoi(getToken(token,":").c_str()) / 8;
157 PointerAlignment = atoi(getToken(token,":").c_str()) / 8;
160 token = getToken(token,":"); //Ignore the size
161 DoubleAlignment = atoi(getToken(token,":").c_str()) / 8;
164 token = getToken(token, ":"); //Ignore the size
165 FloatAlignment = atoi(getToken(token, ":").c_str()) / 8;
168 token = getToken(token, ":"); //Ignore the size
169 LongAlignment = atoi(getToken(token, ":").c_str()) / 8;
172 token = getToken(token, ":"); //Ignore the size
173 IntAlignment = atoi(getToken(token, ":").c_str()) / 8;
176 token = getToken(token, ":"); //Ignore the size
177 ShortAlignment = atoi(getToken(token, ":").c_str()) / 8;
180 token = getToken(token, ":"); //Ignore the size
181 ByteAlignment = atoi(getToken(token, ":").c_str()) / 8;
184 token = getToken(token, ":"); //Ignore the size
185 BoolAlignment = atoi(getToken(token, ":").c_str()) / 8;
193 TargetData::TargetData(const std::string &ToolName, const Module *M) {
194 LittleEndian = M->getEndianness() != Module::BigEndian;
195 PointerSize = M->getPointerSize() != Module::Pointer64 ? 4 : 8;
196 PointerAlignment = PointerSize;
197 DoubleAlignment = PointerSize;
199 LongAlignment = PointerSize;
206 /// Layouts - The lazy cache of structure layout information maintained by
209 static std::map<std::pair<const TargetData*,const StructType*>,
210 StructLayout> *Layouts = 0;
213 TargetData::~TargetData() {
215 // Remove any layouts for this TD.
216 std::map<std::pair<const TargetData*,
217 const StructType*>, StructLayout>::iterator
218 I = Layouts->lower_bound(std::make_pair(this, (const StructType*)0));
219 while (I != Layouts->end() && I->first.first == this)
221 if (Layouts->empty()) {
228 std::string TargetData::getStringRepresentation() const {
229 std::stringstream repr;
236 repr << "-p:" << (PointerSize * 8) << ":" << (PointerAlignment * 8);
237 repr << "-d:64:" << (DoubleAlignment * 8);
238 repr << "-f:32:" << (FloatAlignment * 8);
239 repr << "-l:64:" << (LongAlignment * 8);
240 repr << "-i:32:" << (IntAlignment * 8);
241 repr << "-s:16:" << (ShortAlignment * 8);
242 repr << "-b:8:" << (ByteAlignment * 8);
243 repr << "-B:8:" << (BoolAlignment * 8);
248 const StructLayout *TargetData::getStructLayout(const StructType *Ty) const {
250 Layouts = new std::map<std::pair<const TargetData*,const StructType*>,
252 std::map<std::pair<const TargetData*,const StructType*>,
253 StructLayout>::iterator
254 I = Layouts->lower_bound(std::make_pair(this, Ty));
255 if (I != Layouts->end() && I->first.first == this && I->first.second == Ty)
258 return &Layouts->insert(I, std::make_pair(std::make_pair(this, Ty),
259 StructLayout(Ty, *this)))->second;
263 /// InvalidateStructLayoutInfo - TargetData speculatively caches StructLayout
264 /// objects. If a TargetData object is alive when types are being refined and
265 /// removed, this method must be called whenever a StructType is removed to
266 /// avoid a dangling pointer in this cache.
267 void TargetData::InvalidateStructLayoutInfo(const StructType *Ty) const {
268 if (!Layouts) return; // No cache.
270 std::map<std::pair<const TargetData*,const StructType*>,
271 StructLayout>::iterator I = Layouts->find(std::make_pair(this, Ty));
272 if (I != Layouts->end())
278 static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
279 uint64_t &Size, unsigned char &Alignment) {
280 assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
281 switch (Ty->getTypeID()) {
282 case Type::BoolTyID: Size = 1; Alignment = TD->getBoolAlignment(); return;
284 case Type::UByteTyID:
285 case Type::SByteTyID: Size = 1; Alignment = TD->getByteAlignment(); return;
286 case Type::UShortTyID:
287 case Type::ShortTyID: Size = 2; Alignment = TD->getShortAlignment(); return;
289 case Type::IntTyID: Size = 4; Alignment = TD->getIntAlignment(); return;
290 case Type::ULongTyID:
291 case Type::LongTyID: Size = 8; Alignment = TD->getLongAlignment(); return;
292 case Type::FloatTyID: Size = 4; Alignment = TD->getFloatAlignment(); return;
293 case Type::DoubleTyID: Size = 8; Alignment = TD->getDoubleAlignment(); return;
294 case Type::LabelTyID:
295 case Type::PointerTyID:
296 Size = TD->getPointerSize(); Alignment = TD->getPointerAlignment();
298 case Type::ArrayTyID: {
299 const ArrayType *ATy = cast<ArrayType>(Ty);
300 getTypeInfo(ATy->getElementType(), TD, Size, Alignment);
301 unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment;
302 Size = AlignedSize*ATy->getNumElements();
305 case Type::PackedTyID: {
306 const PackedType *PTy = cast<PackedType>(Ty);
307 getTypeInfo(PTy->getElementType(), TD, Size, Alignment);
308 unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment;
309 Size = AlignedSize*PTy->getNumElements();
310 // FIXME: The alignments of specific packed types are target dependent.
311 // For now, just set it to be equal to Size.
315 case Type::StructTyID: {
316 // Get the layout annotation... which is lazily created on demand.
317 const StructLayout *Layout = TD->getStructLayout(cast<StructType>(Ty));
318 Size = Layout->StructSize; Alignment = Layout->StructAlignment;
323 assert(0 && "Bad type for getTypeInfo!!!");
328 uint64_t TargetData::getTypeSize(const Type *Ty) const {
331 getTypeInfo(Ty, this, Size, Align);
335 unsigned char TargetData::getTypeAlignment(const Type *Ty) const {
338 getTypeInfo(Ty, this, Size, Align);
342 unsigned char TargetData::getTypeAlignmentShift(const Type *Ty) const {
343 unsigned Align = getTypeAlignment(Ty);
344 assert(!(Align & (Align-1)) && "Alignment is not a power of two!");
345 return Log2_32(Align);
348 /// getIntPtrType - Return an unsigned integer type that is the same size or
349 /// greater to the host pointer size.
350 const Type *TargetData::getIntPtrType() const {
351 switch (getPointerSize()) {
352 default: assert(0 && "Unknown pointer size!");
353 case 2: return Type::UShortTy;
354 case 4: return Type::UIntTy;
355 case 8: return Type::ULongTy;
360 uint64_t TargetData::getIndexedOffset(const Type *ptrTy,
361 const std::vector<Value*> &Idx) const {
362 const Type *Ty = ptrTy;
363 assert(isa<PointerType>(Ty) && "Illegal argument for getIndexedOffset()");
366 generic_gep_type_iterator<std::vector<Value*>::const_iterator>
367 TI = gep_type_begin(ptrTy, Idx.begin(), Idx.end());
368 for (unsigned CurIDX = 0; CurIDX != Idx.size(); ++CurIDX, ++TI) {
369 if (const StructType *STy = dyn_cast<StructType>(*TI)) {
370 assert(Idx[CurIDX]->getType() == Type::UIntTy && "Illegal struct idx");
371 unsigned FieldNo = cast<ConstantUInt>(Idx[CurIDX])->getValue();
373 // Get structure layout information...
374 const StructLayout *Layout = getStructLayout(STy);
376 // Add in the offset, as calculated by the structure layout info...
377 assert(FieldNo < Layout->MemberOffsets.size() &&"FieldNo out of range!");
378 Result += Layout->MemberOffsets[FieldNo];
380 // Update Ty to refer to current element
381 Ty = STy->getElementType(FieldNo);
383 // Update Ty to refer to current element
384 Ty = cast<SequentialType>(Ty)->getElementType();
386 // Get the array index and the size of each array element.
387 int64_t arrayIdx = cast<ConstantInt>(Idx[CurIDX])->getRawValue();
388 Result += arrayIdx * (int64_t)getTypeSize(Ty);