clean up load and stores alot
[oota-llvm.git] / lib / Target / TargetData.cpp
index ed6936dd1223c75313227feb656fb5f15e055997..fc58f577497143d12d2ae23afcac08fb3cf72f6d 100644 (file)
@@ -8,8 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // This file defines target properties related to datatype size/offset/alignment
 //===----------------------------------------------------------------------===//
 //
 // This file defines target properties related to datatype size/offset/alignment
-// information.  It uses lazy annotations to cache information about how 
-// structure types are laid out and used.
+// information.
 //
 // This structure should be created once, filled in if the defaults are not
 // correct and then passed around by const&.  None of the members functions
 //
 // This structure should be created once, filled in if the defaults are not
 // correct and then passed around by const&.  None of the members functions
@@ -21,8 +20,9 @@
 #include "llvm/Module.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Constants.h"
 #include "llvm/Module.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Constants.h"
-
-namespace llvm {
+#include "llvm/Support/GetElementPtrTypeIterator.h"
+#include "llvm/Support/MathExtras.h"
+using namespace llvm;
 
 // Handle the Pass registration stuff necessary to use TargetData's.
 namespace {
 
 // Handle the Pass registration stuff necessary to use TargetData's.
 namespace {
@@ -31,21 +31,19 @@ namespace {
 }
 
 static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
 }
 
 static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
-                              uint64_t &Size, unsigned char &Alignment);
+                               uint64_t &Size, unsigned char &Alignment);
 
 //===----------------------------------------------------------------------===//
 
 //===----------------------------------------------------------------------===//
-// Support for StructLayout Annotation
+// Support for StructLayout
 //===----------------------------------------------------------------------===//
 
 //===----------------------------------------------------------------------===//
 
