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/Module.h"
15 #include "llvm/DerivedTypes.h"
16 #include "llvm/Constants.h"
18 // Handle the Pass registration stuff neccesary to use TargetData's.
20 // Register the default SparcV9 implementation...
21 RegisterPass<TargetData> X("targetdata", "Target Data Layout");
25 static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
26 uint64_t &Size, unsigned char &Alignment);
28 //===----------------------------------------------------------------------===//
29 // Support for StructLayout Annotation
30 //===----------------------------------------------------------------------===//
32 StructLayout::StructLayout(const StructType *ST, const TargetData &TD)
33 : Annotation(TD.getStructLayoutAID()) {
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) {
45 getTypeInfo(Ty, &TD, TySize, A);
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...
52 // Keep track of maximum alignment constraint
53 StructAlignment = std::max(TyAlign, StructAlignment);
55 MemberOffsets.push_back(StructSize);
56 StructSize += TySize; // Consume space for this data item
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;
64 if (StructSize == 0) {
65 StructSize = 1; // Empty struct is 1 byte
70 Annotation *TargetData::TypeAnFactory(AnnotationID AID, const Annotable *T,
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);
80 //===----------------------------------------------------------------------===//
81 // TargetData Class Implementation
82 //===----------------------------------------------------------------------===//
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,
91 : AID(AnnotationManager::getID("TargetData::" + TargetName)) {
92 AnnotationManager::registerAnnotationFactory(AID, TypeAnFactory, this);
94 // If this assert triggers, a pass "required" TargetData information, but the
95 // top level tool did not provide once for it. We do not want to default
96 // construct, or else we might end up using a bad endianness or pointer size!
98 assert(!TargetName.empty() &&
99 "ERROR: Tool did not specify a target data to use!");
101 LittleEndian = isLittleEndian;
102 SubWordDataSize = SubWordSize;
103 IntegerRegSize = IntRegSize;
104 PointerSize = PtrSize;
105 PointerAlignment = PtrAl;
106 DoubleAlignment = DoubleAl;
107 assert(DoubleAlignment == PtrAl &&
108 "Double alignment and pointer alignment agree for now!");
109 FloatAlignment = FloatAl;
110 LongAlignment = LongAl;
111 IntAlignment = IntAl;
112 ShortAlignment = ShortAl;
113 ByteAlignment = ByteAl;
116 TargetData::TargetData(const std::string &ToolName, const Module *M)
117 : AID(AnnotationManager::getID("TargetData::" + ToolName)) {
118 AnnotationManager::registerAnnotationFactory(AID, TypeAnFactory, this);
120 LittleEndian = M->isLittleEndian();
123 PointerSize = M->has32BitPointers() ? 4 : 8;
124 PointerAlignment = PointerSize;
125 DoubleAlignment = PointerSize;
133 TargetData::~TargetData() {
134 AnnotationManager::registerAnnotationFactory(AID, 0); // Deregister factory
137 static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
138 uint64_t &Size, unsigned char &Alignment) {
139 assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
140 switch (Ty->getPrimitiveID()) {
143 case Type::UByteTyID:
144 case Type::SByteTyID: Size = 1; Alignment = TD->getByteAlignment(); return;
145 case Type::UShortTyID:
146 case Type::ShortTyID: Size = 2; Alignment = TD->getShortAlignment(); return;
148 case Type::IntTyID: Size = 4; Alignment = TD->getIntAlignment(); return;
149 case Type::ULongTyID:
150 case Type::LongTyID: Size = 8; Alignment = TD->getLongAlignment(); return;
151 case Type::FloatTyID: Size = 4; Alignment = TD->getFloatAlignment(); return;
152 case Type::DoubleTyID: Size = 8; Alignment = TD->getDoubleAlignment(); return;
153 case Type::LabelTyID:
154 case Type::PointerTyID:
155 Size = TD->getPointerSize(); Alignment = TD->getPointerAlignment();
157 case Type::ArrayTyID: {
158 const ArrayType *ATy = (const ArrayType *)Ty;
159 getTypeInfo(ATy->getElementType(), TD, Size, Alignment);
160 Size *= ATy->getNumElements();
163 case Type::StructTyID: {
164 // Get the layout annotation... which is lazily created on demand.
165 const StructLayout *Layout = TD->getStructLayout((const StructType*)Ty);
166 Size = Layout->StructSize; Alignment = Layout->StructAlignment;
172 assert(0 && "Bad type for getTypeInfo!!!");
177 uint64_t TargetData::getTypeSize(const Type *Ty) const {
180 getTypeInfo(Ty, this, Size, Align);
184 unsigned char TargetData::getTypeAlignment(const Type *Ty) const {
187 getTypeInfo(Ty, this, Size, Align);
191 uint64_t TargetData::getIndexedOffset(const Type *ptrTy,
192 const std::vector<Value*> &Idx) const {
193 const Type *Ty = ptrTy;
194 assert(isa<PointerType>(Ty) && "Illegal argument for getIndexedOffset()");
197 for (unsigned CurIDX = 0; CurIDX != Idx.size(); ++CurIDX) {
198 if (Idx[CurIDX]->getType() == Type::LongTy) {
199 // Update Ty to refer to current element
200 Ty = cast<SequentialType>(Ty)->getElementType();
202 // Get the array index and the size of each array element.
203 // Both must be known constants, or the index shd be 0; else this fails.
204 int64_t arrayIdx = cast<ConstantSInt>(Idx[CurIDX])->getValue();
205 Result += arrayIdx == 0? 0
206 : (uint64_t) (arrayIdx * (int64_t) getTypeSize(Ty));
208 } else if (const StructType *STy = dyn_cast<const StructType>(Ty)) {
209 assert(Idx[CurIDX]->getType() == Type::UByteTy && "Illegal struct idx");
210 unsigned FieldNo = cast<ConstantUInt>(Idx[CurIDX])->getValue();
212 // Get structure layout information...
213 const StructLayout *Layout = getStructLayout(STy);
215 // Add in the offset, as calculated by the structure layout info...
216 assert(FieldNo < Layout->MemberOffsets.size() &&"FieldNo out of range!");
217 Result += Layout->MemberOffsets[FieldNo];
219 // Update Ty to refer to current element
220 Ty = STy->getElementTypes()[FieldNo];
222 assert(0 && "Indexing type that is not struct or array?");
223 return 0; // Load directly through ptr