[llvm-commits] [dragonegg] r172106 - in /dragonegg/trunk: src/TypeConversion.cpp test/validator/c/LongDoubleSize.c

Duncan Sands baldrick at free.fr
Thu Jan 10 13:06:46 PST 2013


Author: baldrick
Date: Thu Jan 10 15:06:46 2013
New Revision: 172106

URL: http://llvm.org/viewvc/llvm-project?rev=172106&view=rev
Log:
Add support for -m96bit-long-double and clean up the handling of the memory type
for the C++11 nullptr type at the same time.

Added:
    dragonegg/trunk/test/validator/c/LongDoubleSize.c
Modified:
    dragonegg/trunk/src/TypeConversion.cpp

Modified: dragonegg/trunk/src/TypeConversion.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/src/TypeConversion.cpp?rev=172106&r1=172105&r2=172106&view=diff
==============================================================================
--- dragonegg/trunk/src/TypeConversion.cpp (original)
+++ dragonegg/trunk/src/TypeConversion.cpp Thu Jan 10 15:06:46 2013
@@ -1395,106 +1395,110 @@
   assert(type == TYPE_MAIN_VARIANT(type) && "Not converting the main variant!");
   assert(!mayRecurse(type) && "Expected a non-recursive type!");
 
+  // If we already converted the type, reuse the previous conversion.  Note that
+  // this fires for types which are really recursive, such as pointer types, but
+  // that we don't consider recursive any more because already converted.
+  if (Type *Ty = getCachedType(type))
+    return CheckTypeConversion(type, Ty);
+
+  // Handle the void type early to avoid confusion with incomplete types below.
+  if (isa<VOID_TYPE>(type))
+    return RememberTypeConversion(type, Type::getVoidTy(Context));
+
+  // Return a placeholder if the type is incomplete.
+  if (!TYPE_SIZE(type)) {
+    // Return a byte as the placeholder for incomplete enums.
+    if (isa<ENUMERAL_TYPE>(type))
+      return RememberTypeConversion(type, GetUnitType(Context));
+
+    // Return an opaque struct for an incomplete record type.
+    assert(isa<RECORD_OR_UNION_TYPE>(type) && "Unexpected incomplete type!");
+    return RememberTypeConversion(type,
+                                  StructType::create(Context,
+                                                     getDescriptiveName(type)));
+  }
+
+  // From here on we are only dealing with straightforward types.
+  assert(isSizeCompatible(type) && "Funkily sized types should not get here!");
+  uint64_t SizeInBits = getInt64(TYPE_SIZE(type), true);
+  unsigned AlignInBits = TYPE_ALIGN(type);
+
+  // Convert to the obvious LLVM type.
+  Type *Ty;
   switch (TREE_CODE(type)) {
   default:
     debug_tree(type);
     llvm_unreachable("Unknown or recursive type!");
 
-  case ARRAY_TYPE:
-  case FUNCTION_TYPE:
-  case METHOD_TYPE:
-  case POINTER_TYPE:
-  case REFERENCE_TYPE: {
-    // If these types are not recursive it can only be because they were already
-    // converted and we can safely return the result of the previous conversion.
-    Type *Ty = getCachedType(type);
-    assert(Ty && "Type not already converted!");
-    return CheckTypeConversion(type, Ty);
-  }
+  case BOOLEAN_TYPE:
+  case ENUMERAL_TYPE:
+  case INTEGER_TYPE:
+    Ty = IntegerType::get(Context, SizeInBits);
+    break;
 
   case COMPLEX_TYPE: {
-    if (Type *Ty = getCachedType(type))
-      return CheckTypeConversion(type, Ty);
-    Type *Ty = ConvertTypeNonRecursive(main_type(type));
+    Ty = ConvertTypeNonRecursive(main_type(type));
     Ty = StructType::get(Ty, Ty, NULL);
-    return RememberTypeConversion(type, Ty);
-  }
-
-  case ENUMERAL_TYPE:
-    // If the enum is incomplete return a placeholder type.
-    if (!TYPE_SIZE(type))
-      return CheckTypeConversion(type, GetUnitType(Context));
-    // Otherwise fall through.
-  case BOOLEAN_TYPE:
-  case INTEGER_TYPE: {
-    uint64_t Size = getInt64(TYPE_SIZE(type), true);
-    // Caching the type conversion is not worth it.
-    return CheckTypeConversion(type, IntegerType::get(Context, Size));
+    break;
   }
 
 #if (GCC_MINOR > 5)
-  case NULLPTR_TYPE: {
-    // As NULLPTR_TYPE has an alignment of 1, output it as an array of bytes.
-    // FIXME: Instead we should use a pointer, and have a general mechanism
-    // for using a bunch of bytes instead for any type which is underaligned.
-    uint64_t Units = getInt64(TYPE_SIZE_UNIT(type), true);
-    return CheckTypeConversion(type, GetUnitType(Context, Units));
-  }
+  case NULLPTR_TYPE:
+    Ty = GetUnitPointerType(Context, TYPE_ADDR_SPACE(type));
+    break;
 #endif
 
   case OFFSET_TYPE: {
     // Handle OFFSET_TYPE specially.  This is used for pointers to members,
     // which are really just integer offsets.  Return the appropriate integer
     // type directly.
-    // Caching the type conversion is not worth it.
     unsigned AS = TYPE_ADDR_SPACE(type);
-    return CheckTypeConversion(type, getDataLayout().getIntPtrType(Context, AS));
+    Ty = getDataLayout().getIntPtrType(Context, AS);
+    break;
   }
 
   case REAL_TYPE:
-    // Caching the type conversion is not worth it.
     switch (TYPE_PRECISION(type)) {
     default:
       debug_tree(type);
       llvm_unreachable("Unknown FP type!");
-    case 32: return CheckTypeConversion(type, Type::getFloatTy(Context));
-    case 64: return CheckTypeConversion(type, Type::getDoubleTy(Context));
-    case 80: return CheckTypeConversion(type, Type::getX86_FP80Ty(Context));
+    case 32:
+      Ty = Type::getFloatTy(Context);
+      break;
+    case 64:
+      Ty = Type::getDoubleTy(Context);
+      break;
+    case 80:
+      Ty = Type::getX86_FP80Ty(Context);
+      break;
     case 128:
 #ifdef TARGET_POWERPC
-      return CheckTypeConversion(type, Type::getPPC_FP128Ty(Context));
+      Ty = Type::getPPC_FP128Ty(Context);
 #else
       // IEEE quad precision.
-      return CheckTypeConversion(type, Type::getFP128Ty(Context));
+      Ty = Type::getFP128Ty(Context);
 #endif
+      break;
     }
-
-  case RECORD_TYPE:
-  case QUAL_UNION_TYPE:
-  case UNION_TYPE:
-    // If the type was already converted then return the already computed type.
-    if (Type *Ty = getCachedType(type))
-      return CheckTypeConversion(type, Ty);
-
-    // Otherwise this must be an incomplete type - return an opaque struct.
-    assert(!TYPE_SIZE(type) && "Expected an incomplete type!");
-    return RememberTypeConversion(type,
-                                  StructType::create(Context,
-                                                     getDescriptiveName(type)));
+    break;
 
   case VECTOR_TYPE: {
-    if (Type *Ty = getCachedType(type))
-      return CheckTypeConversion(type, Ty);
     assert(!isa<ACCESS_TYPE>(TREE_TYPE(type)) && "Type not already converted!");
-    Type *Ty = ConvertTypeNonRecursive(main_type(type));
+    Ty = ConvertTypeNonRecursive(main_type(type));
     Ty = VectorType::get(Ty, TYPE_VECTOR_SUBPARTS(type));
-    return RememberTypeConversion(type, Ty);
+    break;
   }
-
-  case VOID_TYPE:
-    // Caching the type conversion is not worth it.
-    return CheckTypeConversion(type, Type::getVoidTy(Context));
   }
