Rename SPARC V8 target to be the LLVM SPARC target.
[oota-llvm.git] / lib / Target / TargetData.cpp
index 594c33588efc7b7a077022458cbadbed8831e2bf..40b762d8e7392285fdc4b9e90ee1ae613694e8cf 100644 (file)
@@ -1,10 +1,10 @@
 //===-- TargetData.cpp - Data size & alignment routines --------------------==//
-// 
+//
 //                     The LLVM Compiler Infrastructure
 //
 // This file was developed by the LLVM research group and is distributed under
 // the University of Illinois Open Source License. See LICENSE.TXT for details.
-// 
+//
 //===----------------------------------------------------------------------===//
 //
 // This file defines target properties related to datatype size/offset/alignment
@@ -22,6 +22,7 @@
 #include "llvm/Constants.h"
 #include "llvm/Support/GetElementPtrTypeIterator.h"
 #include "llvm/Support/MathExtras.h"
+#include <algorithm>
 using namespace llvm;
 
 // Handle the Pass registration stuff necessary to use TargetData's.
@@ -42,7 +43,7 @@ StructLayout::StructLayout(const StructType *ST, const TargetData &TD) {
   StructSize = 0;
 
   // Loop over each of the elements, placing them in memory...
-  for (StructType::element_iterator TI = ST->element_begin(), 
+  for (StructType::element_iterator TI = ST->element_begin(),
          TE = ST->element_end(); TI != TE; ++TI) {
     const Type *Ty = *TI;
     unsigned char A;
@@ -71,6 +72,22 @@ StructLayout::StructLayout(const StructType *ST, const TargetData &TD) {
     StructSize = (StructSize/StructAlignment + 1) * StructAlignment;
 }
 
+
+/// getElementContainingOffset - Given a valid offset into the structure,
+/// return the structure index that contains it.
+unsigned StructLayout::getElementContainingOffset(uint64_t Offset) const {
+  std::vector<uint64_t>::const_iterator SI =
+    std::upper_bound(MemberOffsets.begin(), MemberOffsets.end(),
+                     Offset);
+  assert(SI != MemberOffsets.begin() && "Offset not in structure type!");
+  --SI;
+  assert(*SI <= Offset && "upper_bound didn't work");
+  assert((SI == MemberOffsets.begin() || *(SI-1) < Offset) &&
+         (SI+1 == MemberOffsets.end() || *(SI+1) > Offset) &&
+         "Upper bound didn't work!");
+  return SI-MemberOffsets.begin();
+}
+
 //===----------------------------------------------------------------------===//
 //                       TargetData Class Implementation
 //===----------------------------------------------------------------------===//
@@ -78,7 +95,7 @@ StructLayout::StructLayout(const StructType *ST, const TargetData &TD) {
 TargetData::TargetData(const std::string &TargetName,
                        bool isLittleEndian, unsigned char PtrSize,
                        unsigned char PtrAl, unsigned char DoubleAl,
-                       unsigned char FloatAl, unsigned char LongAl, 
+                       unsigned char FloatAl, unsigned char LongAl,
                        unsigned char IntAl, unsigned char ShortAl,
                        unsigned char ByteAl, unsigned char BoolAl) {
 
@@ -114,6 +131,9 @@ TargetData::TargetData(const std::string &ToolName, const Module *M) {
   BoolAlignment    = 1;
 }
 
+/// Layouts - The lazy cache of structure layout information maintained by
+/// TargetData.
+///
 static std::map<std::pair<const TargetData*,const StructType*>,
                 StructLayout> *Layouts = 0;
 
@@ -148,6 +168,21 @@ const StructLayout *TargetData::getStructLayout(const StructType *Ty) const {
   }
 }
 
+/// InvalidateStructLayoutInfo - TargetData speculatively caches StructLayout
+/// objects.  If a TargetData object is alive when types are being refined and
+/// removed, this method must be called whenever a StructType is removed to
+/// avoid a dangling pointer in this cache.
+void TargetData::InvalidateStructLayoutInfo(const StructType *Ty) const {
+  if (!Layouts) return;  // No cache.
+
+  std::map<std::pair<const TargetData*,const StructType*>,
+           StructLayout>::iterator I = Layouts->find(std::make_pair(this, Ty));
+  if (I != Layouts->end())
+    Layouts->erase(I);
+}
+
+
+
 static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
                                uint64_t &Size, unsigned char &Alignment) {
   assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
@@ -175,13 +210,20 @@ static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
     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.
     const StructLayout *Layout = TD->getStructLayout(cast<StructType>(Ty));
     Size = Layout->StructSize; Alignment = Layout->StructAlignment;
     return;
   }
-    
+
   default:
     assert(0 && "Bad type for getTypeInfo!!!");
     return;
@@ -205,7 +247,7 @@ unsigned char TargetData::getTypeAlignment(const Type *Ty) const {
 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);
+  return Log2_32(Align);
 }
 
 /// getIntPtrType - Return an unsigned integer type that is the same size or