Add a method to generate a string representation from a TargetData.
[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 #include <sstream>
29 using namespace llvm;
30
31 // Handle the Pass registration stuff necessary to use TargetData's.
32 namespace {
33   // Register the default SparcV9 implementation...
34   RegisterPass<TargetData> X("targetdata", "Target Data Layout");
35 }
36
37 static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
38                                uint64_t &Size, unsigned char &Alignment);
39
40 //===----------------------------------------------------------------------===//
41 // Support for StructLayout
42 //===----------------------------------------------------------------------===//
43
44 StructLayout::StructLayout(const StructType *ST, const TargetData &TD) {
45   StructAlignment = 0;
46   StructSize = 0;
47
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) {
51     const Type *Ty = *TI;
52     unsigned char A;
53     unsigned TyAlign;
54     uint64_t TySize;
55     getTypeInfo(Ty, &TD, TySize, A);
56     TyAlign = A;
57
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...
61
62     // Keep track of maximum alignment constraint
63     StructAlignment = std::max(TyAlign, StructAlignment);
64
65     MemberOffsets.push_back(StructSize);
66     StructSize += TySize;                 // Consume space for this data item
67   }
68
69   // Empty structures have alignment of 1 byte.
70   if (StructAlignment == 0) StructAlignment = 1;
71
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;
76 }
77
78
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(),
84                      Offset);
85   assert(SI != MemberOffsets.begin() && "Offset not in structure type!");
86   --SI;
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();
92 }
93
94 //===----------------------------------------------------------------------===//
95 //                       TargetData Class Implementation
96 //===----------------------------------------------------------------------===//
97
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) {
104
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!
108   //
109   assert(!TargetName.empty() &&
110          "ERROR: Tool did not specify a target data to use!");
111
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;
122 }
123
124 TargetData::TargetData(const std::string &TargetName,
125                        const std::string &TargetDescription) {
126   std::string temp = TargetDescription;
127   
128   LittleEndian = false;
129   PointerSize = 8;
130   PointerAlignment   = 8;
131   DoubleAlignment = 8;
132   FloatAlignment = 4;
133   LongAlignment   = 8;
134   IntAlignment   = 4;
135   ShortAlignment  = 2;
136   ByteAlignment  = 1;
137   BoolAlignment   = 1;
138   
139   while (temp.length() > 0) {
140     std::string token = getToken(temp, "-");
141     
142     switch(token[0]) {
143     case 'E':
144       LittleEndian = false;
145       break;
146     case 'e':
147       LittleEndian = true;
148       break;
149     case 'p':
150       PointerSize = atoi(getToken(token,":").c_str()) / 8;
151       PointerAlignment = atoi(getToken(token,":").c_str()) / 8;
152       break;
153     case 'd':
154       token = getToken(token,":"); //Ignore the size
155       DoubleAlignment = atoi(getToken(token,":").c_str()) / 8;
156       break;
157     case 'f':
158       token = getToken(token, ":"); //Ignore the size
159       FloatAlignment = atoi(getToken(token, ":").c_str()) / 8;
160       break;
161     case 'l':
162       token = getToken(token, ":"); //Ignore the size
163       LongAlignment = atoi(getToken(token, ":").c_str()) / 8;
164       break;
165     case 'i':
166       token = getToken(token, ":"); //Ignore the size
167       IntAlignment = atoi(getToken(token, ":").c_str()) / 8;
168       break;
169     case 's':
170       token = getToken(token, ":"); //Ignore the size
171       ShortAlignment = atoi(getToken(token, ":").c_str()) / 8;
172       break;
173     case 'b':
174       token = getToken(token, ":"); //Ignore the size
175       ByteAlignment = atoi(getToken(token, ":").c_str()) / 8;
176       break;
177     case 'B':
178       token = getToken(token, ":"); //Ignore the size
179       BoolAlignment = atoi(getToken(token, ":").c_str()) / 8;
180       break;
181     default:
182       break;
183     }
184   }
185 }
186
187 TargetData::TargetData(const std::string &ToolName, const Module *M) {
188   LittleEndian     = M->getEndianness() != Module::BigEndian;
189   PointerSize      = M->getPointerSize() != Module::Pointer64 ? 4 : 8;
190   PointerAlignment = PointerSize;
191   DoubleAlignment  = PointerSize;
192   FloatAlignment   = 4;
193   LongAlignment    = PointerSize;
194   IntAlignment     = 4;
195   ShortAlignment   = 2;
196   ByteAlignment    = 1;
197   BoolAlignment    = 1;
198 }
199
200 /// Layouts - The lazy cache of structure layout information maintained by
201 /// TargetData.
202 ///
203 static std::map<std::pair<const TargetData*,const StructType*>,
204                 StructLayout> *Layouts = 0;
205
206
207 TargetData::~TargetData() {
208   if (Layouts) {
209     // Remove any layouts for this TD.
210     std::map<std::pair<const TargetData*,
211       const StructType*>, StructLayout>::iterator
212       I = Layouts->lower_bound(std::make_pair(this, (const StructType*)0));
213     while (I != Layouts->end() && I->first.first == this)
214       Layouts->erase(I++);
215     if (Layouts->empty()) {
216       delete Layouts;
217       Layouts = 0;
218     }
219   }
220 }
221
222 std::string TargetData::getStringRepresentation() const {
223   std::stringstream repr;
224   
225   if (LittleEndian)
226     repr << "e";
227   else
228     repr << "E";
229   
230   repr << "-p:" << (PointerSize * 8) << ":" << (PointerAlignment * 8);
231   repr << "-d:64:" << (DoubleAlignment * 8);
232   repr << "-f:32:" << (FloatAlignment * 8);
233   repr << "-l:64:" << (LongAlignment * 8);
234   repr << "-i:32:" << (IntAlignment * 8);
235   repr << "-s:16:" << (ShortAlignment * 8);
236   repr << "-b:8:" << (ByteAlignment * 8);
237   repr << "-B:8:" << (BoolAlignment * 8);
238   
239   return repr.str();
240 }
241
242 const StructLayout *TargetData::getStructLayout(const StructType *Ty) const {
243   if (Layouts == 0)
244     Layouts = new std::map<std::pair<const TargetData*,const StructType*>,
245                            StructLayout>();
246   std::map<std::pair<const TargetData*,const StructType*>,
247                      StructLayout>::iterator
248     I = Layouts->lower_bound(std::make_pair(this, Ty));
249   if (I != Layouts->end() && I->first.first == this && I->first.second == Ty)
250     return &I->second;
251   else {
252     return &Layouts->insert(I, std::make_pair(std::make_pair(this, Ty),
253                                               StructLayout(Ty, *this)))->second;
254   }
255 }
256
257 /// InvalidateStructLayoutInfo - TargetData speculatively caches StructLayout
258 /// objects.  If a TargetData object is alive when types are being refined and
259 /// removed, this method must be called whenever a StructType is removed to
260 /// avoid a dangling pointer in this cache.
261 void TargetData::InvalidateStructLayoutInfo(const StructType *Ty) const {
262   if (!Layouts) return;  // No cache.
263
264   std::map<std::pair<const TargetData*,const StructType*>,
265            StructLayout>::iterator I = Layouts->find(std::make_pair(this, Ty));
266   if (I != Layouts->end())
267     Layouts->erase(I);
268 }
269
270
271
272 static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
273                                uint64_t &Size, unsigned char &Alignment) {
274   assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
275   switch (Ty->getTypeID()) {
276   case Type::BoolTyID:   Size = 1; Alignment = TD->getBoolAlignment(); return;
277   case Type::VoidTyID:
278   case Type::UByteTyID:
279   case Type::SByteTyID:  Size = 1; Alignment = TD->getByteAlignment(); return;
280   case Type::UShortTyID:
281   case Type::ShortTyID:  Size = 2; Alignment = TD->getShortAlignment(); return;
282   case Type::UIntTyID:
283   case Type::IntTyID:    Size = 4; Alignment = TD->getIntAlignment(); return;
284   case Type::ULongTyID:
285   case Type::LongTyID:   Size = 8; Alignment = TD->getLongAlignment(); return;
286   case Type::FloatTyID:  Size = 4; Alignment = TD->getFloatAlignment(); return;
287   case Type::DoubleTyID: Size = 8; Alignment = TD->getDoubleAlignment(); return;
288   case Type::LabelTyID:
289   case Type::PointerTyID:
290     Size = TD->getPointerSize(); Alignment = TD->getPointerAlignment();
291     return;
292   case Type::ArrayTyID: {
293     const ArrayType *ATy = cast<ArrayType>(Ty);
294     getTypeInfo(ATy->getElementType(), TD, Size, Alignment);
295     unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment;
296     Size = AlignedSize*ATy->getNumElements();
297     return;
298   }
299   case Type::PackedTyID: {
300     const PackedType *PTy = cast<PackedType>(Ty);
301     getTypeInfo(PTy->getElementType(), TD, Size, Alignment);
302     unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment;
303     Size = AlignedSize*PTy->getNumElements();
304     // FIXME: The alignments of specific packed types are target dependent.
305     // For now, just set it to be equal to Size.
306     Alignment = Size;
307     return;
308   }
309   case Type::StructTyID: {
310     // Get the layout annotation... which is lazily created on demand.
311     const StructLayout *Layout = TD->getStructLayout(cast<StructType>(Ty));
312     Size = Layout->StructSize; Alignment = Layout->StructAlignment;
313     return;
314   }
315
316   default:
317     assert(0 && "Bad type for getTypeInfo!!!");
318     return;
319   }
320 }
321
322 uint64_t TargetData::getTypeSize(const Type *Ty) const {
323   uint64_t Size;
324   unsigned char Align;
325   getTypeInfo(Ty, this, Size, Align);
326   return Size;
327 }
328
329 unsigned char TargetData::getTypeAlignment(const Type *Ty) const {
330   uint64_t Size;
331   unsigned char Align;
332   getTypeInfo(Ty, this, Size, Align);
333   return Align;
334 }
335
336 unsigned char TargetData::getTypeAlignmentShift(const Type *Ty) const {
337   unsigned Align = getTypeAlignment(Ty);
338   assert(!(Align & (Align-1)) && "Alignment is not a power of two!");
339   return Log2_32(Align);
340 }
341
342 /// getIntPtrType - Return an unsigned integer type that is the same size or
343 /// greater to the host pointer size.
344 const Type *TargetData::getIntPtrType() const {
345   switch (getPointerSize()) {
346   default: assert(0 && "Unknown pointer size!");
347   case 2: return Type::UShortTy;
348   case 4: return Type::UIntTy;
349   case 8: return Type::ULongTy;
350   }
351 }
352
353
354 uint64_t TargetData::getIndexedOffset(const Type *ptrTy,
355                                       const std::vector<Value*> &Idx) const {
356   const Type *Ty = ptrTy;
357   assert(isa<PointerType>(Ty) && "Illegal argument for getIndexedOffset()");
358   uint64_t Result = 0;
359
360   generic_gep_type_iterator<std::vector<Value*>::const_iterator>
361     TI = gep_type_begin(ptrTy, Idx.begin(), Idx.end());
362   for (unsigned CurIDX = 0; CurIDX != Idx.size(); ++CurIDX, ++TI) {
363     if (const StructType *STy = dyn_cast<StructType>(*TI)) {
364       assert(Idx[CurIDX]->getType() == Type::UIntTy && "Illegal struct idx");
365       unsigned FieldNo = cast<ConstantUInt>(Idx[CurIDX])->getValue();
366
367       // Get structure layout information...
368       const StructLayout *Layout = getStructLayout(STy);
369
370       // Add in the offset, as calculated by the structure layout info...
371       assert(FieldNo < Layout->MemberOffsets.size() &&"FieldNo out of range!");
372       Result += Layout->MemberOffsets[FieldNo];
373
374       // Update Ty to refer to current element
375       Ty = STy->getElementType(FieldNo);
376     } else {
377       // Update Ty to refer to current element
378       Ty = cast<SequentialType>(Ty)->getElementType();
379
380       // Get the array index and the size of each array element.
381       int64_t arrayIdx = cast<ConstantInt>(Idx[CurIDX])->getRawValue();
382       Result += arrayIdx * (int64_t)getTypeSize(Ty);
383     }
384   }
385
386   return Result;
387 }
388