+
+  // If the LLVM type we chose has the wrong size or is overaligned then use a
+  // bunch of bytes instead.
+  assert(Ty->isSized() && "Must convert to a sized type!");
+  uint64_t LLVMSizeInBits = getDataLayout().getTypeAllocSizeInBits(Ty);
+  unsigned LLVMAlignInBits = getDataLayout().getABITypeAlignment(Ty) * 8;
+  if (LLVMSizeInBits != SizeInBits || LLVMAlignInBits > AlignInBits)
+    Ty = GetUnitType(Context, SizeInBits / BITS_PER_UNIT);
+
+  return RememberTypeConversion(type, Ty);
 }
 
 /// RecursiveTypeIterator - A convenience class that visits only those nodes

Added: dragonegg/trunk/test/validator/c/LongDoubleSize.c
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/test/validator/c/LongDoubleSize.c?rev=172106&view=auto
==============================================================================
--- dragonegg/trunk/test/validator/c/LongDoubleSize.c (added)
+++ dragonegg/trunk/test/validator/c/LongDoubleSize.c Thu Jan 10 15:06:46 2013
@@ -0,0 +1,4 @@
+// RUN: %dragonegg -S %s
+// RUN: %dragonegg -S %s -m96bit-long-double
+// RUN: %dragonegg -S %s -m128bit-long-double
+long double d;





More information about the llvm-commits mailing list