1 //===-- TargetData.cpp - Data size & alignment routines --------------------==//
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.
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.
11 //===----------------------------------------------------------------------===//
13 #include "llvm/Target/TargetData.h"
14 #include "llvm/DerivedTypes.h"
15 #include "llvm/Constants.h"
17 // Handle the Pass registration stuff neccesary to use TargetData's.
19 // Register the default SparcV9 implementation...
20 RegisterPass<TargetData> X("targetdata", "Target Data Layout");
24 static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
25 uint64_t &Size, unsigned char &Alignment);
27 //===----------------------------------------------------------------------===//
28 // Support for StructLayout Annotation
29 //===----------------------------------------------------------------------===//
31 StructLayout::StructLayout(const StructType *ST, const TargetData &TD)
32 : Annotation(TD.getStructLayoutAID()) {
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) {
44 getTypeInfo(Ty, &TD, TySize, A);
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...
51 // Keep track of maximum alignment constraint
52 StructAlignment = std::max(TyAlign, StructAlignment);
54 MemberOffsets.push_back(StructSize);
55 StructSize += TySize; // Consume space for this data item
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;
63 if (StructSize == 0) {
64 StructSize = 1; // Empty struct is 1 byte
69 Annotation *TargetData::TypeAnFactory(AnnotationID AID, const Annotable *T,
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);
79 //===----------------------------------------------------------------------===//
80 // TargetData Class Implementation
81 //===----------------------------------------------------------------------===//
83 TargetData::TargetData(const std::string &TargetName,
84 bool isLittleEndian, unsigned char SubWordSize,
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,
90 : AID(AnnotationManager::getID("TargetData::" + TargetName)) {
91 AnnotationManager::registerAnnotationFactory(AID, TypeAnFactory, this);
93 LittleEndian = isLittleEndian;
94 SubWordDataSize = SubWordSize;
95 IntegerRegSize = IntRegSize;
96 PointerSize = PtrSize;
97 PointerAlignment = PtrAl;
98 DoubleAlignment = DoubleAl;
99 FloatAlignment = FloatAl;
100 LongAlignment = LongAl;
101 IntAlignment = IntAl;
102 ShortAlignment = ShortAl;
103 ByteAlignment = ByteAl;
106 TargetData::~TargetData() {
107 AnnotationManager::registerAnnotationFactory(AID, 0); // Deregister factory
110 static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
111 uint64_t &Size, unsigned char &Alignment) {
112 assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
113 switch (Ty->getPrimitiveID()) {
116 case Type::UByteTyID:
117 case Type::SByteTyID: Size = 1; Alignment = TD->getByteAlignment(); return;
118 case Type::UShortTyID:
119 case Type::ShortTyID: Size = 2; Alignment = TD->getShortAlignment(); return;
121 case Type::IntTyID: Size = 4; Alignment = TD->getIntAlignment(); return;
122 case Type::ULongTyID:
123 case Type::LongTyID: Size = 8; Alignment = TD->getLongAlignment(); return;
124 case Type::FloatTyID: Size = 4; Alignment = TD->getFloatAlignment(); return;
125 case Type::DoubleTyID: Size = 8; Alignment = TD->getDoubleAlignment(); return;
126 case Type::LabelTyID:
127 case Type::PointerTyID:
128 Size = TD->getPointerSize(); Alignment = TD->getPointerAlignment();
130 case Type::ArrayTyID: {
131 const ArrayType *ATy = (const ArrayType *)Ty;
132 getTypeInfo(ATy->getElementType(), TD, Size, Alignment);
133 Size *= ATy->getNumElements();
136 case Type::StructTyID: {
137 // Get the layout annotation... which is lazily created on demand.
138 const StructLayout *Layout = TD->getStructLayout((const StructType*)Ty);
139 Size = Layout->StructSize; Alignment = Layout->StructAlignment;
145 assert(0 && "Bad type for getTypeInfo!!!");
150 uint64_t TargetData::getTypeSize(const Type *Ty) const {
153 getTypeInfo(Ty, this, Size, Align);
157 unsigned char TargetData::getTypeAlignment(const Type *Ty) const {
160 getTypeInfo(Ty, this, Size, Align);
164 uint64_t TargetData::getIndexedOffset(const Type *ptrTy,
165 const std::vector<Value*> &Idx) const {
166 const Type *Ty = ptrTy;
167 assert(isa<PointerType>(Ty) && "Illegal argument for getIndexedOffset()");
170 for (unsigned CurIDX = 0; CurIDX != Idx.size(); ++CurIDX) {
171 if (Idx[CurIDX]->getType() == Type::LongTy) {
172 // Update Ty to refer to current element
173 Ty = cast<SequentialType>(Ty)->getElementType();
175 // Get the array index and the size of each array element.
176 // Both must be known constants, or the index shd be 0; else this fails.
177 int64_t arrayIdx = cast<ConstantSInt>(Idx[CurIDX])->getValue();
178 Result += arrayIdx == 0? 0
179 : (uint64_t) (arrayIdx * (int64_t) getTypeSize(Ty));
181 } else if (const StructType *STy = dyn_cast<const StructType>(Ty)) {
182 assert(Idx[CurIDX]->getType() == Type::UByteTy && "Illegal struct idx");
183 unsigned FieldNo = cast<ConstantUInt>(Idx[CurIDX])->getValue();
185 // Get structure layout information...
186 const StructLayout *Layout = getStructLayout(STy);
188 // Add in the offset, as calculated by the structure layout info...
189 assert(FieldNo < Layout->MemberOffsets.size() &&"FieldNo out of range!");
190 Result += Layout->MemberOffsets[FieldNo];
192 // Update Ty to refer to current element
193 Ty = STy->getElementTypes()[FieldNo];
195 } else if (isa<const ArrayType>(Ty)) {
196 assert(0 && "Loading from arrays not implemented yet!");
198 assert(0 && "Indexing type that is not struct or array?");
199 return 0; // Load directly through ptr