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