* Add BoolAlignment to TargetData, default is 1 byte, size 1 byte
[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 using namespace llvm;
25
26 // Handle the Pass registration stuff necessary to use TargetData's.
27 namespace {
28   // Register the default SparcV9 implementation...
29   RegisterPass<TargetData> X("targetdata", "Target Data Layout");
30 }
31
32 static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
33                                uint64_t &Size, unsigned char &Alignment);
34
35 //===----------------------------------------------------------------------===//
36 // Support for StructLayout
37 //===----------------------------------------------------------------------===//
38
39 StructLayout::StructLayout(const StructType *ST, const TargetData &TD) {
40   StructAlignment = 0;
41   StructSize = 0;
42
43   // Loop over each of the elements, placing them in memory...
44   for (StructType::element_iterator TI = ST->element_begin(), 
45          TE = ST->element_end(); TI != TE; ++TI) {
46     const Type *Ty = *TI;
47     unsigned char A;
48     unsigned TyAlign;
49     uint64_t TySize;
50     getTypeInfo(Ty, &TD, TySize, A);
51     TyAlign = A;
52
53     // Add padding if necessary to make the data element aligned properly...
54     if (StructSize % TyAlign != 0)
55       StructSize = (StructSize/TyAlign + 1) * TyAlign;   // Add padding...
56
57     // Keep track of maximum alignment constraint
58     StructAlignment = std::max(TyAlign, StructAlignment);
59
60     MemberOffsets.push_back(StructSize);
61     StructSize += TySize;                 // Consume space for this data item
62   }
63
64   // Empty structures have alignment of 1 byte.
65   if (StructAlignment == 0) StructAlignment = 1;
66
67   // Add padding to the end of the struct so that it could be put in an array
68   // and all array elements would be aligned correctly.
69   if (StructSize % StructAlignment != 0)
70     StructSize = (StructSize/StructAlignment + 1) * StructAlignment;
71 }
72
73 //===----------------------------------------------------------------------===//
74 //                       TargetData Class Implementation
75 //===----------------------------------------------------------------------===//
76
77 TargetData::TargetData(const std::string &TargetName,
78                        bool isLittleEndian, unsigned char PtrSize,
79                        unsigned char PtrAl, unsigned char DoubleAl,
80                        unsigned char FloatAl, unsigned char LongAl, 
81                        unsigned char IntAl, unsigned char ShortAl,
82                        unsigned char ByteAl, unsigned char BoolAl) {
83
84   // If this assert triggers, a pass "required" TargetData information, but the
85   // top level tool did not provide one for it.  We do not want to default
86   // construct, or else we might end up using a bad endianness or pointer size!
87   //
88   assert(!TargetName.empty() &&
89          "ERROR: Tool did not specify a target data to use!");
90
91   LittleEndian     = isLittleEndian;
92   PointerSize      = PtrSize;
93   PointerAlignment = PtrAl;
94   DoubleAlignment  = DoubleAl;
95   FloatAlignment   = FloatAl;
96   LongAlignment    = LongAl;
97   IntAlignment     = IntAl;
98   ShortAlignment   = ShortAl;
99   ByteAlignment    = ByteAl;
100   BoolAlignment    = BoolAl;
101 }
102
103 TargetData::TargetData(const std::string &ToolName, const Module *M) {
104   LittleEndian     = M->getEndianness() != Module::BigEndian;
105   PointerSize      = M->getPointerSize() != Module::Pointer64 ? 4 : 8;
106   PointerAlignment = PointerSize;
107   DoubleAlignment  = PointerSize;
108   FloatAlignment   = 4;
109   LongAlignment    = 8;
110   IntAlignment     = 4;
111   ShortAlignment   = 2;
112   ByteAlignment    = 1;
113   BoolAlignment    = 1;
114 }
115
116 static std::map<std::pair<const TargetData*,const StructType*>,
117                 StructLayout> *Layouts = 0;
118
119
120 TargetData::~TargetData() {
121   if (Layouts) {
122     // Remove any layouts for this TD.
123     std::map<std::pair<const TargetData*,
124       const StructType*>, StructLayout>::iterator
125       I = Layouts->lower_bound(std::make_pair(this, (const StructType*)0));
126     while (I != Layouts->end() && I->first.first == this)
127       Layouts->erase(I++);
128     if (Layouts->empty()) {
129       delete Layouts;
130       Layouts = 0;
131     }
132   }
133 }
134
135 const StructLayout *TargetData::getStructLayout(const StructType *Ty) const {
136   if (Layouts == 0)
137     Layouts = new std::map<std::pair<const TargetData*,const StructType*>,
138                            StructLayout>();
139   std::map<std::pair<const TargetData*,const StructType*>,
140                      StructLayout>::iterator
141     I = Layouts->lower_bound(std::make_pair(this, Ty));
142   if (I != Layouts->end() && I->first.first == this && I->first.second == Ty)
143     return &I->second;
144   else {
145     return &Layouts->insert(I, std::make_pair(std::make_pair(this, Ty),
146                                               StructLayout(Ty, *this)))->second;
147   }
148 }
149
150 static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
151                                uint64_t &Size, unsigned char &Alignment) {
152   assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
153   switch (Ty->getTypeID()) {
154   case Type::BoolTyID:   Size = 1; Alignment = TD->getBoolAlignment(); return;
155   case Type::VoidTyID:
156   case Type::UByteTyID:
157   case Type::SByteTyID:  Size = 1; Alignment = TD->getByteAlignment(); return;
158   case Type::UShortTyID:
159   case Type::ShortTyID:  Size = 2; Alignment = TD->getShortAlignment(); return;
160   case Type::UIntTyID:
161   case Type::IntTyID:    Size = 4; Alignment = TD->getIntAlignment(); return;
162   case Type::ULongTyID:
163   case Type::LongTyID:   Size = 8; Alignment = TD->getLongAlignment(); return;
164   case Type::FloatTyID:  Size = 4; Alignment = TD->getFloatAlignment(); return;
165   case Type::DoubleTyID: Size = 8; Alignment = TD->getDoubleAlignment(); return;
166   case Type::LabelTyID:
167   case Type::PointerTyID:
168     Size = TD->getPointerSize(); Alignment = TD->getPointerAlignment();
169     return;
170   case Type::ArrayTyID: {
171     const ArrayType *ATy = cast<ArrayType>(Ty);
172     getTypeInfo(ATy->getElementType(), TD, Size, Alignment);
173     unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment;
174     Size = AlignedSize*ATy->getNumElements();
175     return;
176   }
177   case Type::StructTyID: {
178     // Get the layout annotation... which is lazily created on demand.
179     const StructLayout *Layout = TD->getStructLayout(cast<StructType>(Ty));
180     Size = Layout->StructSize; Alignment = Layout->StructAlignment;
181     return;
182   }
183     
184   default:
185     assert(0 && "Bad type for getTypeInfo!!!");
186     return;
187   }
188 }
189
190 uint64_t TargetData::getTypeSize(const Type *Ty) const {
191   uint64_t Size;
192   unsigned char Align;
193   getTypeInfo(Ty, this, Size, Align);
194   return Size;
195 }
196
197 unsigned char TargetData::getTypeAlignment(const Type *Ty) const {
198   uint64_t Size;
199   unsigned char Align;
200   getTypeInfo(Ty, this, Size, Align);
201   return Align;
202 }
203
204 /// getIntPtrType - Return an unsigned integer type that is the same size or
205 /// greater to the host pointer size.
206 const Type *TargetData::getIntPtrType() const {
207   switch (getPointerSize()) {
208   default: assert(0 && "Unknown pointer size!");
209   case 2: return Type::UShortTy;
210   case 4: return Type::UIntTy;
211   case 8: return Type::ULongTy;
212   }
213 }
214
215
216 uint64_t TargetData::getIndexedOffset(const Type *ptrTy,
217                                       const std::vector<Value*> &Idx) const {
218   const Type *Ty = ptrTy;
219   assert(isa<PointerType>(Ty) && "Illegal argument for getIndexedOffset()");
220   uint64_t Result = 0;
221
222   generic_gep_type_iterator<std::vector<Value*>::const_iterator>
223     TI = gep_type_begin(ptrTy, Idx.begin(), Idx.end());
224   for (unsigned CurIDX = 0; CurIDX != Idx.size(); ++CurIDX, ++TI) {
225     if (const StructType *STy = dyn_cast<StructType>(*TI)) {
226       assert(Idx[CurIDX]->getType() == Type::UIntTy && "Illegal struct idx");
227       unsigned FieldNo = cast<ConstantUInt>(Idx[CurIDX])->getValue();
228
229       // Get structure layout information...
230       const StructLayout *Layout = getStructLayout(STy);
231
232       // Add in the offset, as calculated by the structure layout info...
233       assert(FieldNo < Layout->MemberOffsets.size() &&"FieldNo out of range!");
234       Result += Layout->MemberOffsets[FieldNo];
235
236       // Update Ty to refer to current element
237       Ty = STy->getElementType(FieldNo);
238     } else {
239       // Update Ty to refer to current element
240       Ty = cast<SequentialType>(Ty)->getElementType();
241
242       // Get the array index and the size of each array element.
243       int64_t arrayIdx = cast<ConstantInt>(Idx[CurIDX])->getRawValue();
244       Result += arrayIdx * (int64_t)getTypeSize(Ty);
245     }
246   }
247
248   return Result;
249 }
250