Add a new constructor to TargetData that builds a TargetData from its
[oota-llvm.git] / lib / Target / TargetData.cpp
1 //===-- TargetData.cpp - Data size & alignment routines --------------------==//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
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.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines target properties related to datatype size/offset/alignment
11 // information.
12 //
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.
16 //
17 //===----------------------------------------------------------------------===//
18
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"
26 #include <algorithm>
27 #include <cstdlib>
28 using namespace llvm;
29
30 // Handle the Pass registration stuff necessary to use TargetData's.
31 namespace {
32   // Register the default SparcV9 implementation...
33   RegisterPass<TargetData> X("targetdata", "Target Data Layout");
34 }
35
36 static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
37                                uint64_t &Size, unsigned char &Alignment);
38
39 //===----------------------------------------------------------------------===//
40 // Support for StructLayout
41 //===----------------------------------------------------------------------===//
42
43 StructLayout::StructLayout(const StructType *ST, const TargetData &TD) {
44   StructAlignment = 0;
45   StructSize = 0;
46
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) {
50     const Type *Ty = *TI;
51     unsigned char A;
52     unsigned TyAlign;
53     uint64_t TySize;
54     getTypeInfo(Ty, &TD, TySize, A);
55     TyAlign = A;
56
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...
60
61     // Keep track of maximum alignment constraint
62     StructAlignment = std::max(TyAlign, StructAlignment);
63
64     MemberOffsets.push_back(StructSize);
65     StructSize += TySize;                 // Consume space for this data item
66   }
67
68   // Empty structures have alignment of 1 byte.
69   if (StructAlignment == 0) StructAlignment = 1;
70
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;
75 }
76
77
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(),
83                      Offset);
84   assert(SI != MemberOffsets.begin() && "Offset not in structure type!");
85   --SI;
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();
91 }
92
93 //===----------------------------------------------------------------------===//
94 //                       TargetData Class Implementation
95 //===----------------------------------------------------------------------===//
96
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) {
103
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!
107   //
108   assert(!TargetName.empty() &&
109          "ERROR: Tool did not specify a target data to use!");
110
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;
121 }
122
123 TargetData::TargetData(const std::string &TargetName,
124                        const std::string &TargetDescription) {
125   std::string temp = TargetDescription;
126   
127   LittleEndian = false;
128   PointerSize = 8;
129   PointerAlignment   = 8;
130   DoubleAlignment = 8;
131   FloatAlignment = 4;
132   LongAlignment   = 8;
133   IntAlignment   = 4;
134   ShortAlignment  = 2;
135   ByteAlignment  = 1;
136   BoolAlignment   = 1;
137   
138   while (temp.length() > 0) {
139     std::string token = getToken(temp, "-");
140     
141     switch(token[0]) {
142     case 'E':
143                 LittleEndian = false;
144         break;
145     case 'e':
146                 LittleEndian = true;
147         break;
148     case 'p':
149                 PointerSize = atoi(getToken(token,":").c_str()) / 8;
150                 PointerAlignment = atoi(getToken(token,":").c_str()) / 8;
151                 break;
152     case 'd':
153                 token = getToken(token,":"); //Ignore the size
154                 DoubleAlignment = atoi(getToken(token,":").c_str()) / 8;
155         break;
156     case 'f':
157                 token = getToken(token, ":"); //Ignore the size
158                 FloatAlignment = atoi(getToken(token, ":").c_str()) / 8;
159         break;
160     case 'l':
161                 token = getToken(token, ":"); //Ignore the size
162                 LongAlignment = atoi(getToken(token, ":").c_str()) / 8;
163         break;
164     case 'i':
165                 token = getToken(token, ":"); //Ignore the size
166                 IntAlignment = atoi(getToken(token, ":").c_str()) / 8;
167         break;
168     case 's':
169                 token = getToken(token, ":"); //Ignore the size
170                 ShortAlignment = atoi(getToken(token, ":").c_str()) / 8;
171         break;
172     case 'b':
173                 token = getToken(token, ":"); //Ignore the size
174                 ByteAlignment = atoi(getToken(token, ":").c_str()) / 8;
175         break;
176     case 'B':
177                 token = getToken(token, ":"); //Ignore the size
178                 BoolAlignment = atoi(getToken(token, ":").c_str()) / 8;
179         break;
180     default:
181         break;
182     }
183   }
184 }
185
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;
191   FloatAlignment   = 4;
192   LongAlignment    = PointerSize;
193   IntAlignment     = 4;
194   ShortAlignment   = 2;
195   ByteAlignment    = 1;
196   BoolAlignment    = 1;
197 }
198
199 /// Layouts - The lazy cache of structure layout information maintained by
200 /// TargetData.
201 ///
202 static std::map<std::pair<const TargetData*,const StructType*>,
203                 StructLayout> *Layouts = 0;
204
205
206 TargetData::~TargetData() {
207   if (Layouts) {
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)
213       Layouts->erase(I++);
214     if (Layouts->empty()) {
215       delete Layouts;
216       Layouts = 0;
217     }
218   }
219 }
220
221 const StructLayout *TargetData::getStructLayout(const StructType *Ty) const {
222   if (Layouts == 0)
223     Layouts = new std::map<std::pair<const TargetData*,const StructType*>,
224                            StructLayout>();
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)
229     return &I->second;
230   else {
231     return &Layouts->insert(I, std::make_pair(std::make_pair(this, Ty),
232                                               StructLayout(Ty, *this)))->second;
233   }
234 }
235
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.
242
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())
246     Layouts->erase(I);
247 }
248
249
250
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;
256   case Type::VoidTyID:
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;
261   case Type::UIntTyID:
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();
270     return;
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();
276     return;
277   }
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.
285     Alignment = Size;
286     return;
287   }
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;
292     return;
293   }
294
295   default:
296     assert(0 && "Bad type for getTypeInfo!!!");
297     return;
298   }
299 }
300
301 uint64_t TargetData::getTypeSize(const Type *Ty) const {
302   uint64_t Size;
303   unsigned char Align;
304   getTypeInfo(Ty, this, Size, Align);
305   return Size;
306 }
307
308 unsigned char TargetData::getTypeAlignment(const Type *Ty) const {
309   uint64_t Size;
310   unsigned char Align;
311   getTypeInfo(Ty, this, Size, Align);
312   return Align;
313 }
314
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);
319 }
320
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;
329   }
330 }
331
332
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()");
337   uint64_t Result = 0;
338
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();
345
346       // Get structure layout information...
347       const StructLayout *Layout = getStructLayout(STy);
348
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];
352
353       // Update Ty to refer to current element
354       Ty = STy->getElementType(FieldNo);
355     } else {
356       // Update Ty to refer to current element
357       Ty = cast<SequentialType>(Ty)->getElementType();
358
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);
362     }
363   }
364
365   return Result;
366 }
367