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 static std::map<std::pair<const TargetData*,const StructType*>,
135 StructLayout> *Layouts = 0;
138 TargetData::~TargetData() {
140 // Remove any layouts for this TD.
141 std::map<std::pair<const TargetData*,
142 const StructType*>, StructLayout>::iterator
143 I = Layouts->lower_bound(std::make_pair(this, (const StructType*)0));
144 while (I != Layouts->end() && I->first.first == this)
146 if (Layouts->empty()) {
153 const StructLayout *TargetData::getStructLayout(const StructType *Ty) const {
155 Layouts = new std::map<std::pair<const TargetData*,const StructType*>,
157 std::map<std::pair<const TargetData*,const StructType*>,
158 StructLayout>::iterator
159 I = Layouts->lower_bound(std::make_pair(this, Ty));
160 if (I != Layouts->end() && I->first.first == this && I->first.second == Ty)
163 return &Layouts->insert(I, std::make_pair(std::make_pair(this, Ty),
164 StructLayout(Ty, *this)))->second;
168 static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
169 uint64_t &Size, unsigned char &Alignment) {
170 assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
171 switch (Ty->getTypeID()) {
172 case Type::BoolTyID: Size = 1; Alignment = TD->getBoolAlignment(); return;
174 case Type::UByteTyID:
175 case Type::SByteTyID: Size = 1; Alignment = TD->getByteAlignment(); return;
176 case Type::UShortTyID:
177 case Type::ShortTyID: Size = 2; Alignment = TD->getShortAlignment(); return;
179 case Type::IntTyID: Size = 4; Alignment = TD->getIntAlignment(); return;
180 case Type::ULongTyID:
181 case Type::LongTyID: Size = 8; Alignment = TD->getLongAlignment(); return;
182 case Type::FloatTyID: Size = 4; Alignment = TD->getFloatAlignment(); return;
183 case Type::DoubleTyID: Size = 8; Alignment = TD->getDoubleAlignment(); return;
184 case Type::LabelTyID:
185 case Type::PointerTyID:
186 Size = TD->getPointerSize(); Alignment = TD->getPointerAlignment();
188 case Type::ArrayTyID: {
189 const ArrayType *ATy = cast<ArrayType>(Ty);
190 getTypeInfo(ATy->getElementType(), TD, Size, Alignment);
191 unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment;
192 Size = AlignedSize*ATy->getNumElements();
195 case Type::PackedTyID: {
196 const PackedType *PTy = cast<PackedType>(Ty);
197 getTypeInfo(PTy->getElementType(), TD, Size, Alignment);
198 unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment;
199 Size = AlignedSize*PTy->getNumElements();
202 case Type::StructTyID: {
203 // Get the layout annotation... which is lazily created on demand.
204 const StructLayout *Layout = TD->getStructLayout(cast<StructType>(Ty));
205 Size = Layout->StructSize; Alignment = Layout->StructAlignment;
210 assert(0 && "Bad type for getTypeInfo!!!");
215 uint64_t TargetData::getTypeSize(const Type *Ty) const {
218 getTypeInfo(Ty, this, Size, Align);
222 unsigned char TargetData::getTypeAlignment(const Type *Ty) const {
225 getTypeInfo(Ty, this, Size, Align);
229 unsigned char TargetData::getTypeAlignmentShift(const Type *Ty) const {
230 unsigned Align = getTypeAlignment(Ty);
231 assert(!(Align & (Align-1)) && "Alignment is not a power of two!");
235 /// getIntPtrType - Return an unsigned integer type that is the same size or
236 /// greater to the host pointer size.
237 const Type *TargetData::getIntPtrType() const {
238 switch (getPointerSize()) {
239 default: assert(0 && "Unknown pointer size!");
240 case 2: return Type::UShortTy;
241 case 4: return Type::UIntTy;
242 case 8: return Type::ULongTy;
247 uint64_t TargetData::getIndexedOffset(const Type *ptrTy,
248 const std::vector<Value*> &Idx) const {
249 const Type *Ty = ptrTy;
250 assert(isa<PointerType>(Ty) && "Illegal argument for getIndexedOffset()");
253 generic_gep_type_iterator<std::vector<Value*>::const_iterator>
254 TI = gep_type_begin(ptrTy, Idx.begin(), Idx.end());
255 for (unsigned CurIDX = 0; CurIDX != Idx.size(); ++CurIDX, ++TI) {
256 if (const StructType *STy = dyn_cast<StructType>(*TI)) {
257 assert(Idx[CurIDX]->getType() == Type::UIntTy && "Illegal struct idx");
258 unsigned FieldNo = cast<ConstantUInt>(Idx[CurIDX])->getValue();
260 // Get structure layout information...
261 const StructLayout *Layout = getStructLayout(STy);
263 // Add in the offset, as calculated by the structure layout info...
264 assert(FieldNo < Layout->MemberOffsets.size() &&"FieldNo out of range!");
265 Result += Layout->MemberOffsets[FieldNo];
267 // Update Ty to refer to current element
268 Ty = STy->getElementType(FieldNo);
270 // Update Ty to refer to current element
271 Ty = cast<SequentialType>(Ty)->getElementType();
273 // Get the array index and the size of each array element.
274 int64_t arrayIdx = cast<ConstantInt>(Idx[CurIDX])->getRawValue();
275 Result += arrayIdx * (int64_t)getTypeSize(Ty);