Whoops, 32 bit targets have _4_ byte pointers, not _32_ byte pointers!
[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 SubWordSize,
86                        unsigned char IntRegSize, unsigned char PtrSize,
87                        unsigned char PtrAl, unsigned char DoubleAl,
88                        unsigned char FloatAl, unsigned char LongAl, 
89                        unsigned char IntAl, unsigned char ShortAl,
90                        unsigned char ByteAl)
91   : AID(AnnotationManager::getID("TargetData::" + TargetName)) {
92   AnnotationManager::registerAnnotationFactory(AID, TypeAnFactory, this);
93
94   // If this assert triggers, a pass "required" TargetData information, but the
95   // top level tool did not provide once for it.  We do not want to default
96   // construct, or else we might end up using a bad endianness or pointer size!
97   //
98   assert(!TargetName.empty() &&
99          "ERROR: Tool did not specify a target data to use!");
100
101   LittleEndian     = isLittleEndian;
102   SubWordDataSize  = SubWordSize;
103   IntegerRegSize   = IntRegSize;
104   PointerSize      = PtrSize;
105   PointerAlignment = PtrAl;
106   DoubleAlignment  = DoubleAl;
107   assert(DoubleAlignment == PtrAl &&
108          "Double alignment and pointer alignment agree for now!");
109   FloatAlignment   = FloatAl;
110   LongAlignment    = LongAl;
111   IntAlignment     = IntAl;
112   ShortAlignment   = ShortAl;
113   ByteAlignment    = ByteAl;
114 }
115
116 TargetData::TargetData(const std::string &ToolName, const Module *M)
117   : AID(AnnotationManager::getID("TargetData::" + ToolName)) {
118   AnnotationManager::registerAnnotationFactory(AID, TypeAnFactory, this);
119
120   LittleEndian     = M->isLittleEndian();
121   SubWordDataSize  = 1;
122   IntegerRegSize   = 8;
123   PointerSize      = M->has32BitPointers() ? 4 : 8;
124   PointerAlignment = PointerSize;
125   DoubleAlignment  = PointerSize;
126   FloatAlignment   = 4;
127   LongAlignment    = 8;
128   IntAlignment     = 4;
129   ShortAlignment   = 2;
130   ByteAlignment    = 1;
131 }
132
133 TargetData::~TargetData() {
134   AnnotationManager::registerAnnotationFactory(AID, 0);   // Deregister factory
135 }
136
137 static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
138                                uint64_t &Size, unsigned char &Alignment) {
139   assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
140   switch (Ty->getPrimitiveID()) {
141   case Type::VoidTyID:
142   case Type::BoolTyID:
143   case Type::UByteTyID:
144   case Type::SByteTyID:  Size = 1; Alignment = TD->getByteAlignment(); return;
145   case Type::UShortTyID:
146   case Type::ShortTyID:  Size = 2; Alignment = TD->getShortAlignment(); return;
147   case Type::UIntTyID:
148   case Type::IntTyID:    Size = 4; Alignment = TD->getIntAlignment(); return;
149   case Type::ULongTyID:
150   case Type::LongTyID:   Size = 8; Alignment = TD->getLongAlignment(); return;
151   case Type::FloatTyID:  Size = 4; Alignment = TD->getFloatAlignment(); return;
152   case Type::DoubleTyID: Size = 8; Alignment = TD->getDoubleAlignment(); return;
153   case Type::LabelTyID:
154   case Type::PointerTyID:
155     Size = TD->getPointerSize(); Alignment = TD->getPointerAlignment();
156     return;
157   case Type::ArrayTyID: {
158     const ArrayType *ATy = (const ArrayType *)Ty;
159     getTypeInfo(ATy->getElementType(), TD, Size, Alignment);
160     Size *= ATy->getNumElements();
161     return;
162   }
163   case Type::StructTyID: {
164     // Get the layout annotation... which is lazily created on demand.
165     const StructLayout *Layout = TD->getStructLayout((const StructType*)Ty);
166     Size = Layout->StructSize; Alignment = Layout->StructAlignment;
167     return;
168   }
169     
170   case Type::TypeTyID:
171   default:
172     assert(0 && "Bad type for getTypeInfo!!!");
173     return;
174   }
175 }
176
177 uint64_t TargetData::getTypeSize(const Type *Ty) const {
178   uint64_t Size;
179   unsigned char Align;
180   getTypeInfo(Ty, this, Size, Align);
181   return Size;
182 }
183
184 unsigned char TargetData::getTypeAlignment(const Type *Ty) const {
185   uint64_t Size;
186   unsigned char Align;
187   getTypeInfo(Ty, this, Size, Align);
188   return Align;
189 }
190
191 uint64_t TargetData::getIndexedOffset(const Type *ptrTy,
192                                       const std::vector<Value*> &Idx) const {
193   const Type *Ty = ptrTy;
194   assert(isa<PointerType>(Ty) && "Illegal argument for getIndexedOffset()");
195   uint64_t Result = 0;
196
197   for (unsigned CurIDX = 0; CurIDX != Idx.size(); ++CurIDX) {
198     if (Idx[CurIDX]->getType() == Type::LongTy) {
199       // Update Ty to refer to current element
200       Ty = cast<SequentialType>(Ty)->getElementType();
201
202       // Get the array index and the size of each array element.
203       // Both must be known constants, or the index shd be 0; else this fails.
204       int64_t arrayIdx = cast<ConstantSInt>(Idx[CurIDX])->getValue();
205       Result += arrayIdx == 0? 0
206                 : (uint64_t) (arrayIdx * (int64_t) getTypeSize(Ty)); 
207
208     } else if (const StructType *STy = dyn_cast<const StructType>(Ty)) {
209       assert(Idx[CurIDX]->getType() == Type::UByteTy && "Illegal struct idx");
210       unsigned FieldNo = cast<ConstantUInt>(Idx[CurIDX])->getValue();
211
212       // Get structure layout information...
213       const StructLayout *Layout = getStructLayout(STy);
214
215       // Add in the offset, as calculated by the structure layout info...
216       assert(FieldNo < Layout->MemberOffsets.size() &&"FieldNo out of range!");
217       Result += Layout->MemberOffsets[FieldNo];
218
219       // Update Ty to refer to current element
220       Ty = STy->getElementTypes()[FieldNo];
221     } else {
222       assert(0 && "Indexing type that is not struct or array?");
223       return 0;                         // Load directly through ptr
224     }
225   }
226
227   return Result;
228 }