-StructLayout::StructLayout(const StructType *ST, const TargetData &TD) 
-  : Annotation(TD.getStructLayoutAID()) {
+StructLayout::StructLayout(const StructType *ST, const TargetData &TD) {
   StructAlignment = 0;
   StructSize = 0;
 
   // Loop over each of the elements, placing them in memory...
   StructAlignment = 0;
   StructSize = 0;
 
   // Loop over each of the elements, placing them in memory...
-  for (StructType::ElementTypes::const_iterator
-        TI = ST->getElementTypes().begin(), 
-        TE = ST->getElementTypes().end(); TI != TE; ++TI) {
+  for (StructType::element_iterator TI = ST->element_begin(), 
+         TE = ST->element_end(); TI != TE; ++TI) {
     const Type *Ty = *TI;
     unsigned char A;
     unsigned TyAlign;
     const Type *Ty = *TI;
     unsigned char A;
     unsigned TyAlign;
@@ -73,16 +71,6 @@ StructLayout::StructLayout(const StructType *ST, const TargetData &TD)
     StructSize = (StructSize/StructAlignment + 1) * StructAlignment;
 }
 
     StructSize = (StructSize/StructAlignment + 1) * StructAlignment;
 }
 
-Annotation *TargetData::TypeAnFactory(AnnotationID AID, const Annotable *T,
-                                     void *D) {
-  const TargetData &TD = *(const TargetData*)D;
-  assert(AID == TD.AID && "Target data annotation ID mismatch!");
-  const Type *Ty = cast<Type>((const Value *)T);
-  assert(isa<StructType>(Ty) && 
-        "Can only create StructLayout annotation on structs!");
-  return new StructLayout(cast<StructType>(Ty), TD);
-}
-
 //===----------------------------------------------------------------------===//
 //                       TargetData Class Implementation
 //===----------------------------------------------------------------------===//
 //===----------------------------------------------------------------------===//
 //                       TargetData Class Implementation
 //===----------------------------------------------------------------------===//
@@ -92,12 +80,10 @@ TargetData::TargetData(const std::string &TargetName,
                        unsigned char PtrAl, unsigned char DoubleAl,
                        unsigned char FloatAl, unsigned char LongAl, 
                        unsigned char IntAl, unsigned char ShortAl,
                        unsigned char PtrAl, unsigned char DoubleAl,
                        unsigned char FloatAl, unsigned char LongAl, 
                        unsigned char IntAl, unsigned char ShortAl,
-                       unsigned char ByteAl)
-  : AID(AnnotationManager::getID("TargetData::" + TargetName)) {
-  AnnotationManager::registerAnnotationFactory(AID, TypeAnFactory, this);
+                       unsigned char ByteAl, unsigned char BoolAl) {
 
   // If this assert triggers, a pass "required" TargetData information, but the
 
   // If this assert triggers, a pass "required" TargetData information, but the
-  // top level tool did not provide once for it.  We do not want to default
+  // top level tool did not provide one for it.  We do not want to default
   // construct, or else we might end up using a bad endianness or pointer size!
   //
   assert(!TargetName.empty() &&
   // construct, or else we might end up using a bad endianness or pointer size!
   //
   assert(!TargetName.empty() &&
@@ -107,40 +93,67 @@ TargetData::TargetData(const std::string &TargetName,
   PointerSize      = PtrSize;
   PointerAlignment = PtrAl;
   DoubleAlignment  = DoubleAl;
   PointerSize      = PtrSize;
   PointerAlignment = PtrAl;
   DoubleAlignment  = DoubleAl;
-  assert(DoubleAlignment == PtrAl &&
-         "Double alignment and pointer alignment agree for now!");
   FloatAlignment   = FloatAl;
   LongAlignment    = LongAl;
   IntAlignment     = IntAl;
   ShortAlignment   = ShortAl;
   ByteAlignment    = ByteAl;
   FloatAlignment   = FloatAl;
   LongAlignment    = LongAl;
   IntAlignment     = IntAl;
   ShortAlignment   = ShortAl;
   ByteAlignment    = ByteAl;
+  BoolAlignment    = BoolAl;
 }
 
 }
 
-TargetData::TargetData(const std::string &ToolName, const Module *M)
-  : AID(AnnotationManager::getID("TargetData::" + ToolName)) {
-  AnnotationManager::registerAnnotationFactory(AID, TypeAnFactory, this);
-
+TargetData::TargetData(const std::string &ToolName, const Module *M) {
   LittleEndian     = M->getEndianness() != Module::BigEndian;
   PointerSize      = M->getPointerSize() != Module::Pointer64 ? 4 : 8;
   PointerAlignment = PointerSize;
   DoubleAlignment  = PointerSize;
   FloatAlignment   = 4;
   LittleEndian     = M->getEndianness() != Module::BigEndian;
   PointerSize      = M->getPointerSize() != Module::Pointer64 ? 4 : 8;
   PointerAlignment = PointerSize;
   DoubleAlignment  = PointerSize;
   FloatAlignment   = 4;
-  LongAlignment    = 8;
+  LongAlignment    = PointerSize;
   IntAlignment     = 4;
   ShortAlignment   = 2;
   ByteAlignment    = 1;
   IntAlignment     = 4;
   ShortAlignment   = 2;
   ByteAlignment    = 1;
+  BoolAlignment    = 1;
 }
 
 }
 
+static std::map<std::pair<const TargetData*,const StructType*>,
+                StructLayout> *Layouts = 0;
+
+
 TargetData::~TargetData() {
 TargetData::~TargetData() {
-  AnnotationManager::registerAnnotationFactory(AID, 0);   // Deregister factory
+  if (Layouts) {
+    // Remove any layouts for this TD.
+    std::map<std::pair<const TargetData*,
+      const StructType*>, StructLayout>::iterator
+      I = Layouts->lower_bound(std::make_pair(this, (const StructType*)0));
+    while (I != Layouts->end() && I->first.first == this)
+      Layouts->erase(I++);
+    if (Layouts->empty()) {
+      delete Layouts;
+      Layouts = 0;
+    }
+  }
+}
+
+const StructLayout *TargetData::getStructLayout(const StructType *Ty) const {
+  if (Layouts == 0)
+    Layouts = new std::map<std::pair<const TargetData*,const StructType*>,
+                           StructLayout>();
+  std::map<std::pair<const TargetData*,const StructType*>,
+                     StructLayout>::iterator
+    I = Layouts->lower_bound(std::make_pair(this, Ty));
+  if (I != Layouts->end() && I->first.first == this && I->first.second == Ty)
+    return &I->second;
+  else {
+    return &Layouts->insert(I, std::make_pair(std::make_pair(this, Ty),
+                                              StructLayout(Ty, *this)))->second;
+  }
 }
 
 static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
 }
 
 static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
-                              uint64_t &Size, unsigned char &Alignment) {
+                               uint64_t &Size, unsigned char &Alignment) {
   assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
   assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
-  switch (Ty->getPrimitiveID()) {
+  switch (Ty->getTypeID()) {
+  case Type::BoolTyID:   Size = 1; Alignment = TD->getBoolAlignment(); return;
   case Type::VoidTyID:
   case Type::VoidTyID:
-  case Type::BoolTyID:
   case Type::UByteTyID:
   case Type::SByteTyID:  Size = 1; Alignment = TD->getByteAlignment(); return;
   case Type::UShortTyID:
   case Type::UByteTyID:
   case Type::SByteTyID:  Size = 1; Alignment = TD->getByteAlignment(); return;
   case Type::UShortTyID:
@@ -156,19 +169,26 @@ static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
     Size = TD->getPointerSize(); Alignment = TD->getPointerAlignment();
     return;
   case Type::ArrayTyID: {
     Size = TD->getPointerSize(); Alignment = TD->getPointerAlignment();
     return;
   case Type::ArrayTyID: {
-    const ArrayType *ATy = (const ArrayType *)Ty;
+    const ArrayType *ATy = cast<ArrayType>(Ty);
     getTypeInfo(ATy->getElementType(), TD, Size, Alignment);
     getTypeInfo(ATy->getElementType(), TD, Size, Alignment);
-    Size *= ATy->getNumElements();
+    unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment;
+    Size = AlignedSize*ATy->getNumElements();
+    return;
+  }
+  case Type::PackedTyID: {
+    const PackedType *PTy = cast<PackedType>(Ty);
+    getTypeInfo(PTy->getElementType(), TD, Size, Alignment);
+    unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment;
+    Size = AlignedSize*PTy->getNumElements();
     return;
   }
   case Type::StructTyID: {
     // Get the layout annotation... which is lazily created on demand.
     return;
   }
   case Type::StructTyID: {
     // Get the layout annotation... which is lazily created on demand.
-    const StructLayout *Layout = TD->getStructLayout((const StructType*)Ty);
+    const StructLayout *Layout = TD->getStructLayout(cast<StructType>(Ty));
     Size = Layout->StructSize; Alignment = Layout->StructAlignment;
     return;
   }
     
     Size = Layout->StructSize; Alignment = Layout->StructAlignment;
     return;
   }
     
-  case Type::TypeTyID:
   default:
     assert(0 && "Bad type for getTypeInfo!!!");
     return;
   default:
     assert(0 && "Bad type for getTypeInfo!!!");
     return;
@@ -189,23 +209,35 @@ unsigned char TargetData::getTypeAlignment(const Type *Ty) const {
   return Align;
 }
 
   return Align;
 }
 
+unsigned char TargetData::getTypeAlignmentShift(const Type *Ty) const {
+  unsigned Align = getTypeAlignment(Ty);
+  assert(!(Align & (Align-1)) && "Alignment is not a power of two!");
+  return log2(Align);
+}
+
+/// getIntPtrType - Return an unsigned integer type that is the same size or
+/// greater to the host pointer size.
+const Type *TargetData::getIntPtrType() const {
+  switch (getPointerSize()) {
+  default: assert(0 && "Unknown pointer size!");
+  case 2: return Type::UShortTy;
+  case 4: return Type::UIntTy;
+  case 8: return Type::ULongTy;
+  }
+}
+
+
 uint64_t TargetData::getIndexedOffset(const Type *ptrTy,
 uint64_t TargetData::getIndexedOffset(const Type *ptrTy,
-                                     const std::vector<Value*> &Idx) const {
+                                      const std::vector<Value*> &Idx) const {
   const Type *Ty = ptrTy;
   assert(isa<PointerType>(Ty) && "Illegal argument for getIndexedOffset()");
   uint64_t Result = 0;
 
   const Type *Ty = ptrTy;
   assert(isa<PointerType>(Ty) && "Illegal argument for getIndexedOffset()");
   uint64_t Result = 0;
 
-  for (unsigned CurIDX = 0; CurIDX != Idx.size(); ++CurIDX) {
-    if (Idx[CurIDX]->getType() == Type::LongTy) {
-      // Update Ty to refer to current element
-      Ty = cast<SequentialType>(Ty)->getElementType();
-
-      // Get the array index and the size of each array element.
-      int64_t arrayIdx = cast<ConstantSInt>(Idx[CurIDX])->getValue();
-      Result += arrayIdx * (int64_t)getTypeSize(Ty);
-    } else {
-      const StructType *STy = cast<StructType>(Ty);
-      assert(Idx[CurIDX]->getType() == Type::UByteTy && "Illegal struct idx");
+  generic_gep_type_iterator<std::vector<Value*>::const_iterator>
+    TI = gep_type_begin(ptrTy, Idx.begin(), Idx.end());
+  for (unsigned CurIDX = 0; CurIDX != Idx.size(); ++CurIDX, ++TI) {
+    if (const StructType *STy = dyn_cast<StructType>(*TI)) {
+      assert(Idx[CurIDX]->getType() == Type::UIntTy && "Illegal struct idx");
       unsigned FieldNo = cast<ConstantUInt>(Idx[CurIDX])->getValue();
 
       // Get structure layout information...
       unsigned FieldNo = cast<ConstantUInt>(Idx[CurIDX])->getValue();
 
       // Get structure layout information...
@@ -216,11 +248,17 @@ uint64_t TargetData::getIndexedOffset(const Type *ptrTy,
       Result += Layout->MemberOffsets[FieldNo];
 
       // Update Ty to refer to current element
       Result += Layout->MemberOffsets[FieldNo];
 
       // Update Ty to refer to current element
-      Ty = STy->getElementTypes()[FieldNo];
+      Ty = STy->getElementType(FieldNo);
+    } else {
+      // Update Ty to refer to current element
+      Ty = cast<SequentialType>(Ty)->getElementType();
+
+      // Get the array index and the size of each array element.
+      int64_t arrayIdx = cast<ConstantInt>(Idx[CurIDX])->getRawValue();
+      Result += arrayIdx * (int64_t)getTypeSize(Ty);
     }
   }
 
   return Result;
 }
 
     }
   }
 
   return Result;
 }
 
-} // End llvm namespace