Remove two fields from TargetData which are target specific.
[oota-llvm.git] / lib / Target / TargetData.cpp
1 //===-- TargetData.cpp - Data size & alignment routines --------------------==//
2 //
3 // This file defines target properties related to datatype size/offset/alignment
4 // information.  It uses lazy annotations to cache information about how 
5 // structure types are laid out and used.
6 //
7 // This structure should be created once, filled in if the defaults are not
8 // correct and then passed around by const&.  None of the members functions
9 // require modification to the object.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "llvm/Target/TargetData.h"
14 #include "llvm/Module.h"
15 #include "llvm/DerivedTypes.h"
16 #include "llvm/Constants.h"
17
18 // Handle the Pass registration stuff neccesary to use TargetData's.
19 namespace {
20   // Register the default SparcV9 implementation...
21   RegisterPass<TargetData> X("targetdata", "Target Data Layout");
22 }
23
24
25 static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
26                                uint64_t &Size, unsigned char &Alignment);
27
28 //===----------------------------------------------------------------------===//
29 // Support for StructLayout Annotation
30 //===----------------------------------------------------------------------===//
31
32 StructLayout::StructLayout(const StructType *ST, const TargetData &TD) 
33   : Annotation(TD.getStructLayoutAID()) {
34   StructAlignment = 0;
35   StructSize = 0;
36
37   // Loop over each of the elements, placing them in memory...
38   for (StructType::ElementTypes::const_iterator
39          TI = ST->getElementTypes().begin(), 
40          TE = ST->getElementTypes().end(); TI != TE; ++TI) {
41     const Type *Ty = *TI;
42     unsigned char A;
43     unsigned TyAlign;
44     uint64_t TySize;
45     getTypeInfo(Ty, &TD, TySize, A);
46     TyAlign = A;
47
48     // Add padding if neccesary to make the data element aligned properly...
49     if (StructSize % TyAlign != 0)
50       StructSize = (StructSize/TyAlign + 1) * TyAlign;   // Add padding...
51
52     // Keep track of maximum alignment constraint
53     StructAlignment = std::max(TyAlign, StructAlignment);
54
55     MemberOffsets.push_back(StructSize);
56     StructSize += TySize;                 // Consume space for this data item
57   }
58
59   // Add padding to the end of the struct so that it could be put in an array
60   // and all array elements would be aligned correctly.
61   if (StructSize % StructAlignment != 0)
62     StructSize = (StructSize/StructAlignment + 1) * StructAlignment;
63
64   if (StructSize == 0) {
65     StructSize = 1;           // Empty struct is 1 byte
66     StructAlignment = 1;
67   }
68 }
69
70 Annotation *TargetData::TypeAnFactory(AnnotationID AID, const Annotable *T,
71                                       void *D) {
72   const TargetData &TD = *(const TargetData*)D;
73   assert(AID == TD.AID && "Target data annotation ID mismatch!");
74   const Type *Ty = cast<const Type>((const Value *)T);
75   assert(isa<StructType>(Ty) && 
76          "Can only create StructLayout annotation on structs!");
77   return new StructLayout((const StructType *)Ty, TD);
78 }
79
80 //===----------------------------------------------------------------------===//
81 //                       TargetData Class Implementation
82 //===----------------------------------------------------------------------===//
83
84 TargetData::TargetData(const std::string &TargetName,
85                        bool isLittleEndian, unsigned char PtrSize,
86                        unsigned char PtrAl, unsigned char DoubleAl,
87                        unsigned char FloatAl, unsigned char LongAl, 
88                        unsigned char IntAl, unsigned char ShortAl,
89                        unsigned char ByteAl)
90   : AID(AnnotationManager::getID("TargetData::" + TargetName)) {
91   AnnotationManager::registerAnnotationFactory(AID, TypeAnFactory, this);
92
93   // If this assert triggers, a pass "required" TargetData information, but the
94   // top level tool did not provide once for it.  We do not want to default
95   // construct, or else we might end up using a bad endianness or pointer size!
96   //
97   assert(!TargetName.empty() &&
98          "ERROR: Tool did not specify a target data to use!");
99
100   LittleEndian     = isLittleEndian;
101   PointerSize      = PtrSize;
102   PointerAlignment = PtrAl;
103   DoubleAlignment  = DoubleAl;
104   assert(DoubleAlignment == PtrAl &&
105          "Double alignment and pointer alignment agree for now!");
106   FloatAlignment   = FloatAl;
107   LongAlignment    = LongAl;
108   IntAlignment     = IntAl;
109   ShortAlignment   = ShortAl;
110   ByteAlignment    = ByteAl;
111 }
112
113 TargetData::TargetData(const std::string &ToolName, const Module *M)
114   : AID(AnnotationManager::getID("TargetData::" + ToolName)) {
115   AnnotationManager::registerAnnotationFactory(AID, TypeAnFactory, this);
116
117   LittleEndian     = M->isLittleEndian();
118   PointerSize      = M->has32BitPointers() ? 4 : 8;
119   PointerAlignment = PointerSize;
120   DoubleAlignment  = PointerSize;
121   FloatAlignment   = 4;
122   LongAlignment    = 8;
123   IntAlignment     = 4;
124   ShortAlignment   = 2;
125   ByteAlignment    = 1;
126 }
127
128 TargetData::~TargetData() {
129   AnnotationManager::registerAnnotationFactory(AID, 0);   // Deregister factory
130 }
131
132 static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
133                                uint64_t &Size, unsigned char &Alignment) {
134   assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
135   switch (Ty->getPrimitiveID()) {
136   case Type::VoidTyID:
137   case Type::BoolTyID:
138   case Type::UByteTyID:
139   case Type::SByteTyID:  Size = 1; Alignment = TD->getByteAlignment(); return;
140   case Type::UShortTyID:
141   case Type::ShortTyID:  Size = 2; Alignment = TD->getShortAlignment(); return;
142   case Type::UIntTyID:
143   case Type::IntTyID:    Size = 4; Alignment = TD->getIntAlignment(); return;
144   case Type::ULongTyID:
145   case Type::LongTyID:   Size = 8; Alignment = TD->getLongAlignment(); return;
146   case Type::FloatTyID:  Size = 4; Alignment = TD->getFloatAlignment(); return;
147   case Type::DoubleTyID: Size = 8; Alignment = TD->getDoubleAlignment(); return;
148   case Type::LabelTyID:
149   case Type::PointerTyID:
150     Size = TD->getPointerSize(); Alignment = TD->getPointerAlignment();
151     return;
152   case Type::ArrayTyID: {
153     const ArrayType *ATy = (const ArrayType *)Ty;
154     getTypeInfo(ATy->getElementType(), TD, Size, Alignment);
155     Size *= ATy->getNumElements();
156     return;
157   }
158   case Type::StructTyID: {
159     // Get the layout annotation... which is lazily created on demand.
160     const StructLayout *Layout = TD->getStructLayout((const StructType*)Ty);
161     Size = Layout->StructSize; Alignment = Layout->StructAlignment;
162     return;
163   }
164     
165   case Type::TypeTyID:
166   default:
167     assert(0 && "Bad type for getTypeInfo!!!");
168     return;
169   }
170 }
171
172 uint64_t TargetData::getTypeSize(const Type *Ty) const {
173   uint64_t Size;
174   unsigned char Align;
175   getTypeInfo(Ty, this, Size, Align);
176   return Size;
177 }
178
179 unsigned char TargetData::getTypeAlignment(const Type *Ty) const {
180   uint64_t Size;
181   unsigned char Align;
182   getTypeInfo(Ty, this, Size, Align);
183   return Align;
184 }
185
186 uint64_t TargetData::getIndexedOffset(const Type *ptrTy,
187                                       const std::vector<Value*> &Idx) const {
188   const Type *Ty = ptrTy;
189   assert(isa<PointerType>(Ty) && "Illegal argument for getIndexedOffset()");
190   uint64_t Result = 0;
191
192   for (unsigned CurIDX = 0; CurIDX != Idx.size(); ++CurIDX) {
193     if (Idx[CurIDX]->getType() == Type::LongTy) {
194       // Update Ty to refer to current element
195       Ty = cast<SequentialType>(Ty)->getElementType();
196
197       // Get the array index and the size of each array element.
198       // Both must be known constants, or the index shd be 0; else this fails.
199       int64_t arrayIdx = cast<ConstantSInt>(Idx[CurIDX])->getValue();
200       Result += arrayIdx == 0? 0
201                 : (uint64_t) (arrayIdx * (int64_t) getTypeSize(Ty)); 
202
203     } else if (const StructType *STy = dyn_cast<const StructType>(Ty)) {
204       assert(Idx[CurIDX]->getType() == Type::UByteTy && "Illegal struct idx");
205       unsigned FieldNo = cast<ConstantUInt>(Idx[CurIDX])->getValue();
206
207       // Get structure layout information...
208       const StructLayout *Layout = getStructLayout(STy);
209
210       // Add in the offset, as calculated by the structure layout info...
211       assert(FieldNo < Layout->MemberOffsets.size() &&"FieldNo out of range!");
212       Result += Layout->MemberOffsets[FieldNo];
213
214       // Update Ty to refer to current element
215       Ty = STy->getElementTypes()[FieldNo];
216     } else {
217       assert(0 && "Indexing type that is not struct or array?");
218       return 0;                         // Load directly through ptr
219     }
220   }
221
222   return Result;
223 }