LLVM API Documentation
00001 //===-- TargetData.cpp - Data size & alignment routines --------------------==// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was developed by the LLVM research group and is distributed under 00006 // the University of Illinois Open Source License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines target properties related to datatype size/offset/alignment 00011 // information. 00012 // 00013 // This structure should be created once, filled in if the defaults are not 00014 // correct and then passed around by const&. None of the members functions 00015 // require modification to the object. 00016 // 00017 //===----------------------------------------------------------------------===// 00018 00019 #include "llvm/Target/TargetData.h" 00020 #include "llvm/Module.h" 00021 #include "llvm/DerivedTypes.h" 00022 #include "llvm/Constants.h" 00023 #include "llvm/Support/GetElementPtrTypeIterator.h" 00024 #include "llvm/Support/MathExtras.h" 00025 #include "llvm/ADT/StringExtras.h" 00026 #include <algorithm> 00027 #include <cstdlib> 00028 #include <sstream> 00029 using namespace llvm; 00030 00031 // Handle the Pass registration stuff necessary to use TargetData's. 00032 namespace { 00033 // Register the default SparcV9 implementation... 00034 RegisterPass<TargetData> X("targetdata", "Target Data Layout"); 00035 } 00036 00037 static inline void getTypeInfo(const Type *Ty, const TargetData *TD, 00038 uint64_t &Size, unsigned char &Alignment); 00039 00040 //===----------------------------------------------------------------------===// 00041 // Support for StructLayout 00042 //===----------------------------------------------------------------------===// 00043 00044 StructLayout::StructLayout(const StructType *ST, const TargetData &TD) { 00045 StructAlignment = 0; 00046 StructSize = 0; 00047 00048 // Loop over each of the elements, placing them in memory... 00049 for (StructType::element_iterator TI = ST->element_begin(), 00050 TE = ST->element_end(); TI != TE; ++TI) { 00051 const Type *Ty = *TI; 00052 unsigned char A; 00053 unsigned TyAlign; 00054 uint64_t TySize; 00055 getTypeInfo(Ty, &TD, TySize, A); 00056 TyAlign = A; 00057 00058 // Add padding if necessary to make the data element aligned properly... 00059 if (StructSize % TyAlign != 0) 00060 StructSize = (StructSize/TyAlign + 1) * TyAlign; // Add padding... 00061 00062 // Keep track of maximum alignment constraint 00063 StructAlignment = std::max(TyAlign, StructAlignment); 00064 00065 MemberOffsets.push_back(StructSize); 00066 StructSize += TySize; // Consume space for this data item 00067 } 00068 00069 // Empty structures have alignment of 1 byte. 00070 if (StructAlignment == 0) StructAlignment = 1; 00071 00072 // Add padding to the end of the struct so that it could be put in an array 00073 // and all array elements would be aligned correctly. 00074 if (StructSize % StructAlignment != 0) 00075 StructSize = (StructSize/StructAlignment + 1) * StructAlignment; 00076 } 00077 00078 00079 /// getElementContainingOffset - Given a valid offset into the structure, 00080 /// return the structure index that contains it. 00081 unsigned StructLayout::getElementContainingOffset(uint64_t Offset) const { 00082 std::vector<uint64_t>::const_iterator SI = 00083 std::upper_bound(MemberOffsets.begin(), MemberOffsets.end(), 00084 Offset); 00085 assert(SI != MemberOffsets.begin() && "Offset not in structure type!"); 00086 --SI; 00087 assert(*SI <= Offset && "upper_bound didn't work"); 00088 assert((SI == MemberOffsets.begin() || *(SI-1) < Offset) && 00089 (SI+1 == MemberOffsets.end() || *(SI+1) > Offset) && 00090 "Upper bound didn't work!"); 00091 return SI-MemberOffsets.begin(); 00092 } 00093 00094 //===----------------------------------------------------------------------===// 00095 // TargetData Class Implementation 00096 //===----------------------------------------------------------------------===// 00097 00098 void TargetData::init(const std::string &TargetDescription) { 00099 std::string temp = TargetDescription; 00100 00101 LittleEndian = false; 00102 PointerSize = 8; 00103 PointerAlignment = 8; 00104 DoubleAlignment = 8; 00105 FloatAlignment = 4; 00106 LongAlignment = 8; 00107 IntAlignment = 4; 00108 ShortAlignment = 2; 00109 ByteAlignment = 1; 00110 BoolAlignment = 1; 00111 00112 while (!temp.empty()) { 00113 std::string token = getToken(temp, "-"); 00114 00115 char signal = getToken(token, ":")[0]; 00116 00117 switch(signal) { 00118 case 'E': 00119 LittleEndian = false; 00120 break; 00121 case 'e': 00122 LittleEndian = true; 00123 break; 00124 case 'p': 00125 PointerSize = atoi(getToken(token,":").c_str()) / 8; 00126 PointerAlignment = atoi(getToken(token,":").c_str()) / 8; 00127 break; 00128 case 'd': 00129 DoubleAlignment = atoi(getToken(token,":").c_str()) / 8; 00130 break; 00131 case 'f': 00132 FloatAlignment = atoi(getToken(token, ":").c_str()) / 8; 00133 break; 00134 case 'l': 00135 LongAlignment = atoi(getToken(token, ":").c_str()) / 8; 00136 break; 00137 case 'i': 00138 IntAlignment = atoi(getToken(token, ":").c_str()) / 8; 00139 break; 00140 case 's': 00141 ShortAlignment = atoi(getToken(token, ":").c_str()) / 8; 00142 break; 00143 case 'b': 00144 ByteAlignment = atoi(getToken(token, ":").c_str()) / 8; 00145 break; 00146 case 'B': 00147 BoolAlignment = atoi(getToken(token, ":").c_str()) / 8; 00148 break; 00149 default: 00150 break; 00151 } 00152 } 00153 } 00154 00155 TargetData::TargetData(const Module *M) { 00156 LittleEndian = M->getEndianness() != Module::BigEndian; 00157 PointerSize = M->getPointerSize() != Module::Pointer64 ? 4 : 8; 00158 PointerAlignment = PointerSize; 00159 DoubleAlignment = PointerSize; 00160 FloatAlignment = 4; 00161 LongAlignment = PointerSize; 00162 IntAlignment = 4; 00163 ShortAlignment = 2; 00164 ByteAlignment = 1; 00165 BoolAlignment = 1; 00166 } 00167 00168 /// Layouts - The lazy cache of structure layout information maintained by 00169 /// TargetData. 00170 /// 00171 static std::map<std::pair<const TargetData*,const StructType*>, 00172 StructLayout> *Layouts = 0; 00173 00174 00175 TargetData::~TargetData() { 00176 if (Layouts) { 00177 // Remove any layouts for this TD. 00178 std::map<std::pair<const TargetData*, 00179 const StructType*>, StructLayout>::iterator 00180 I = Layouts->lower_bound(std::make_pair(this, (const StructType*)0)); 00181 while (I != Layouts->end() && I->first.first == this) 00182 Layouts->erase(I++); 00183 if (Layouts->empty()) { 00184 delete Layouts; 00185 Layouts = 0; 00186 } 00187 } 00188 } 00189 00190 std::string TargetData::getStringRepresentation() const { 00191 std::stringstream repr; 00192 00193 if (LittleEndian) 00194 repr << "e"; 00195 else 00196 repr << "E"; 00197 00198 repr << "-p:" << (PointerSize * 8) << ":" << (PointerAlignment * 8); 00199 repr << "-d:64:" << (DoubleAlignment * 8); 00200 repr << "-f:32:" << (FloatAlignment * 8); 00201 repr << "-l:64:" << (LongAlignment * 8); 00202 repr << "-i:32:" << (IntAlignment * 8); 00203 repr << "-s:16:" << (ShortAlignment * 8); 00204 repr << "-b:8:" << (ByteAlignment * 8); 00205 repr << "-B:8:" << (BoolAlignment * 8); 00206 00207 return repr.str(); 00208 } 00209 00210 const StructLayout *TargetData::getStructLayout(const StructType *Ty) const { 00211 if (Layouts == 0) 00212 Layouts = new std::map<std::pair<const TargetData*,const StructType*>, 00213 StructLayout>(); 00214 std::map<std::pair<const TargetData*,const StructType*>, 00215 StructLayout>::iterator 00216 I = Layouts->lower_bound(std::make_pair(this, Ty)); 00217 if (I != Layouts->end() && I->first.first == this && I->first.second == Ty) 00218 return &I->second; 00219 else { 00220 return &Layouts->insert(I, std::make_pair(std::make_pair(this, Ty), 00221 StructLayout(Ty, *this)))->second; 00222 } 00223 } 00224 00225 /// InvalidateStructLayoutInfo - TargetData speculatively caches StructLayout 00226 /// objects. If a TargetData object is alive when types are being refined and 00227 /// removed, this method must be called whenever a StructType is removed to 00228 /// avoid a dangling pointer in this cache. 00229 void TargetData::InvalidateStructLayoutInfo(const StructType *Ty) const { 00230 if (!Layouts) return; // No cache. 00231 00232 std::map<std::pair<const TargetData*,const StructType*>, 00233 StructLayout>::iterator I = Layouts->find(std::make_pair(this, Ty)); 00234 if (I != Layouts->end()) 00235 Layouts->erase(I); 00236 } 00237 00238 00239 00240 static inline void getTypeInfo(const Type *Ty, const TargetData *TD, 00241 uint64_t &Size, unsigned char &Alignment) { 00242 assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!"); 00243 switch (Ty->getTypeID()) { 00244 case Type::BoolTyID: Size = 1; Alignment = TD->getBoolAlignment(); return; 00245 case Type::VoidTyID: 00246 case Type::UByteTyID: 00247 case Type::SByteTyID: Size = 1; Alignment = TD->getByteAlignment(); return; 00248 case Type::UShortTyID: 00249 case Type::ShortTyID: Size = 2; Alignment = TD->getShortAlignment(); return; 00250 case Type::UIntTyID: 00251 case Type::IntTyID: Size = 4; Alignment = TD->getIntAlignment(); return; 00252 case Type::ULongTyID: 00253 case Type::LongTyID: Size = 8; Alignment = TD->getLongAlignment(); return; 00254 case Type::FloatTyID: Size = 4; Alignment = TD->getFloatAlignment(); return; 00255 case Type::DoubleTyID: Size = 8; Alignment = TD->getDoubleAlignment(); return; 00256 case Type::LabelTyID: 00257 case Type::PointerTyID: 00258 Size = TD->getPointerSize(); Alignment = TD->getPointerAlignment(); 00259 return; 00260 case Type::ArrayTyID: { 00261 const ArrayType *ATy = cast<ArrayType>(Ty); 00262 getTypeInfo(ATy->getElementType(), TD, Size, Alignment); 00263 unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment; 00264 Size = AlignedSize*ATy->getNumElements(); 00265 return; 00266 } 00267 case Type::PackedTyID: { 00268 const PackedType *PTy = cast<PackedType>(Ty); 00269 getTypeInfo(PTy->getElementType(), TD, Size, Alignment); 00270 unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment; 00271 Size = AlignedSize*PTy->getNumElements(); 00272 // FIXME: The alignments of specific packed types are target dependent. 00273 // For now, just set it to be equal to Size. 00274 Alignment = Size; 00275 return; 00276 } 00277 case Type::StructTyID: { 00278 // Get the layout annotation... which is lazily created on demand. 00279 const StructLayout *Layout = TD->getStructLayout(cast<StructType>(Ty)); 00280 Size = Layout->StructSize; Alignment = Layout->StructAlignment; 00281 return; 00282 } 00283 00284 default: 00285 assert(0 && "Bad type for getTypeInfo!!!"); 00286 return; 00287 } 00288 } 00289 00290 uint64_t TargetData::getTypeSize(const Type *Ty) const { 00291 uint64_t Size; 00292 unsigned char Align; 00293 getTypeInfo(Ty, this, Size, Align); 00294 return Size; 00295 } 00296 00297 unsigned char TargetData::getTypeAlignment(const Type *Ty) const { 00298 uint64_t Size; 00299 unsigned char Align; 00300 getTypeInfo(Ty, this, Size, Align); 00301 return Align; 00302 } 00303 00304 unsigned char TargetData::getTypeAlignmentShift(const Type *Ty) const { 00305 unsigned Align = getTypeAlignment(Ty); 00306 assert(!(Align & (Align-1)) && "Alignment is not a power of two!"); 00307 return Log2_32(Align); 00308 } 00309 00310 /// getIntPtrType - Return an unsigned integer type that is the same size or 00311 /// greater to the host pointer size. 00312 const Type *TargetData::getIntPtrType() const { 00313 switch (getPointerSize()) { 00314 default: assert(0 && "Unknown pointer size!"); 00315 case 2: return Type::UShortTy; 00316 case 4: return Type::UIntTy; 00317 case 8: return Type::ULongTy; 00318 } 00319 } 00320 00321 00322 uint64_t TargetData::getIndexedOffset(const Type *ptrTy, 00323 const std::vector<Value*> &Idx) const { 00324 const Type *Ty = ptrTy; 00325 assert(isa<PointerType>(Ty) && "Illegal argument for getIndexedOffset()"); 00326 uint64_t Result = 0; 00327 00328 generic_gep_type_iterator<std::vector<Value*>::const_iterator> 00329 TI = gep_type_begin(ptrTy, Idx.begin(), Idx.end()); 00330 for (unsigned CurIDX = 0; CurIDX != Idx.size(); ++CurIDX, ++TI) { 00331 if (const StructType *STy = dyn_cast<StructType>(*TI)) { 00332 assert(Idx[CurIDX]->getType() == Type::UIntTy && "Illegal struct idx"); 00333 unsigned FieldNo = cast<ConstantUInt>(Idx[CurIDX])->getValue(); 00334 00335 // Get structure layout information... 00336 const StructLayout *Layout = getStructLayout(STy); 00337 00338 // Add in the offset, as calculated by the structure layout info... 00339 assert(FieldNo < Layout->MemberOffsets.size() &&"FieldNo out of range!"); 00340 Result += Layout->MemberOffsets[FieldNo]; 00341 00342 // Update Ty to refer to current element 00343 Ty = STy->getElementType(FieldNo); 00344 } else { 00345 // Update Ty to refer to current element 00346 Ty = cast<SequentialType>(Ty)->getElementType(); 00347 00348 // Get the array index and the size of each array element. 00349 int64_t arrayIdx = cast<ConstantInt>(Idx[CurIDX])->getRawValue(); 00350 Result += arrayIdx * (int64_t)getTypeSize(Ty); 00351 } 00352 } 00353 00354 return Result; 00355 } 00356