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