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"
28 // Handle the Pass registration stuff necessary to use TargetData's.
30 // Register the default SparcV9 implementation...
31 RegisterPass<TargetData> X("targetdata", "Target Data Layout");
34 static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
35 uint64_t &Size, unsigned char &Alignment);
37 //===----------------------------------------------------------------------===//
38 // Support for StructLayout
39 //===----------------------------------------------------------------------===//
41 StructLayout::StructLayout(const StructType *ST, const TargetData &TD) {
45 // Loop over each of the elements, placing them in memory...
46 for (StructType::element_iterator TI = ST->element_begin(),
47 TE = ST->element_end(); TI != TE; ++TI) {
52 getTypeInfo(Ty, &TD, TySize, A);
55 // Add padding if necessary to make the data element aligned properly...
56 if (StructSize % TyAlign != 0)
57 StructSize = (StructSize/TyAlign + 1) * TyAlign; // Add padding...
59 // Keep track of maximum alignment constraint
60 StructAlignment = std::max(TyAlign, StructAlignment);
62 MemberOffsets.push_back(StructSize);
63 StructSize += TySize; // Consume space for this data item
66 // Empty structures have alignment of 1 byte.
67 if (StructAlignment == 0) StructAlignment = 1;
69 // Add padding to the end of the struct so that it could be put in an array
70 // and all array elements would be aligned correctly.
71 if (StructSize % StructAlignment != 0)
72 StructSize = (StructSize/StructAlignment + 1) * StructAlignment;
76 /// getElementContainingOffset - Given a valid offset into the structure,
77 /// return the structure index that contains it.
78 unsigned StructLayout::getElementContainingOffset(uint64_t Offset) const {
79 std::vector<uint64_t>::const_iterator SI =
80 std::upper_bound(MemberOffsets.begin(), MemberOffsets.end(),
82 assert(SI != MemberOffsets.begin() && "Offset not in structure type!");
84 assert(*SI <= Offset && "upper_bound didn't work");
85 assert((SI == MemberOffsets.begin() || *(SI-1) < Offset) &&
86 (SI+1 == MemberOffsets.end() || *(SI+1) > Offset) &&
87 "Upper bound didn't work!");
88 return SI-MemberOffsets.begin();
91 //===----------------------------------------------------------------------===//
92 // TargetData Class Implementation
93 //===----------------------------------------------------------------------===//
95 TargetData::TargetData(const std::string &TargetName,
96 bool isLittleEndian, unsigned char PtrSize,
97 unsigned char PtrAl, unsigned char DoubleAl,
98 unsigned char FloatAl, unsigned char LongAl,
99 unsigned char IntAl, unsigned char ShortAl,
100 unsigned char ByteAl, unsigned char BoolAl) {
102 // If this assert triggers, a pass "required" TargetData information, but the
103 // top level tool did not provide one for it. We do not want to default
104 // construct, or else we might end up using a bad endianness or pointer size!
106 assert(!TargetName.empty() &&
107 "ERROR: Tool did not specify a target data to use!");
109 LittleEndian = isLittleEndian;
110 PointerSize = PtrSize;
111 PointerAlignment = PtrAl;
112 DoubleAlignment = DoubleAl;
113 FloatAlignment = FloatAl;
114 LongAlignment = LongAl;
115 IntAlignment = IntAl;
116 ShortAlignment = ShortAl;
117 ByteAlignment = ByteAl;
118 BoolAlignment = BoolAl;
121 TargetData::TargetData(const std::string &ToolName, const Module *M) {
122 LittleEndian = M->getEndianness() != Module::BigEndian;
123 PointerSize = M->getPointerSize() != Module::Pointer64 ? 4 : 8;
124 PointerAlignment = PointerSize;
125 DoubleAlignment = PointerSize;
127 LongAlignment = PointerSize;
134 /// Layouts - The lazy cache of structure layout information maintained by
137 static std::map<std::pair<const TargetData*,const StructType*>,
138 StructLayout> *Layouts = 0;
141 TargetData::~TargetData() {
143 // Remove any layouts for this TD.
144 std::map<std::pair<const TargetData*,
145 const StructType*>, StructLayout>::iterator
146 I = Layouts->lower_bound(std::make_pair(this, (const StructType*)0));
147 while (I != Layouts->end() && I->first.first == this)
149 if (Layouts->empty()) {
156 const StructLayout *TargetData::getStructLayout(const StructType *Ty) const {
158 Layouts = new std::map<std::pair<const TargetData*,const StructType*>,
160 std::map<std::pair<const TargetData*,const StructType*>,
161 StructLayout>::iterator
162 I = Layouts->lower_bound(std::make_pair(this, Ty));
163 if (I != Layouts->end() && I->first.first == this && I->first.second == Ty)
166 return &Layouts->insert(I, std::make_pair(std::make_pair(this, Ty),
167 StructLayout(Ty, *this)))->second;
171 /// InvalidateStructLayoutInfo - TargetData speculatively caches StructLayout
172 /// objects. If a TargetData object is alive when types are being refined and
173 /// removed, this method must be called whenever a StructType is removed to
174 /// avoid a dangling pointer in this cache.
175 void TargetData::InvalidateStructLayoutInfo(const StructType *Ty) const {
176 if (!Layouts) return; // No cache.
178 std::map<std::pair<const TargetData*,const StructType*>,
179 StructLayout>::iterator I = Layouts->find(std::make_pair(this, Ty));
180 if (I != Layouts->end())
186 static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
187 uint64_t &Size, unsigned char &Alignment) {
188 assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
189 switch (Ty->getTypeID()) {
190 case Type::BoolTyID: Size = 1; Alignment = TD->getBoolAlignment(); return;
192 case Type::UByteTyID:
193 case Type::SByteTyID: Size = 1; Alignment = TD->getByteAlignment(); return;
194 case Type::UShortTyID:
195 case Type::ShortTyID: Size = 2; Alignment = TD->getShortAlignment(); return;
197 case Type::IntTyID: Size = 4; Alignment = TD->getIntAlignment(); return;
198 case Type::ULongTyID:
199 case Type::LongTyID: Size = 8; Alignment = TD->getLongAlignment(); return;
200 case Type::FloatTyID: Size = 4; Alignment = TD->getFloatAlignment(); return;
201 case Type::DoubleTyID: Size = 8; Alignment = TD->getDoubleAlignment(); return;
202 case Type::LabelTyID:
203 case Type::PointerTyID:
204 Size = TD->getPointerSize(); Alignment = TD->getPointerAlignment();
206 case Type::ArrayTyID: {
207 const ArrayType *ATy = cast<ArrayType>(Ty);
208 getTypeInfo(ATy->getElementType(), TD, Size, Alignment);
209 unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment;
210 Size = AlignedSize*ATy->getNumElements();
213 case Type::PackedTyID: {
214 const PackedType *PTy = cast<PackedType>(Ty);
215 getTypeInfo(PTy->getElementType(), TD, Size, Alignment);
216 unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment;
217 Size = AlignedSize*PTy->getNumElements();
218 // FIXME: The alignments of specific packed types are target dependent.
219 // For now, just set it to be equal to Size.
223 case Type::StructTyID: {
224 // Get the layout annotation... which is lazily created on demand.
225 const StructLayout *Layout = TD->getStructLayout(cast<StructType>(Ty));
226 Size = Layout->StructSize; Alignment = Layout->StructAlignment;
231 assert(0 && "Bad type for getTypeInfo!!!");
236 uint64_t TargetData::getTypeSize(const Type *Ty) const {
239 getTypeInfo(Ty, this, Size, Align);
243 unsigned char TargetData::getTypeAlignment(const Type *Ty) const {
246 getTypeInfo(Ty, this, Size, Align);
250 unsigned char TargetData::getTypeAlignmentShift(const Type *Ty) const {
251 unsigned Align = getTypeAlignment(Ty);
252 assert(!(Align & (Align-1)) && "Alignment is not a power of two!");
253 return Log2_32(Align);
256 /// getIntPtrType - Return an unsigned integer type that is the same size or
257 /// greater to the host pointer size.
258 const Type *TargetData::getIntPtrType() const {
259 switch (getPointerSize()) {
260 default: assert(0 && "Unknown pointer size!");
261 case 2: return Type::UShortTy;
262 case 4: return Type::UIntTy;
263 case 8: return Type::ULongTy;
268 uint64_t TargetData::getIndexedOffset(const Type *ptrTy,
269 const std::vector<Value*> &Idx) const {
270 const Type *Ty = ptrTy;
271 assert(isa<PointerType>(Ty) && "Illegal argument for getIndexedOffset()");
274 generic_gep_type_iterator<std::vector<Value*>::const_iterator>
275 TI = gep_type_begin(ptrTy, Idx.begin(), Idx.end());
276 for (unsigned CurIDX = 0; CurIDX != Idx.size(); ++CurIDX, ++TI) {
277 if (const StructType *STy = dyn_cast<StructType>(*TI)) {
278 assert(Idx[CurIDX]->getType() == Type::UIntTy && "Illegal struct idx");
279 unsigned FieldNo = cast<ConstantUInt>(Idx[CurIDX])->getValue();
281 // Get structure layout information...
282 const StructLayout *Layout = getStructLayout(STy);
284 // Add in the offset, as calculated by the structure layout info...
285 assert(FieldNo < Layout->MemberOffsets.size() &&"FieldNo out of range!");
286 Result += Layout->MemberOffsets[FieldNo];
288 // Update Ty to refer to current element
289 Ty = STy->getElementType(FieldNo);
291 // Update Ty to refer to current element
292 Ty = cast<SequentialType>(Ty)->getElementType();
294 // Get the array index and the size of each array element.
295 int64_t arrayIdx = cast<ConstantInt>(Idx[CurIDX])->getRawValue();
296 Result += arrayIdx * (int64_t)getTypeSize(Ty);