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"
27 // Handle the Pass registration stuff necessary to use TargetData's.
29 // Register the default SparcV9 implementation...
30 RegisterPass<TargetData> X("targetdata", "Target Data Layout");
33 static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
34 uint64_t &Size, unsigned char &Alignment);
36 //===----------------------------------------------------------------------===//
37 // Support for StructLayout
38 //===----------------------------------------------------------------------===//
40 StructLayout::StructLayout(const StructType *ST, const TargetData &TD) {
44 // Loop over each of the elements, placing them in memory...
45 for (StructType::element_iterator TI = ST->element_begin(),
46 TE = ST->element_end(); TI != TE; ++TI) {
51 getTypeInfo(Ty, &TD, TySize, A);
54 // Add padding if necessary to make the data element aligned properly...
55 if (StructSize % TyAlign != 0)
56 StructSize = (StructSize/TyAlign + 1) * TyAlign; // Add padding...
58 // Keep track of maximum alignment constraint
59 StructAlignment = std::max(TyAlign, StructAlignment);
61 MemberOffsets.push_back(StructSize);
62 StructSize += TySize; // Consume space for this data item
65 // Empty structures have alignment of 1 byte.
66 if (StructAlignment == 0) StructAlignment = 1;
68 // Add padding to the end of the struct so that it could be put in an array
69 // and all array elements would be aligned correctly.
70 if (StructSize % StructAlignment != 0)
71 StructSize = (StructSize/StructAlignment + 1) * StructAlignment;
74 //===----------------------------------------------------------------------===//
75 // TargetData Class Implementation
76 //===----------------------------------------------------------------------===//
78 TargetData::TargetData(const std::string &TargetName,
79 bool isLittleEndian, unsigned char PtrSize,
80 unsigned char PtrAl, unsigned char DoubleAl,
81 unsigned char FloatAl, unsigned char LongAl,
82 unsigned char IntAl, unsigned char ShortAl,
83 unsigned char ByteAl, unsigned char BoolAl) {
85 // If this assert triggers, a pass "required" TargetData information, but the
86 // top level tool did not provide one for it. We do not want to default
87 // construct, or else we might end up using a bad endianness or pointer size!
89 assert(!TargetName.empty() &&
90 "ERROR: Tool did not specify a target data to use!");
92 LittleEndian = isLittleEndian;
93 PointerSize = PtrSize;
94 PointerAlignment = PtrAl;
95 DoubleAlignment = DoubleAl;
96 FloatAlignment = FloatAl;
97 LongAlignment = LongAl;
99 ShortAlignment = ShortAl;
100 ByteAlignment = ByteAl;
101 BoolAlignment = BoolAl;
104 TargetData::TargetData(const std::string &ToolName, const Module *M) {
105 LittleEndian = M->getEndianness() != Module::BigEndian;
106 PointerSize = M->getPointerSize() != Module::Pointer64 ? 4 : 8;
107 PointerAlignment = PointerSize;
108 DoubleAlignment = PointerSize;
110 LongAlignment = PointerSize;
117 static std::map<std::pair<const TargetData*,const StructType*>,
118 StructLayout> *Layouts = 0;
121 TargetData::~TargetData() {
123 // Remove any layouts for this TD.
124 std::map<std::pair<const TargetData*,
125 const StructType*>, StructLayout>::iterator
126 I = Layouts->lower_bound(std::make_pair(this, (const StructType*)0));
127 while (I != Layouts->end() && I->first.first == this)
129 if (Layouts->empty()) {
136 const StructLayout *TargetData::getStructLayout(const StructType *Ty) const {
138 Layouts = new std::map<std::pair<const TargetData*,const StructType*>,
140 std::map<std::pair<const TargetData*,const StructType*>,
141 StructLayout>::iterator
142 I = Layouts->lower_bound(std::make_pair(this, Ty));
143 if (I != Layouts->end() && I->first.first == this && I->first.second == Ty)
146 return &Layouts->insert(I, std::make_pair(std::make_pair(this, Ty),
147 StructLayout(Ty, *this)))->second;
151 static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
152 uint64_t &Size, unsigned char &Alignment) {
153 assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
154 switch (Ty->getTypeID()) {
155 case Type::BoolTyID: Size = 1; Alignment = TD->getBoolAlignment(); return;
157 case Type::UByteTyID:
158 case Type::SByteTyID: Size = 1; Alignment = TD->getByteAlignment(); return;
159 case Type::UShortTyID:
160 case Type::ShortTyID: Size = 2; Alignment = TD->getShortAlignment(); return;
162 case Type::IntTyID: Size = 4; Alignment = TD->getIntAlignment(); return;
163 case Type::ULongTyID:
164 case Type::LongTyID: Size = 8; Alignment = TD->getLongAlignment(); return;
165 case Type::FloatTyID: Size = 4; Alignment = TD->getFloatAlignment(); return;
166 case Type::DoubleTyID: Size = 8; Alignment = TD->getDoubleAlignment(); return;
167 case Type::LabelTyID:
168 case Type::PointerTyID:
169 Size = TD->getPointerSize(); Alignment = TD->getPointerAlignment();
171 case Type::ArrayTyID: {
172 const ArrayType *ATy = cast<ArrayType>(Ty);
173 getTypeInfo(ATy->getElementType(), TD, Size, Alignment);
174 unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment;
175 Size = AlignedSize*ATy->getNumElements();
178 case Type::PackedTyID: {
179 const PackedType *PTy = cast<PackedType>(Ty);
180 getTypeInfo(PTy->getElementType(), TD, Size, Alignment);
181 unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment;
182 Size = AlignedSize*PTy->getNumElements();
185 case Type::StructTyID: {
186 // Get the layout annotation... which is lazily created on demand.
187 const StructLayout *Layout = TD->getStructLayout(cast<StructType>(Ty));
188 Size = Layout->StructSize; Alignment = Layout->StructAlignment;
193 assert(0 && "Bad type for getTypeInfo!!!");
198 uint64_t TargetData::getTypeSize(const Type *Ty) const {
201 getTypeInfo(Ty, this, Size, Align);
205 unsigned char TargetData::getTypeAlignment(const Type *Ty) const {
208 getTypeInfo(Ty, this, Size, Align);
212 unsigned char TargetData::getTypeAlignmentShift(const Type *Ty) const {
213 unsigned Align = getTypeAlignment(Ty);
214 assert(!(Align & (Align-1)) && "Alignment is not a power of two!");
218 /// getIntPtrType - Return an unsigned integer type that is the same size or
219 /// greater to the host pointer size.
220 const Type *TargetData::getIntPtrType() const {
221 switch (getPointerSize()) {
222 default: assert(0 && "Unknown pointer size!");
223 case 2: return Type::UShortTy;
224 case 4: return Type::UIntTy;
225 case 8: return Type::ULongTy;
230 uint64_t TargetData::getIndexedOffset(const Type *ptrTy,
231 const std::vector<Value*> &Idx) const {
232 const Type *Ty = ptrTy;
233 assert(isa<PointerType>(Ty) && "Illegal argument for getIndexedOffset()");
236 generic_gep_type_iterator<std::vector<Value*>::const_iterator>
237 TI = gep_type_begin(ptrTy, Idx.begin(), Idx.end());
238 for (unsigned CurIDX = 0; CurIDX != Idx.size(); ++CurIDX, ++TI) {
239 if (const StructType *STy = dyn_cast<StructType>(*TI)) {
240 assert(Idx[CurIDX]->getType() == Type::UIntTy && "Illegal struct idx");
241 unsigned FieldNo = cast<ConstantUInt>(Idx[CurIDX])->getValue();
243 // Get structure layout information...
244 const StructLayout *Layout = getStructLayout(STy);
246 // Add in the offset, as calculated by the structure layout info...
247 assert(FieldNo < Layout->MemberOffsets.size() &&"FieldNo out of range!");
248 Result += Layout->MemberOffsets[FieldNo];
250 // Update Ty to refer to current element
251 Ty = STy->getElementType(FieldNo);
253 // Update Ty to refer to current element
254 Ty = cast<SequentialType>(Ty)->getElementType();
256 // Get the array index and the size of each array element.
257 int64_t arrayIdx = cast<ConstantInt>(Idx[CurIDX])->getRawValue();
258 Result += arrayIdx * (int64_t)getTypeSize(Ty);