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 <algorithm> 00026 using namespace llvm; 00027 00028 // Handle the Pass registration stuff necessary to use TargetData's. 00029 namespace { 00030 // Register the default SparcV9 implementation... 00031 RegisterPass<TargetData> X("targetdata", "Target Data Layout"); 00032 } 00033 00034 static inline void getTypeInfo(const Type *Ty, const TargetData *TD, 00035 uint64_t &Size, unsigned char &Alignment); 00036 00037 //===----------------------------------------------------------------------===// 00038 // Support for StructLayout 00039 //===----------------------------------------------------------------------===// 00040 00041 StructLayout::StructLayout(const StructType *ST, const TargetData &TD) { 00042 StructAlignment = 0; 00043 StructSize = 0; 00044 00045 // Loop over each of the elements, placing them in memory... 00046 for (StructType::element_iterator TI = ST->element_begin(), 00047 TE = ST->element_end(); TI != TE; ++TI) { 00048 const Type *Ty = *TI; 00049 unsigned char A; 00050 unsigned TyAlign; 00051 uint64_t TySize; 00052 getTypeInfo(Ty, &TD, TySize, A); 00053 TyAlign = A; 00054 00055 // Add padding if necessary to make the data element aligned properly... 00056 if (StructSize % TyAlign != 0) 00057 StructSize = (StructSize/TyAlign + 1) * TyAlign; // Add padding... 00058 00059 // Keep track of maximum alignment constraint 00060 StructAlignment = std::max(TyAlign, StructAlignment); 00061 00062 MemberOffsets.push_back(StructSize); 00063 StructSize += TySize; // Consume space for this data item 00064 } 00065 00066 // Empty structures have alignment of 1 byte. 00067 if (StructAlignment == 0) StructAlignment = 1; 00068 00069 // Add padding to the end of the struct so that it could be put in an array 00070 // and all array elements would be aligned correctly. 00071 if (StructSize % StructAlignment != 0) 00072 StructSize = (StructSize/StructAlignment + 1) * StructAlignment; 00073 } 00074 00075 00076 /// getElementContainingOffset - Given a valid offset into the structure, 00077 /// return the structure index that contains it. 00078 unsigned StructLayout::getElementContainingOffset(uint64_t Offset) const { 00079 std::vector<uint64_t>::const_iterator SI = 00080 std::upper_bound(MemberOffsets.begin(), MemberOffsets.end(), 00081 Offset); 00082 assert(SI != MemberOffsets.begin() && "Offset not in structure type!"); 00083 --SI; 00084 assert(*SI <= Offset && "upper_bound didn't work"); 00085 assert((SI == MemberOffsets.begin() || *(SI-1) < Offset) && 00086 (SI+1 == MemberOffsets.end() || *(SI+1) > Offset) && 00087 "Upper bound didn't work!"); 00088 return SI-MemberOffsets.begin(); 00089 } 00090 00091 //===----------------------------------------------------------------------===// 00092 // TargetData Class Implementation 00093 //===----------------------------------------------------------------------===// 00094 00095 TargetData::TargetData(const std::string &TargetName, 00096 bool isLittleEndian, unsigned char PtrSize, 00097 unsigned char PtrAl, unsigned char DoubleAl, 00098 unsigned char FloatAl, unsigned char LongAl, 00099 unsigned char IntAl, unsigned char ShortAl, 00100 unsigned char ByteAl, unsigned char BoolAl) { 00101 00102 // If this assert triggers, a pass "required" TargetData information, but the 00103 // top level tool did not provide one for it. We do not want to default 00104 // construct, or else we might end up using a bad endianness or pointer size! 00105 // 00106 assert(!TargetName.empty() && 00107 "ERROR: Tool did not specify a target data to use!"); 00108 00109 LittleEndian = isLittleEndian; 00110 PointerSize = PtrSize; 00111 PointerAlignment = PtrAl; 00112 DoubleAlignment = DoubleAl; 00113 FloatAlignment = FloatAl; 00114 LongAlignment = LongAl; 00115 IntAlignment = IntAl; 00116 ShortAlignment = ShortAl; 00117 ByteAlignment = ByteAl; 00118 BoolAlignment = BoolAl; 00119 } 00120 00121 TargetData::TargetData(const std::string &ToolName, const Module *M) { 00122 LittleEndian = M->getEndianness() != Module::BigEndian; 00123 PointerSize = M->getPointerSize() != Module::Pointer64 ? 4 : 8; 00124 PointerAlignment = PointerSize; 00125 DoubleAlignment = PointerSize; 00126 FloatAlignment = 4; 00127 LongAlignment = PointerSize; 00128 IntAlignment = 4; 00129 ShortAlignment = 2; 00130 ByteAlignment = 1; 00131 BoolAlignment = 1; 00132 } 00133 00134 /// Layouts - The lazy cache of structure layout information maintained by 00135 /// TargetData. 00136 /// 00137 static std::map<std::pair<const TargetData*,const StructType*>, 00138 StructLayout> *Layouts = 0; 00139 00140 00141 TargetData::~TargetData() { 00142 if (Layouts) { 00143 // Remove any layouts for this TD. 00144 std::map<std::pair<const TargetData*, 00145 const StructType*>, StructLayout>::iterator 00146 I = Layouts->lower_bound(std::make_pair(this, (const StructType*)0)); 00147 while (I != Layouts->end() && I->first.first == this) 00148 Layouts->erase(I++); 00149 if (Layouts->empty()) { 00150 delete Layouts; 00151 Layouts = 0; 00152 } 00153 } 00154 } 00155 00156 const StructLayout *TargetData::getStructLayout(const StructType *Ty) const { 00157 if (Layouts == 0) 00158 Layouts = new std::map<std::pair<const TargetData*,const StructType*>, 00159 StructLayout>(); 00160 std::map<std::pair<const TargetData*,const StructType*>, 00161 StructLayout>::iterator 00162 I = Layouts->lower_bound(std::make_pair(this, Ty)); 00163 if (I != Layouts->end() && I->first.first == this && I->first.second == Ty) 00164 return &I->second; 00165 else { 00166 return &Layouts->insert(I, std::make_pair(std::make_pair(this, Ty), 00167 StructLayout(Ty, *this)))->second; 00168 } 00169 } 00170 00171 /// InvalidateStructLayoutInfo - TargetData speculatively caches StructLayout 00172 /// objects. If a TargetData object is alive when types are being refined and 00173 /// removed, this method must be called whenever a StructType is removed to 00174 /// avoid a dangling pointer in this cache. 00175 void TargetData::InvalidateStructLayoutInfo(const StructType *Ty) const { 00176 if (!Layouts) return; // No cache. 00177 00178 std::map<std::pair<const TargetData*,const StructType*>, 00179 StructLayout>::iterator I = Layouts->find(std::make_pair(this, Ty)); 00180 if (I != Layouts->end()) 00181 Layouts->erase(I); 00182 } 00183 00184 00185 00186 static inline void getTypeInfo(const Type *Ty, const TargetData *TD, 00187 uint64_t &Size, unsigned char &Alignment) { 00188 assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!"); 00189 switch (Ty->getTypeID()) { 00190 case Type::BoolTyID: Size = 1; Alignment = TD->getBoolAlignment(); return; 00191 case Type::VoidTyID: 00192 case Type::UByteTyID: 00193 case Type::SByteTyID: Size = 1; Alignment = TD->getByteAlignment(); return; 00194 case Type::UShortTyID: 00195 case Type::ShortTyID: Size = 2; Alignment = TD->getShortAlignment(); return; 00196 case Type::UIntTyID: 00197 case Type::IntTyID: Size = 4; Alignment = TD->getIntAlignment(); return; 00198 case Type::ULongTyID: 00199 case Type::LongTyID: Size = 8; Alignment = TD->getLongAlignment(); return; 00200 case Type::FloatTyID: Size = 4; Alignment = TD->getFloatAlignment(); return; 00201 case Type::DoubleTyID: Size = 8; Alignment = TD->getDoubleAlignment(); return; 00202 case Type::LabelTyID: 00203 case Type::PointerTyID: 00204 Size = TD->getPointerSize(); Alignment = TD->getPointerAlignment(); 00205 return; 00206 case Type::ArrayTyID: { 00207 const ArrayType *ATy = cast<ArrayType>(Ty); 00208 getTypeInfo(ATy->getElementType(), TD, Size, Alignment); 00209 unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment; 00210 Size = AlignedSize*ATy->getNumElements(); 00211 return; 00212 } 00213 case Type::PackedTyID: { 00214 const PackedType *PTy = cast<PackedType>(Ty); 00215 getTypeInfo(PTy->getElementType(), TD, Size, Alignment); 00216 unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment; 00217 Size = AlignedSize*PTy->getNumElements(); 00218 // FIXME: The alignments of specific packed types are target dependent. 00219 // For now, just set it to be equal to Size. 00220 Alignment = Size; 00221 return; 00222 } 00223 case Type::StructTyID: { 00224 // Get the layout annotation... which is lazily created on demand. 00225 const StructLayout *Layout = TD->getStructLayout(cast<StructType>(Ty)); 00226 Size = Layout->StructSize; Alignment = Layout->StructAlignment; 00227 return; 00228 } 00229 00230 default: 00231 assert(0 && "Bad type for getTypeInfo!!!"); 00232 return; 00233 } 00234 } 00235 00236 uint64_t TargetData::getTypeSize(const Type *Ty) const { 00237 uint64_t Size; 00238 unsigned char Align; 00239 getTypeInfo(Ty, this, Size, Align); 00240 return Size; 00241 } 00242 00243 unsigned char TargetData::getTypeAlignment(const Type *Ty) const { 00244 uint64_t Size; 00245 unsigned char Align; 00246 getTypeInfo(Ty, this, Size, Align); 00247 return Align; 00248 } 00249 00250 unsigned char TargetData::getTypeAlignmentShift(const Type *Ty) const { 00251 unsigned Align = getTypeAlignment(Ty); 00252 assert(!(Align & (Align-1)) && "Alignment is not a power of two!"); 00253 return Log2_32(Align); 00254 } 00255 00256 /// getIntPtrType - Return an unsigned integer type that is the same size or 00257 /// greater to the host pointer size. 00258 const Type *TargetData::getIntPtrType() const { 00259 switch (getPointerSize()) { 00260 default: assert(0 && "Unknown pointer size!"); 00261 case 2: return Type::UShortTy; 00262 case 4: return Type::UIntTy; 00263 case 8: return Type::ULongTy; 00264 } 00265 } 00266 00267 00268 uint64_t TargetData::getIndexedOffset(const Type *ptrTy, 00269 const std::vector<Value*> &Idx) const { 00270 const Type *Ty = ptrTy; 00271 assert(isa<PointerType>(Ty) && "Illegal argument for getIndexedOffset()"); 00272 uint64_t Result = 0; 00273 00274 generic_gep_type_iterator<std::vector<Value*>::const_iterator> 00275 TI = gep_type_begin(ptrTy, Idx.begin(), Idx.end()); 00276 for (unsigned CurIDX = 0; CurIDX != Idx.size(); ++CurIDX, ++TI) { 00277 if (const StructType *STy = dyn_cast<StructType>(*TI)) { 00278 assert(Idx[CurIDX]->getType() == Type::UIntTy && "Illegal struct idx"); 00279 unsigned FieldNo = cast<ConstantUInt>(Idx[CurIDX])->getValue(); 00280 00281 // Get structure layout information... 00282 const StructLayout *Layout = getStructLayout(STy); 00283 00284 // Add in the offset, as calculated by the structure layout info... 00285 assert(FieldNo < Layout->MemberOffsets.size() &&"FieldNo out of range!"); 00286 Result += Layout->MemberOffsets[FieldNo]; 00287 00288 // Update Ty to refer to current element 00289 Ty = STy->getElementType(FieldNo); 00290 } else { 00291 // Update Ty to refer to current element 00292 Ty = cast<SequentialType>(Ty)->getElementType(); 00293 00294 // Get the array index and the size of each array element. 00295 int64_t arrayIdx = cast<ConstantInt>(Idx[CurIDX])->getRawValue(); 00296 Result += arrayIdx * (int64_t)getTypeSize(Ty); 00297 } 00298 } 00299 00300 return Result; 00301 } 00302