blob: 701b36640ec764423de608c80e6eaace5e5dd7f5 [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 Lattner85131c82002-10-14 22:41:13 +000094 LittleEndian = isLittleEndian;
Chris Lattnerc56406c2002-10-29 21:48:17 +000095 SubWordDataSize = SubWordSize;
Vikram S. Advef66723f2002-05-19 15:28:02 +000096 IntegerRegSize = IntRegSize;
Chris Lattnere7fb3602001-08-27 16:00:15 +000097 PointerSize = PtrSize;
98 PointerAlignment = PtrAl;
99 DoubleAlignment = DoubleAl;
100 FloatAlignment = FloatAl;
101 LongAlignment = LongAl;
102 IntAlignment = IntAl;
103 ShortAlignment = ShortAl;
104 ByteAlignment = ByteAl;
105}
106
Chris Lattner53a0c382003-04-24 19:09:05 +0000107TargetData::TargetData(const std::string &ToolName, const Module *M)
108 : AID(AnnotationManager::getID("TargetData::" + ToolName)) {
109 AnnotationManager::registerAnnotationFactory(AID, TypeAnFactory, this);
110
111 LittleEndian = M->isLittleEndian();
112 SubWordDataSize = 1;
113 IntegerRegSize = 8;
114 PointerSize = M->has32BitPointers() ? 32 : 64;
115 PointerAlignment = PointerSize;
116 DoubleAlignment = 8;
117 FloatAlignment = 4;
118 LongAlignment = 8;
119 IntAlignment = 4;
120 ShortAlignment = 2;
121 ByteAlignment = 1;
122}
123
Chris Lattnere7fb3602001-08-27 16:00:15 +0000124TargetData::~TargetData() {
125 AnnotationManager::registerAnnotationFactory(AID, 0); // Deregister factory
126}
127
128static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
Vikram S. Advef66723f2002-05-19 15:28:02 +0000129 uint64_t &Size, unsigned char &Alignment) {
Chris Lattnerf59ce922001-12-13 00:46:11 +0000130 assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
Chris Lattnere7fb3602001-08-27 16:00:15 +0000131 switch (Ty->getPrimitiveID()) {
132 case Type::VoidTyID:
133 case Type::BoolTyID:
134 case Type::UByteTyID:
135 case Type::SByteTyID: Size = 1; Alignment = TD->getByteAlignment(); return;
136 case Type::UShortTyID:
137 case Type::ShortTyID: Size = 2; Alignment = TD->getShortAlignment(); return;
138 case Type::UIntTyID:
139 case Type::IntTyID: Size = 4; Alignment = TD->getIntAlignment(); return;
140 case Type::ULongTyID:
141 case Type::LongTyID: Size = 8; Alignment = TD->getLongAlignment(); return;
142 case Type::FloatTyID: Size = 4; Alignment = TD->getFloatAlignment(); return;
143 case Type::DoubleTyID: Size = 8; Alignment = TD->getDoubleAlignment(); return;
144 case Type::LabelTyID:
145 case Type::PointerTyID:
146 Size = TD->getPointerSize(); Alignment = TD->getPointerAlignment();
147 return;
148 case Type::ArrayTyID: {
149 const ArrayType *ATy = (const ArrayType *)Ty;
Chris Lattnere7fb3602001-08-27 16:00:15 +0000150 getTypeInfo(ATy->getElementType(), TD, Size, Alignment);
151 Size *= ATy->getNumElements();
152 return;
153 }
154 case Type::StructTyID: {
155 // Get the layout annotation... which is lazily created on demand.
156 const StructLayout *Layout = TD->getStructLayout((const StructType*)Ty);
157 Size = Layout->StructSize; Alignment = Layout->StructAlignment;
158 return;
159 }
160
161 case Type::TypeTyID:
162 default:
163 assert(0 && "Bad type for getTypeInfo!!!");
164 return;
165 }
166}
167
Vikram S. Advef66723f2002-05-19 15:28:02 +0000168uint64_t TargetData::getTypeSize(const Type *Ty) const {
169 uint64_t Size;
170 unsigned char Align;
Chris Lattnere7fb3602001-08-27 16:00:15 +0000171 getTypeInfo(Ty, this, Size, Align);
172 return Size;
173}
174
175unsigned char TargetData::getTypeAlignment(const Type *Ty) const {
Vikram S. Advef66723f2002-05-19 15:28:02 +0000176 uint64_t Size;
177 unsigned char Align;
Chris Lattnere7fb3602001-08-27 16:00:15 +0000178 getTypeInfo(Ty, this, Size, Align);
179 return Align;
180}
181
Vikram S. Advef66723f2002-05-19 15:28:02 +0000182uint64_t TargetData::getIndexedOffset(const Type *ptrTy,
Chris Lattner697954c2002-01-20 22:54:45 +0000183 const std::vector<Value*> &Idx) const {
Vikram S. Adveed0030e2002-08-04 20:52:39 +0000184 const Type *Ty = ptrTy;
185 assert(isa<PointerType>(Ty) && "Illegal argument for getIndexedOffset()");
Vikram S. Advef66723f2002-05-19 15:28:02 +0000186 uint64_t Result = 0;
Chris Lattnere7fb3602001-08-27 16:00:15 +0000187
Chris Lattner3cac88a2002-09-11 01:21:33 +0000188 for (unsigned CurIDX = 0; CurIDX != Idx.size(); ++CurIDX) {
189 if (Idx[CurIDX]->getType() == Type::LongTy) {
Vikram S. Adveca710e92002-08-13 18:17:56 +0000190 // Update Ty to refer to current element
191 Ty = cast<SequentialType>(Ty)->getElementType();
192
Vikram S. Advef66723f2002-05-19 15:28:02 +0000193 // Get the array index and the size of each array element.
Vikram S. Adve8e22ead2002-10-13 21:47:44 +0000194 // Both must be known constants, or the index shd be 0; else this fails.
Chris Lattner3cac88a2002-09-11 01:21:33 +0000195 int64_t arrayIdx = cast<ConstantSInt>(Idx[CurIDX])->getValue();
Vikram S. Adve8e22ead2002-10-13 21:47:44 +0000196 Result += arrayIdx == 0? 0
197 : (uint64_t) (arrayIdx * (int64_t) getTypeSize(Ty));
Vikram S. Adveed0030e2002-08-04 20:52:39 +0000198
Vikram S. Advef66723f2002-05-19 15:28:02 +0000199 } else if (const StructType *STy = dyn_cast<const StructType>(Ty)) {
Chris Lattnere7fb3602001-08-27 16:00:15 +0000200 assert(Idx[CurIDX]->getType() == Type::UByteTy && "Illegal struct idx");
Chris Lattnere9bb2df2001-12-03 22:26:30 +0000201 unsigned FieldNo = cast<ConstantUInt>(Idx[CurIDX])->getValue();
Chris Lattnere7fb3602001-08-27 16:00:15 +0000202
203 // Get structure layout information...
204 const StructLayout *Layout = getStructLayout(STy);
205
206 // Add in the offset, as calculated by the structure layout info...
Vikram S. Advef66723f2002-05-19 15:28:02 +0000207 assert(FieldNo < Layout->MemberOffsets.size() &&"FieldNo out of range!");
Chris Lattnere7fb3602001-08-27 16:00:15 +0000208 Result += Layout->MemberOffsets[FieldNo];
Vikram S. Adveed0030e2002-08-04 20:52:39 +0000209
Chris Lattnere7fb3602001-08-27 16:00:15 +0000210 // Update Ty to refer to current element
211 Ty = STy->getElementTypes()[FieldNo];
Chris Lattnere7fb3602001-08-27 16:00:15 +0000212 } else {
Vikram S. Advef66723f2002-05-19 15:28:02 +0000213 assert(0 && "Indexing type that is not struct or array?");
Chris Lattnere7fb3602001-08-27 16:00:15 +0000214 return 0; // Load directly through ptr
215 }
216 }
217
218 return Result;
219}