blob: a0a3b82d24fa9cf48fd4c0c3645b4f154d9557e5 [file] [log] [blame]
Chris Lattnere7fb3602001-08-27 16:00:15 +00001//===-- 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
Vikram S. Adve0799fc42001-09-18 12:58:33 +000013#include "llvm/Target/TargetData.h"
Chris Lattner53a0c382003-04-24 19:09:05 +000014#include "llvm/Module.h"
Chris Lattnere7fb3602001-08-27 16:00:15 +000015#include "llvm/DerivedTypes.h"
Chris Lattner31bcdb82002-04-28 19:55:58 +000016#include "llvm/Constants.h"
Chris Lattnere7fb3602001-08-27 16:00:15 +000017
Chris Lattneraa31ad02002-09-25 23:46:55 +000018// Handle the Pass registration stuff neccesary to use TargetData's.
19namespace {
20 // Register the default SparcV9 implementation...
21 RegisterPass<TargetData> X("targetdata", "Target Data Layout");
22}
23
24
Chris Lattnere7fb3602001-08-27 16:00:15 +000025static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
Vikram S. Advef66723f2002-05-19 15:28:02 +000026 uint64_t &Size, unsigned char &Alignment);
Chris Lattnere7fb3602001-08-27 16:00:15 +000027
28//===----------------------------------------------------------------------===//
29// Support for StructLayout Annotation
30//===----------------------------------------------------------------------===//
31
32StructLayout::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;
Vikram S. Advef66723f2002-05-19 15:28:02 +000043 unsigned TyAlign;
44 uint64_t TySize;
45 getTypeInfo(Ty, &TD, TySize, A);
46 TyAlign = A;
Chris Lattnere7fb3602001-08-27 16:00:15 +000047
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
Chris Lattner697954c2002-01-20 22:54:45 +000053 StructAlignment = std::max(TyAlign, StructAlignment);
Chris Lattnere7fb3602001-08-27 16:00:15 +000054
55 MemberOffsets.push_back(StructSize);
Vikram S. Advef66723f2002-05-19 15:28:02 +000056 StructSize += TySize; // Consume space for this data item
Chris Lattnere7fb3602001-08-27 16:00:15 +000057 }
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
Chris Lattner97b73112001-09-07 16:40:04 +000070Annotation *TargetData::TypeAnFactory(AnnotationID AID, const Annotable *T,
71 void *D) {
Chris Lattnere7fb3602001-08-27 16:00:15 +000072 const TargetData &TD = *(const TargetData*)D;
73 assert(AID == TD.AID && "Target data annotation ID mismatch!");
Vikram S. Advef66723f2002-05-19 15:28:02 +000074 const Type *Ty = cast<const Type>((const Value *)T);
Chris Lattner9b625032002-05-06 16:15:30 +000075 assert(isa<StructType>(Ty) &&
Chris Lattnere7fb3602001-08-27 16:00:15 +000076 "Can only create StructLayout annotation on structs!");
Vikram S. Advef66723f2002-05-19 15:28:02 +000077 return new StructLayout((const StructType *)Ty, TD);
Chris Lattnere7fb3602001-08-27 16:00:15 +000078}
79
80//===----------------------------------------------------------------------===//
81// TargetData Class Implementation
82//===----------------------------------------------------------------------===//
83
Vikram S. Advef66723f2002-05-19 15:28:02 +000084TargetData::TargetData(const std::string &TargetName,
Chris Lattnerc56406c2002-10-29 21:48:17 +000085 bool isLittleEndian, unsigned char SubWordSize,
Chris Lattner85131c82002-10-14 22:41:13 +000086 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)
Chris Lattnere7fb3602001-08-27 16:00:15 +000091 : AID(AnnotationManager::getID("TargetData::" + TargetName)) {
92 AnnotationManager::registerAnnotationFactory(AID, TypeAnFactory, this);
93
Chris Lattner46326d92003-04-25 02:50:45 +000094 // 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!
97 //
98 assert(!TargetName.empty() &&
99 "ERROR: Tool did not specify a target data to use!");
100
Chris Lattner85131c82002-10-14 22:41:13 +0000101 LittleEndian = isLittleEndian;
Chris Lattnerc56406c2002-10-29 21:48:17 +0000102 SubWordDataSize = SubWordSize;
Vikram S. Advef66723f2002-05-19 15:28:02 +0000103 IntegerRegSize = IntRegSize;
Chris Lattnere7fb3602001-08-27 16:00:15 +0000104 PointerSize = PtrSize;
105 PointerAlignment = PtrAl;
106 DoubleAlignment = DoubleAl;
107 FloatAlignment = FloatAl;
108 LongAlignment = LongAl;
109 IntAlignment = IntAl;
110 ShortAlignment = ShortAl;
111 ByteAlignment = ByteAl;
112}
113
Chris Lattner53a0c382003-04-24 19:09:05 +0000114TargetData::TargetData(const std::string &ToolName, const Module *M)
115 : AID(AnnotationManager::getID("TargetData::" + ToolName)) {
116 AnnotationManager::registerAnnotationFactory(AID, TypeAnFactory, this);
117
118 LittleEndian = M->isLittleEndian();
119 SubWordDataSize = 1;
120 IntegerRegSize = 8;
121 PointerSize = M->has32BitPointers() ? 32 : 64;
122 PointerAlignment = PointerSize;
123 DoubleAlignment = 8;
124 FloatAlignment = 4;
125 LongAlignment = 8;
126 IntAlignment = 4;
127 ShortAlignment = 2;
128 ByteAlignment = 1;
129}
130
Chris Lattnere7fb3602001-08-27 16:00:15 +0000131TargetData::~TargetData() {
132 AnnotationManager::registerAnnotationFactory(AID, 0); // Deregister factory
133}
134
135static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
Vikram S. Advef66723f2002-05-19 15:28:02 +0000136 uint64_t &Size, unsigned char &Alignment) {
Chris Lattnerf59ce922001-12-13 00:46:11 +0000137 assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
Chris Lattnere7fb3602001-08-27 16:00:15 +0000138 switch (Ty->getPrimitiveID()) {
139 case Type::VoidTyID:
140 case Type::BoolTyID:
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;
145 case Type::UIntTyID:
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();
154 return;
155 case Type::ArrayTyID: {
156 const ArrayType *ATy = (const ArrayType *)Ty;
Chris Lattnere7fb3602001-08-27 16:00:15 +0000157 getTypeInfo(ATy->getElementType(), TD, Size, Alignment);
158 Size *= ATy->getNumElements();
159 return;
160 }
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;
165 return;
166 }
167
168 case Type::TypeTyID:
169 default:
170 assert(0 && "Bad type for getTypeInfo!!!");
171 return;
172 }
173}
174
Vikram S. Advef66723f2002-05-19 15:28:02 +0000175uint64_t TargetData::getTypeSize(const Type *Ty) const {
176 uint64_t Size;
177 unsigned char Align;
Chris Lattnere7fb3602001-08-27 16:00:15 +0000178 getTypeInfo(Ty, this, Size, Align);
179 return Size;
180}
181
182unsigned char TargetData::getTypeAlignment(const Type *Ty) const {
Vikram S. Advef66723f2002-05-19 15:28:02 +0000183 uint64_t Size;
184 unsigned char Align;
Chris Lattnere7fb3602001-08-27 16:00:15 +0000185 getTypeInfo(Ty, this, Size, Align);
186 return Align;
187}
188
Vikram S. Advef66723f2002-05-19 15:28:02 +0000189uint64_t TargetData::getIndexedOffset(const Type *ptrTy,
Chris Lattner697954c2002-01-20 22:54:45 +0000190 const std::vector<Value*> &Idx) const {
Vikram S. Adveed0030e2002-08-04 20:52:39 +0000191 const Type *Ty = ptrTy;
192 assert(isa<PointerType>(Ty) && "Illegal argument for getIndexedOffset()");
Vikram S. Advef66723f2002-05-19 15:28:02 +0000193 uint64_t Result = 0;
Chris Lattnere7fb3602001-08-27 16:00:15 +0000194
Chris Lattner3cac88a2002-09-11 01:21:33 +0000195 for (unsigned CurIDX = 0; CurIDX != Idx.size(); ++CurIDX) {
196 if (Idx[CurIDX]->getType() == Type::LongTy) {
Vikram S. Adveca710e92002-08-13 18:17:56 +0000197 // Update Ty to refer to current element
198 Ty = cast<SequentialType>(Ty)->getElementType();
199
Vikram S. Advef66723f2002-05-19 15:28:02 +0000200 // Get the array index and the size of each array element.
Vikram S. Adve8e22ead2002-10-13 21:47:44 +0000201 // Both must be known constants, or the index shd be 0; else this fails.
Chris Lattner3cac88a2002-09-11 01:21:33 +0000202 int64_t arrayIdx = cast<ConstantSInt>(Idx[CurIDX])->getValue();
Vikram S. Adve8e22ead2002-10-13 21:47:44 +0000203 Result += arrayIdx == 0? 0
204 : (uint64_t) (arrayIdx * (int64_t) getTypeSize(Ty));
Vikram S. Adveed0030e2002-08-04 20:52:39 +0000205
Vikram S. Advef66723f2002-05-19 15:28:02 +0000206 } else if (const StructType *STy = dyn_cast<const StructType>(Ty)) {
Chris Lattnere7fb3602001-08-27 16:00:15 +0000207 assert(Idx[CurIDX]->getType() == Type::UByteTy && "Illegal struct idx");
Chris Lattnere9bb2df2001-12-03 22:26:30 +0000208 unsigned FieldNo = cast<ConstantUInt>(Idx[CurIDX])->getValue();
Chris Lattnere7fb3602001-08-27 16:00:15 +0000209
210 // Get structure layout information...
211 const StructLayout *Layout = getStructLayout(STy);
212
213 // Add in the offset, as calculated by the structure layout info...
Vikram S. Advef66723f2002-05-19 15:28:02 +0000214 assert(FieldNo < Layout->MemberOffsets.size() &&"FieldNo out of range!");
Chris Lattnere7fb3602001-08-27 16:00:15 +0000215 Result += Layout->MemberOffsets[FieldNo];
Vikram S. Adveed0030e2002-08-04 20:52:39 +0000216
Chris Lattnere7fb3602001-08-27 16:00:15 +0000217 // Update Ty to refer to current element
218 Ty = STy->getElementTypes()[FieldNo];
Chris Lattnere7fb3602001-08-27 16:00:15 +0000219 } else {
Vikram S. Advef66723f2002-05-19 15:28:02 +0000220 assert(0 && "Indexing type that is not struct or array?");
Chris Lattnere7fb3602001-08-27 16:00:15 +0000221 return 0; // Load directly through ptr
222 }
223 }
224
225 return Result;
226}