Remove dead variable
[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/DerivedTypes.h"
15 #include "llvm/ConstantVals.h"
16
17 static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
18                                unsigned &Size, unsigned char &Alignment);
19
20 //===----------------------------------------------------------------------===//
21 // Support for StructLayout Annotation
22 //===----------------------------------------------------------------------===//
23
24 StructLayout::StructLayout(const StructType *ST, const TargetData &TD) 
25   : Annotation(TD.getStructLayoutAID()) {
26   StructAlignment = 0;
27   StructSize = 0;
28
29   // Loop over each of the elements, placing them in memory...
30   for (StructType::ElementTypes::const_iterator
31          TI = ST->getElementTypes().begin(), 
32          TE = ST->getElementTypes().end(); TI != TE; ++TI) {
33     const Type *Ty = *TI;
34     unsigned char A;
35     unsigned TySize, TyAlign;
36     getTypeInfo(Ty, &TD, TySize, A);  TyAlign = A;
37
38     // Add padding if neccesary to make the data element aligned properly...
39     if (StructSize % TyAlign != 0)
40       StructSize = (StructSize/TyAlign + 1) * TyAlign;   // Add padding...
41
42     // Keep track of maximum alignment constraint
43     StructAlignment = std::max(TyAlign, StructAlignment);
44
45     MemberOffsets.push_back(StructSize);
46     StructSize += TySize;                 // Consume space for this data item...
47   }
48
49   // Add padding to the end of the struct so that it could be put in an array
50   // and all array elements would be aligned correctly.
51   if (StructSize % StructAlignment != 0)
52     StructSize = (StructSize/StructAlignment + 1) * StructAlignment;
53
54   if (StructSize == 0) {
55     StructSize = 1;           // Empty struct is 1 byte
56     StructAlignment = 1;
57   }
58 }
59
60 Annotation *TargetData::TypeAnFactory(AnnotationID AID, const Annotable *T,
61                                       void *D) {
62   const TargetData &TD = *(const TargetData*)D;
63   assert(AID == TD.AID && "Target data annotation ID mismatch!");
64   const Type *Ty = cast<const Type>((const Value *)T);
65   assert(Ty->isStructType() && 
66          "Can only create StructLayout annotation on structs!");
67   return new StructLayout((const StructType *)Ty, TD);
68 }
69
70 //===----------------------------------------------------------------------===//
71 //                       TargetData Class Implementation
72 //===----------------------------------------------------------------------===//
73
74 TargetData::TargetData(const std::string &TargetName, unsigned char PtrSize = 8,
75              unsigned char PtrAl = 8, unsigned char DoubleAl = 8,
76              unsigned char FloatAl = 4, unsigned char LongAl = 8, 
77              unsigned char IntAl = 4, unsigned char ShortAl = 2,
78              unsigned char ByteAl = 1)
79   : AID(AnnotationManager::getID("TargetData::" + TargetName)) {
80   AnnotationManager::registerAnnotationFactory(AID, TypeAnFactory, this);
81
82   PointerSize      = PtrSize;
83   PointerAlignment = PtrAl;
84   DoubleAlignment  = DoubleAl;
85   FloatAlignment   = FloatAl;
86   LongAlignment    = LongAl;
87   IntAlignment     = IntAl;
88   ShortAlignment   = ShortAl;
89   ByteAlignment    = ByteAl;
90 }
91
92 TargetData::~TargetData() {
93   AnnotationManager::registerAnnotationFactory(AID, 0);   // Deregister factory
94 }
95
96 static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
97                                unsigned &Size, unsigned char &Alignment) {
98   assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
99   switch (Ty->getPrimitiveID()) {
100   case Type::VoidTyID:
101   case Type::BoolTyID:
102   case Type::UByteTyID:
103   case Type::SByteTyID:  Size = 1; Alignment = TD->getByteAlignment(); return;
104   case Type::UShortTyID:
105   case Type::ShortTyID:  Size = 2; Alignment = TD->getShortAlignment(); return;
106   case Type::UIntTyID:
107   case Type::IntTyID:    Size = 4; Alignment = TD->getIntAlignment(); return;
108   case Type::ULongTyID:
109   case Type::LongTyID:   Size = 8; Alignment = TD->getLongAlignment(); return;
110   case Type::FloatTyID:  Size = 4; Alignment = TD->getFloatAlignment(); return;
111   case Type::DoubleTyID: Size = 8; Alignment = TD->getDoubleAlignment(); return;
112   case Type::LabelTyID:
113   case Type::PointerTyID:
114     Size = TD->getPointerSize(); Alignment = TD->getPointerAlignment();
115     return;
116   case Type::ArrayTyID: {
117     const ArrayType *ATy = (const ArrayType *)Ty;
118     getTypeInfo(ATy->getElementType(), TD, Size, Alignment);
119     Size *= ATy->getNumElements();
120     return;
121   }
122   case Type::StructTyID: {
123     // Get the layout annotation... which is lazily created on demand.
124     const StructLayout *Layout = TD->getStructLayout((const StructType*)Ty);
125     Size = Layout->StructSize; Alignment = Layout->StructAlignment;
126     return;
127   }
128     
129   case Type::TypeTyID:
130   default:
131     assert(0 && "Bad type for getTypeInfo!!!");
132     return;
133   }
134 }
135
136 unsigned TargetData::getTypeSize(const Type *Ty) const {
137   unsigned Size; unsigned char Align;
138   getTypeInfo(Ty, this, Size, Align);
139   return Size;
140 }
141
142 unsigned char TargetData::getTypeAlignment(const Type *Ty) const {
143   unsigned Size; unsigned char Align;
144   getTypeInfo(Ty, this, Size, Align);
145   return Align;
146 }
147
148 unsigned TargetData::getIndexedOffset(const Type *ptrTy,
149                                       const std::vector<Value*> &Idx) const {
150   const PointerType *PtrTy = cast<const PointerType>(ptrTy);
151   unsigned Result = 0;
152
153   // Get the type pointed to...
154   const Type *Ty = PtrTy->getElementType();
155
156   for (unsigned CurIDX = 0; CurIDX < Idx.size(); ++CurIDX) {
157     if (const StructType *STy = dyn_cast<const StructType>(Ty)) {
158       assert(Idx[CurIDX]->getType() == Type::UByteTy && "Illegal struct idx");
159       unsigned FieldNo = cast<ConstantUInt>(Idx[CurIDX])->getValue();
160
161       // Get structure layout information...
162       const StructLayout *Layout = getStructLayout(STy);
163
164       // Add in the offset, as calculated by the structure layout info...
165       assert(FieldNo < Layout->MemberOffsets.size() && "FieldNo out of range!");
166       Result += Layout->MemberOffsets[FieldNo];
167       
168       // Update Ty to refer to current element
169       Ty = STy->getElementTypes()[FieldNo];
170
171     } else if (isa<const ArrayType>(Ty)) {
172       assert(0 && "Loading from arrays not implemented yet!");
173     } else {
174       assert(0 && "Indexing type that is not struct or array?");
175       return 0;                         // Load directly through ptr
176     }
177   }
178
179   return Result;
180 }