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 FloatAlignment = FloatAl;
108 LongAlignment = LongAl;
109 IntAlignment = IntAl;
110 ShortAlignment = ShortAl;
111 ByteAlignment = ByteAl;
114 TargetData::TargetData(const std::string &ToolName, const Module *M)
115 : AID(AnnotationManager::getID("TargetData::" + ToolName)) {
116 AnnotationManager::registerAnnotationFactory(AID, TypeAnFactory, this);
118 LittleEndian = M->isLittleEndian();
121 PointerSize = M->has32BitPointers() ? 32 : 64;
122 PointerAlignment = PointerSize;
131 TargetData::~TargetData() {
132 AnnotationManager::registerAnnotationFactory(AID, 0); // Deregister factory
135 static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
136 uint64_t &Size, unsigned char &Alignment) {
137 assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
138 switch (Ty->getPrimitiveID()) {
141 case Type::UByteTyID:
142 case Type::SByteTyID: Size = 1; Alignment = TD->getByteAlignment(); return;
143 case Type::UShortTyID:
144 case Type::ShortTyID: Size = 2; Alignment = TD->getShortAlignment(); return;
146 case Type::IntTyID: Size = 4; Alignment = TD->getIntAlignment(); return;
147 case Type::ULongTyID:
148 case Type::LongTyID: Size = 8; Alignment = TD->getLongAlignment(); return;
149 case Type::FloatTyID: Size = 4; Alignment = TD->getFloatAlignment(); return;
150 case Type::DoubleTyID: Size = 8; Alignment = TD->getDoubleAlignment(); return;
151 case Type::LabelTyID:
152 case Type::PointerTyID:
153 Size = TD->getPointerSize(); Alignment = TD->getPointerAlignment();
155 case Type::ArrayTyID: {
156 const ArrayType *ATy = (const ArrayType *)Ty;
157 getTypeInfo(ATy->getElementType(), TD, Size, Alignment);
158 Size *= ATy->getNumElements();
161 case Type::StructTyID: {
162 // Get the layout annotation... which is lazily created on demand.
163 const StructLayout *Layout = TD->getStructLayout((const StructType*)Ty);
164 Size = Layout->StructSize; Alignment = Layout->StructAlignment;
170 assert(0 && "Bad type for getTypeInfo!!!");
175 uint64_t TargetData::getTypeSize(const Type *Ty) const {
178 getTypeInfo(Ty, this, Size, Align);
182 unsigned char TargetData::getTypeAlignment(const Type *Ty) const {
185 getTypeInfo(Ty, this, Size, Align);
189 uint64_t TargetData::getIndexedOffset(const Type *ptrTy,
190 const std::vector<Value*> &Idx) const {
191 const Type *Ty = ptrTy;
192 assert(isa<PointerType>(Ty) && "Illegal argument for getIndexedOffset()");
195 for (unsigned CurIDX = 0; CurIDX != Idx.size(); ++CurIDX) {
196 if (Idx[CurIDX]->getType() == Type::LongTy) {
197 // Update Ty to refer to current element
198 Ty = cast<SequentialType>(Ty)->getElementType();
200 // Get the array index and the size of each array element.
201 // Both must be known constants, or the index shd be 0; else this fails.
202 int64_t arrayIdx = cast<ConstantSInt>(Idx[CurIDX])->getValue();
203 Result += arrayIdx == 0? 0
204 : (uint64_t) (arrayIdx * (int64_t) getTypeSize(Ty));
206 } else if (const StructType *STy = dyn_cast<const StructType>(Ty)) {
207 assert(Idx[CurIDX]->getType() == Type::UByteTy && "Illegal struct idx");
208 unsigned FieldNo = cast<ConstantUInt>(Idx[CurIDX])->getValue();
210 // Get structure layout information...
211 const StructLayout *Layout = getStructLayout(STy);
213 // Add in the offset, as calculated by the structure layout info...
214 assert(FieldNo < Layout->MemberOffsets.size() &&"FieldNo out of range!");
215 Result += Layout->MemberOffsets[FieldNo];
217 // Update Ty to refer to current element
218 Ty = STy->getElementTypes()[FieldNo];
220 assert(0 && "Indexing type that is not struct or array?");
221 return 0; // Load directly through ptr