LLVM API Documentation

TargetData.cpp

Go to the documentation of this file.
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