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