finegrainify namespacification
[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::ElementTypes::const_iterator
46          TI = ST->getElementTypes().begin(), 
47          TE = ST->getElementTypes().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 Annotation *TargetData::TypeAnFactory(AnnotationID AID, const Annotable *T,
76                                       void *D) {
77   const TargetData &TD = *(const TargetData*)D;
78   assert(AID == TD.AID && "Target data annotation ID mismatch!");
79   const Type *Ty = cast<Type>((const Value *)T);
80   assert(isa<StructType>(Ty) && 
81          "Can only create StructLayout annotation on structs!");
82   return new StructLayout(cast<StructType>(Ty), TD);
83 }
84
85 //===----------------------------------------------------------------------===//
86 //                       TargetData Class Implementation
87 //===----------------------------------------------------------------------===//
88
89 TargetData::TargetData(const std::string &TargetName,
90                        bool isLittleEndian, unsigned char PtrSize,
91                        unsigned char PtrAl, unsigned char DoubleAl,
92                        unsigned char FloatAl, unsigned char LongAl, 
93                        unsigned char IntAl, unsigned char ShortAl,
94                        unsigned char ByteAl)
95   : AID(AnnotationManager::getID("TargetData::" + TargetName)) {
96   AnnotationManager::registerAnnotationFactory(AID, TypeAnFactory, this);
97
98   // If this assert triggers, a pass "required" TargetData information, but the
99   // top level tool did not provide once for it.  We do not want to default
100   // construct, or else we might end up using a bad endianness or pointer size!
101   //
102   assert(!TargetName.empty() &&
103          "ERROR: Tool did not specify a target data to use!");
104
105   LittleEndian     = isLittleEndian;
106   PointerSize      = PtrSize;
107   PointerAlignment = PtrAl;
108   DoubleAlignment  = DoubleAl;
109   assert(DoubleAlignment == PtrAl &&
110          "Double alignment and pointer alignment agree for now!");
111   FloatAlignment   = FloatAl;
112   LongAlignment    = LongAl;
113   IntAlignment     = IntAl;
114   ShortAlignment   = ShortAl;
115   ByteAlignment    = ByteAl;
116 }
117
118 TargetData::TargetData(const std::string &ToolName, const Module *M)
119   : AID(AnnotationManager::getID("TargetData::" + ToolName)) {
120   AnnotationManager::registerAnnotationFactory(AID, TypeAnFactory, this);
121
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    = 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 /// getIntPtrType - Return an unsigned integer type that is the same size or
192 /// greater to the host pointer size.
193 const Type *TargetData::getIntPtrType() const {
194   switch (getPointerSize()) {
195   default: assert(0 && "Unknown pointer size!");
196   case 2: return Type::UShortTy;
197   case 4: return Type::UIntTy;
198   case 8: return Type::ULongTy;
199   }
200 }
201
202
203 uint64_t TargetData::getIndexedOffset(const Type *ptrTy,
204                                       const std::vector<Value*> &Idx) const {
205   const Type *Ty = ptrTy;
206   assert(isa<PointerType>(Ty) && "Illegal argument for getIndexedOffset()");
207   uint64_t Result = 0;
208
209   for (unsigned CurIDX = 0; CurIDX != Idx.size(); ++CurIDX) {
210     if (Idx[CurIDX]->getType() == Type::LongTy) {
211       // Update Ty to refer to current element
212       Ty = cast<SequentialType>(Ty)->getElementType();
213
214       // Get the array index and the size of each array element.
215       int64_t arrayIdx = cast<ConstantSInt>(Idx[CurIDX])->getValue();
216       Result += arrayIdx * (int64_t)getTypeSize(Ty);
217     } else {
218       const StructType *STy = cast<StructType>(Ty);
219       assert(Idx[CurIDX]->getType() == Type::UByteTy && "Illegal struct idx");
220       unsigned FieldNo = cast<ConstantUInt>(Idx[CurIDX])->getValue();
221
222       // Get structure layout information...
223       const StructLayout *Layout = getStructLayout(STy);
224
225       // Add in the offset, as calculated by the structure layout info...
226       assert(FieldNo < Layout->MemberOffsets.size() &&"FieldNo out of range!");
227       Result += Layout->MemberOffsets[FieldNo];
228
229       // Update Ty to refer to current element
230       Ty = STy->getElementTypes()[FieldNo];
231     }
232   }
233
234   return Result;
235 }
236