Correctly extract the ValueType from a VTSDNode.
[oota-llvm.git] / lib / Target / TargetData.cpp
index 2cbb903b96308acbfaed41ed67b5819356c3bdd5..b2d76d841807ce48b46e6b4e720b0e9daada67d4 100644 (file)
@@ -35,6 +35,7 @@ namespace {
   // Register the default SparcV9 implementation...
   RegisterPass<TargetData> X("targetdata", "Target Data Layout");
 }
+char TargetData::ID = 0;
 
 //===----------------------------------------------------------------------===//
 // Support for StructLayout
@@ -145,10 +146,10 @@ const TargetAlignElem TargetData::InvalidAlignmentElem =
  <i>[E|e]</i>: Endianness. "E" specifies a big-endian target data model, "e"
  specifies a little-endian target data model.
  <br><br>
- <i>p:<size>:<abi_align>:<pref_align></i>: Pointer size, ABI and preferred
- alignment.
+ <i>p:@verbatim<size>:<abi_align>:<pref_align>@endverbatim</i>: Pointer size, 
ABI and preferred alignment.
  <br><br>
- <i><type><size>:<abi_align>:<pref_align></i>: Numeric type alignment. Type is
+ <i>@verbatim<type><size>:<abi_align>:<pref_align>@endverbatim</i>: Numeric type alignment. Type is
  one of <i>i|f|v|a</i>, corresponding to integer, floating point, vector (aka
  packed) or aggregate.  Size indicates the size, e.g., 32 or 64 bits.
  \p
@@ -181,7 +182,7 @@ void TargetData::init(const std::string &TargetDescription) {
   setAlignment(VECTOR_ALIGN,    8,  8, 64);  // v2i32
   setAlignment(VECTOR_ALIGN,   16, 16, 128); // v16i8, v8i16, v4i32, ...
   setAlignment(AGGREGATE_ALIGN, 0,  8,  0);  // struct, union, class, ...
-  
+
   while (!temp.empty()) {
     std::string token = getToken(temp, "-");
     std::string arg0 = getToken(token, ":");
@@ -203,10 +204,16 @@ void TargetData::init(const std::string &TargetDescription) {
     case 'i':
     case 'v':
     case 'f':
-    case 'a': {
-      AlignTypeEnum align_type = 
-        (*p == 'i' ? INTEGER_ALIGN : (*p == 'f' ? FLOAT_ALIGN :
-           (*p == 'v' ? VECTOR_ALIGN : AGGREGATE_ALIGN)));
+    case 'a':
+    case 's': {
+      AlignTypeEnum align_type;
+      switch(*p) {
+        case 'i': align_type = INTEGER_ALIGN; break;
+        case 'v': align_type = VECTOR_ALIGN; break;
+        case 'f': align_type = FLOAT_ALIGN; break;
+        case 'a': align_type = AGGREGATE_ALIGN; break;
+        case 's': align_type = STACK_ALIGN; break;
+      }
       uint32_t size = (uint32_t) atoi(++p);
       unsigned char abi_align = atoi(getToken(token, ":").c_str()) / 8;
       unsigned char pref_align = atoi(getToken(token, ":").c_str()) / 8;
@@ -221,7 +228,8 @@ void TargetData::init(const std::string &TargetDescription) {
   }
 }
 
-TargetData::TargetData(const Module *M) {
+TargetData::TargetData(const Module *M) 
+  : ImmutablePass((intptr_t)&ID) {
   init(M->getDataLayout());
 }
 
@@ -307,9 +315,13 @@ struct DenseMapLayoutKeyInfo {
     return LayoutKey((TargetData*)(intptr_t)-1, 0);
   }
   static unsigned getHashValue(const LayoutKey &Val) {
-    return DenseMapKeyInfo<void*>::getHashValue(Val.first) ^
-           DenseMapKeyInfo<void*>::getHashValue(Val.second);
+    return DenseMapInfo<void*>::getHashValue(Val.first) ^
+           DenseMapInfo<void*>::getHashValue(Val.second);
+  }
+  static bool isEqual(const LayoutKey &LHS, const LayoutKey &RHS) {
+    return LHS == RHS;
   }
+
   static bool isPod() { return true; }
 };
 
@@ -434,6 +446,13 @@ uint64_t TargetData::getTypeSize(const Type *Ty) const {
     return 4;
   case Type::DoubleTyID:
     return 8;
+  case Type::PPC_FP128TyID:
+  case Type::FP128TyID:
+    return 16;
+  // In memory objects this is always aligned to a higher boundary, but
+  // only 10 bytes contain information.
+  case Type::X86_FP80TyID:
+    return 10;
   case Type::VectorTyID: {
     const VectorType *PTy = cast<VectorType>(Ty);
     return PTy->getBitWidth() / 8;
@@ -452,7 +471,12 @@ uint64_t TargetData::getTypeSizeInBits(const Type *Ty) const {
     return getTypeSize(Ty) * 8;
 }
 
-
+uint64_t TargetData::getABITypeSizeInBits(const Type *Ty) const {
+  if (Ty->isInteger())
+    return cast<IntegerType>(Ty)->getBitWidth();
+  else
+    return getABITypeSize(Ty) * 8;
+}
 /*!
   \param abi_or_pref Flag that determines which alignment is returned. true
   returns the ABI alignment, false returns the preferred alignment.
@@ -491,6 +515,11 @@ unsigned char TargetData::getAlignment(const Type *Ty, bool abi_or_pref) const {
     break;
   case Type::FloatTyID:
   case Type::DoubleTyID:
+  // PPC_FP128TyID and FP128TyID have different data contents, but the
+  // same size and alignment, so they look the same here.
+  case Type::PPC_FP128TyID:
+  case Type::FP128TyID:
+  case Type::X86_FP80TyID:
     AlignType = FLOAT_ALIGN;
     break;
   case Type::VectorTyID: {
@@ -515,6 +544,14 @@ unsigned char TargetData::getABITypeAlignment(const Type *Ty) const {
   return getAlignment(Ty, true);
 }
 
+unsigned char TargetData::getCallFrameTypeAlignment(const Type *Ty) const {
+  for (unsigned i = 0, e = Alignments.size(); i != e; ++i)
+    if (Alignments[i].AlignType == STACK_ALIGN)
+      return Alignments[i].ABIAlign;
+
+  return getABITypeAlignment(Ty);
+}
+
 unsigned char TargetData::getPrefTypeAlignment(const Type *Ty) const {
   return getAlignment(Ty, false);
 }
@@ -528,12 +565,7 @@ unsigned char TargetData::getPreferredTypeAlignmentShift(const Type *Ty) const {
 /// 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::Int16Ty;
-  case 4: return Type::Int32Ty;
-  case 8: return Type::Int64Ty;
-  }
+  return IntegerType::get(getPointerSizeInBits());
 }