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