Implement a new InvalidateStructLayoutInfo method and add some comments
[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 <algorithm>
26 using namespace llvm;
27
28 // Handle the Pass registration stuff necessary to use TargetData's.
29 namespace {
30   // Register the default SparcV9 implementation...
31   RegisterPass<TargetData> X("targetdata", "Target Data Layout");
32 }
33
34 static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
35                                uint64_t &Size, unsigned char &Alignment);
36
37 //===----------------------------------------------------------------------===//
38 // Support for StructLayout
39 //===----------------------------------------------------------------------===//
40
41 StructLayout::StructLayout(const StructType *ST, const TargetData &TD) {
42   StructAlignment = 0;
43   StructSize = 0;
44
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) {
48     const Type *Ty = *TI;
49     unsigned char A;
50     unsigned TyAlign;
51     uint64_t TySize;
52     getTypeInfo(Ty, &TD, TySize, A);
53     TyAlign = A;
54
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...
58
59     // Keep track of maximum alignment constraint
60     StructAlignment = std::max(TyAlign, StructAlignment);
61
62     MemberOffsets.push_back(StructSize);
63     StructSize += TySize;                 // Consume space for this data item
64   }
65
66   // Empty structures have alignment of 1 byte.
67   if (StructAlignment == 0) StructAlignment = 1;
68
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;
73 }
74
75
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(),
81                      Offset);
82   assert(SI != MemberOffsets.begin() && "Offset not in structure type!");
83   --SI;
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();
89 }
90
91 //===----------------------------------------------------------------------===//
92 //                       TargetData Class Implementation
93 //===----------------------------------------------------------------------===//
94
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) {
101
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!
105   //
106   assert(!TargetName.empty() &&
107          "ERROR: Tool did not specify a target data to use!");
108
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;
119 }
120
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;
126   FloatAlignment   = 4;
127   LongAlignment    = PointerSize;
128   IntAlignment     = 4;
129   ShortAlignment   = 2;
130   ByteAlignment    = 1;
131   BoolAlignment    = 1;
132 }
133
134 /// Layouts - The lazy cache of structure layout information maintained by
135 /// TargetData.
136 ///
137 static std::map<std::pair<const TargetData*,const StructType*>,
138                 StructLayout> *Layouts = 0;
139
140
141 TargetData::~TargetData() {
142   if (Layouts) {
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)
148       Layouts->erase(I++);
149     if (Layouts->empty()) {
150       delete Layouts;
151       Layouts = 0;
152     }
153   }
154 }
155
156 const StructLayout *TargetData::getStructLayout(const StructType *Ty) const {
157   if (Layouts == 0)
158     Layouts = new std::map<std::pair<const TargetData*,const StructType*>,
159                            StructLayout>();
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)
164     return &I->second;
165   else {
166     return &Layouts->insert(I, std::make_pair(std::make_pair(this, Ty),
167                                               StructLayout(Ty, *this)))->second;
168   }
169 }
170
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.
177
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())
181     Layouts->erase(I);
182 }
183
184
185
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;
191   case Type::VoidTyID:
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;
196   case Type::UIntTyID:
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();
205     return;
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();
211     return;
212   }
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     return;
219   }
220   case Type::StructTyID: {
221     // Get the layout annotation... which is lazily created on demand.
222     const StructLayout *Layout = TD->getStructLayout(cast<StructType>(Ty));
223     Size = Layout->StructSize; Alignment = Layout->StructAlignment;
224     return;
225   }
226
227   default:
228     assert(0 && "Bad type for getTypeInfo!!!");
229     return;
230   }
231 }
232
233 uint64_t TargetData::getTypeSize(const Type *Ty) const {
234   uint64_t Size;
235   unsigned char Align;
236   getTypeInfo(Ty, this, Size, Align);
237   return Size;
238 }
239
240 unsigned char TargetData::getTypeAlignment(const Type *Ty) const {
241   uint64_t Size;
242   unsigned char Align;
243   getTypeInfo(Ty, this, Size, Align);
244   return Align;
245 }
246
247 unsigned char TargetData::getTypeAlignmentShift(const Type *Ty) const {
248   unsigned Align = getTypeAlignment(Ty);
249   assert(!(Align & (Align-1)) && "Alignment is not a power of two!");
250   return Log2_32(Align);
251 }
252
253 /// getIntPtrType - Return an unsigned integer type that is the same size or
254 /// greater to the host pointer size.
255 const Type *TargetData::getIntPtrType() const {
256   switch (getPointerSize()) {
257   default: assert(0 && "Unknown pointer size!");
258   case 2: return Type::UShortTy;
259   case 4: return Type::UIntTy;
260   case 8: return Type::ULongTy;
261   }
262 }
263
264
265 uint64_t TargetData::getIndexedOffset(const Type *ptrTy,
266                                       const std::vector<Value*> &Idx) const {
267   const Type *Ty = ptrTy;
268   assert(isa<PointerType>(Ty) && "Illegal argument for getIndexedOffset()");
269   uint64_t Result = 0;
270
271   generic_gep_type_iterator<std::vector<Value*>::const_iterator>
272     TI = gep_type_begin(ptrTy, Idx.begin(), Idx.end());
273   for (unsigned CurIDX = 0; CurIDX != Idx.size(); ++CurIDX, ++TI) {
274     if (const StructType *STy = dyn_cast<StructType>(*TI)) {
275       assert(Idx[CurIDX]->getType() == Type::UIntTy && "Illegal struct idx");
276       unsigned FieldNo = cast<ConstantUInt>(Idx[CurIDX])->getValue();
277
278       // Get structure layout information...
279       const StructLayout *Layout = getStructLayout(STy);
280
281       // Add in the offset, as calculated by the structure layout info...
282       assert(FieldNo < Layout->MemberOffsets.size() &&"FieldNo out of range!");
283       Result += Layout->MemberOffsets[FieldNo];
284
285       // Update Ty to refer to current element
286       Ty = STy->getElementType(FieldNo);
287     } else {
288       // Update Ty to refer to current element
289       Ty = cast<SequentialType>(Ty)->getElementType();
290
291       // Get the array index and the size of each array element.
292       int64_t arrayIdx = cast<ConstantInt>(Idx[CurIDX])->getRawValue();
293       Result += arrayIdx * (int64_t)getTypeSize(Ty);
294     }
295   }
296
297   return Result;
298 }
299