Adjust to the changed StructType interface. In particular, getElementTypes() is...
[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.  It uses lazy annotations to cache information about how 
12 // structure types are laid out and used.
13 //
14 // This structure should be created once, filled in if the defaults are not
15 // correct and then passed around by const&.  None of the members functions
16 // require modification to the object.
17 //
18 //===----------------------------------------------------------------------===//
19
20 #include "llvm/Target/TargetData.h"
21 #include "llvm/Module.h"
22 #include "llvm/DerivedTypes.h"
23 #include "llvm/Constants.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 Annotation
37 //===----------------------------------------------------------------------===//
38
39 StructLayout::StructLayout(const StructType *ST, const TargetData &TD) 
40   : Annotation(TD.getStructLayoutAID()) {
41   StructAlignment = 0;
42   StructSize = 0;
43
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) {
47     const Type *Ty = *TI;
48     unsigned char A;
49     unsigned TyAlign;
50     uint64_t TySize;
51     getTypeInfo(Ty, &TD, TySize, A);
52     TyAlign = A;
53
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...
57
58     // Keep track of maximum alignment constraint
59     StructAlignment = std::max(TyAlign, StructAlignment);
60
61     MemberOffsets.push_back(StructSize);
62     StructSize += TySize;                 // Consume space for this data item
63   }
64
65   // Empty structures have alignment of 1 byte.
66   if (StructAlignment == 0) StructAlignment = 1;
67
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;
72 }
73
74 Annotation *TargetData::TypeAnFactory(AnnotationID AID, const Annotable *T,
75                                       void *D) {
76   const TargetData &TD = *(const TargetData*)D;
77   assert(AID == TD.AID && "Target data annotation ID mismatch!");
78   const Type *Ty = cast<Type>((const Value *)T);
79   assert(isa<StructType>(Ty) && 
80          "Can only create StructLayout annotation on structs!");
81   return new StructLayout(cast<StructType>(Ty), TD);
82 }
83
84 //===----------------------------------------------------------------------===//
85 //                       TargetData Class Implementation
86 //===----------------------------------------------------------------------===//
87
88 TargetData::TargetData(const std::string &TargetName,
89                        bool isLittleEndian, unsigned char PtrSize,
90                        unsigned char PtrAl, unsigned char DoubleAl,
91                        unsigned char FloatAl, unsigned char LongAl, 
92                        unsigned char IntAl, unsigned char ShortAl,
93                        unsigned char ByteAl)
94   : AID(AnnotationManager::getID("TargetData::" + TargetName)) {
95   AnnotationManager::registerAnnotationFactory(AID, TypeAnFactory, this);
96
97   // If this assert triggers, a pass "required" TargetData information, but the
98   // top level tool did not provide once for it.  We do not want to default
99   // construct, or else we might end up using a bad endianness or pointer size!
100   //
101   assert(!TargetName.empty() &&
102          "ERROR: Tool did not specify a target data to use!");
103
104   LittleEndian     = isLittleEndian;
105   PointerSize      = PtrSize;
106   PointerAlignment = PtrAl;
107   DoubleAlignment  = DoubleAl;
108   assert(DoubleAlignment == PtrAl &&
109          "Double alignment and pointer alignment agree for now!");
110   FloatAlignment   = FloatAl;
111   LongAlignment    = LongAl;
112   IntAlignment     = IntAl;
113   ShortAlignment   = ShortAl;
114   ByteAlignment    = ByteAl;
115 }
116
117 TargetData::TargetData(const std::string &ToolName, const Module *M)
118   : AID(AnnotationManager::getID("TargetData::" + ToolName)) {
119   AnnotationManager::registerAnnotationFactory(AID, TypeAnFactory, this);
120
121   LittleEndian     = M->getEndianness() != Module::BigEndian;
122   PointerSize      = M->getPointerSize() != Module::Pointer64 ? 4 : 8;
123   PointerAlignment = PointerSize;
124   DoubleAlignment  = PointerSize;
125   FloatAlignment   = 4;
126   LongAlignment    = 8;
127   IntAlignment     = 4;
128   ShortAlignment   = 2;
129   ByteAlignment    = 1;
130 }
131
132 TargetData::~TargetData() {
133   AnnotationManager::registerAnnotationFactory(AID, 0);   // Deregister factory
134 }
135
136 static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
137                                uint64_t &Size, unsigned char &Alignment) {
138   assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
139   switch (Ty->getPrimitiveID()) {
140   case Type::VoidTyID:
141   case Type::BoolTyID:
142   case Type::UByteTyID:
143   case Type::SByteTyID:  Size = 1; Alignment = TD->getByteAlignment(); return;
144   case Type::UShortTyID:
145   case Type::ShortTyID:  Size = 2; Alignment = TD->getShortAlignment(); return;
146   case Type::UIntTyID:
147   case Type::IntTyID:    Size = 4; Alignment = TD->getIntAlignment(); return;
148   case Type::ULongTyID:
149   case Type::LongTyID:   Size = 8; Alignment = TD->getLongAlignment(); return;
150   case Type::FloatTyID:  Size = 4; Alignment = TD->getFloatAlignment(); return;
151   case Type::DoubleTyID: Size = 8; Alignment = TD->getDoubleAlignment(); return;
152   case Type::LabelTyID:
153   case Type::PointerTyID:
154     Size = TD->getPointerSize(); Alignment = TD->getPointerAlignment();
155     return;
156   case Type::ArrayTyID: {
157     const ArrayType *ATy = (const ArrayType *)Ty;
158     getTypeInfo(ATy->getElementType(), TD, Size, Alignment);
159     Size *= ATy->getNumElements();
160     return;
161   }
162   case Type::StructTyID: {
163     // Get the layout annotation... which is lazily created on demand.
164     const StructLayout *Layout = TD->getStructLayout((const StructType*)Ty);
165     Size = Layout->StructSize; Alignment = Layout->StructAlignment;
166     return;
167   }
168     
169   case Type::TypeTyID:
170   default:
171     assert(0 && "Bad type for getTypeInfo!!!");
172     return;
173   }
174 }
175
176 uint64_t TargetData::getTypeSize(const Type *Ty) const {
177   uint64_t Size;
178   unsigned char Align;
179   getTypeInfo(Ty, this, Size, Align);
180   return Size;
181 }
182
183 unsigned char TargetData::getTypeAlignment(const Type *Ty) const {
184   uint64_t Size;
185   unsigned char Align;
186   getTypeInfo(Ty, this, Size, Align);
187   return Align;
188 }
189
190 /// getIntPtrType - Return an unsigned integer type that is the same size or
191 /// greater to the host pointer size.
192 const Type *TargetData::getIntPtrType() const {
193   switch (getPointerSize()) {
194   default: assert(0 && "Unknown pointer size!");
195   case 2: return Type::UShortTy;
196   case 4: return Type::UIntTy;
197   case 8: return Type::ULongTy;
198   }
199 }
200
201
202 uint64_t TargetData::getIndexedOffset(const Type *ptrTy,
203                                       const std::vector<Value*> &Idx) const {
204   const Type *Ty = ptrTy;
205   assert(isa<PointerType>(Ty) && "Illegal argument for getIndexedOffset()");
206   uint64_t Result = 0;
207
208   for (unsigned CurIDX = 0; CurIDX != Idx.size(); ++CurIDX) {
209     if (Idx[CurIDX]->getType() == Type::LongTy) {
210       // Update Ty to refer to current element
211       Ty = cast<SequentialType>(Ty)->getElementType();
212
213       // Get the array index and the size of each array element.
214       int64_t arrayIdx = cast<ConstantSInt>(Idx[CurIDX])->getValue();
215       Result += arrayIdx * (int64_t)getTypeSize(Ty);
216     } else {
217       const StructType *STy = cast<StructType>(Ty);
218       assert(Idx[CurIDX]->getType() == Type::UByteTy && "Illegal struct idx");
219       unsigned FieldNo = cast<ConstantUInt>(Idx[CurIDX])->getValue();
220
221       // Get structure layout information...
222       const StructLayout *Layout = getStructLayout(STy);
223
224       // Add in the offset, as calculated by the structure layout info...
225       assert(FieldNo < Layout->MemberOffsets.size() &&"FieldNo out of range!");
226       Result += Layout->MemberOffsets[FieldNo];
227
228       // Update Ty to refer to current element
229       Ty = STy->getElementType(FieldNo);
230     }
231   }
232
233   return Result;
234 }
235