[llvm-commits] [dragonegg] r151937 - in /dragonegg/trunk: include/dragonegg/Constants.h include/dragonegg/Trees.h include/dragonegg/Types.h src/Constants.cpp src/Debug.cpp src/Types.cpp test/compilator/local/UnderAligned.ii

Duncan Sands baldrick at free.fr
Fri Mar 2 13:01:32 PST 2012


Author: baldrick
Date: Fri Mar  2 15:01:32 2012
New Revision: 151937

URL: http://llvm.org/viewvc/llvm-project?rev=151937&view=rev
Log:
Be more consistent in using the main variant of types, in particular only look
at the main variant when converting constants.  This should fix the x86-64
gcc-4.5 self-host builder, where an assertion was firing because the type
conversion logic was using the main variant, but constant conversion was using
the original type.

Added:
    dragonegg/trunk/test/compilator/local/UnderAligned.ii
Modified:
    dragonegg/trunk/include/dragonegg/Constants.h
    dragonegg/trunk/include/dragonegg/Trees.h
    dragonegg/trunk/include/dragonegg/Types.h
    dragonegg/trunk/src/Constants.cpp
    dragonegg/trunk/src/Debug.cpp
    dragonegg/trunk/src/Types.cpp

Modified: dragonegg/trunk/include/dragonegg/Constants.h
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/include/dragonegg/Constants.h?rev=151937&r1=151936&r2=151937&view=diff
==============================================================================
--- dragonegg/trunk/include/dragonegg/Constants.h (original)
+++ dragonegg/trunk/include/dragonegg/Constants.h Fri Mar  2 15:01:32 2012
@@ -42,11 +42,12 @@
 /// equivalent LLVM constant.  Also handles constant constructors.  The type of
 /// the returned value may be pretty much anything.  All that is guaranteed is
 /// that its alloc size is equal to the size of the initial value and that its
-/// alignment is less than or equal to the initial value's GCC type alignment.
-/// Note that the GCC type may have variable size or no size, in which case the
-/// size is determined by the initial value.  When this happens the size of the
-/// initial value may exceed the alloc size of the LLVM memory type generated
-/// for the GCC type (see ConvertType); it is never smaller than the alloc size.
+/// alignment is less than or equal to the initial value's GCC type alignment
+/// (here the GCC type means the main variant).  Note that the GCC type may have
+/// variable size or no size in which case the size is determined by the initial
+/// value.  When this happens the size of the initial value may exceed the alloc
+/// size of the LLVM memory type generated for the GCC type (see ConvertType);
+/// it is never smaller than the alloc size.
 extern llvm::Constant *ConvertInitializer(tree_node *exp);
 
 /// ExtractRegisterFromConstant - Extract a value of the given scalar GCC type

Modified: dragonegg/trunk/include/dragonegg/Trees.h
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/include/dragonegg/Trees.h?rev=151937&r1=151936&r2=151937&view=diff
==============================================================================
--- dragonegg/trunk/include/dragonegg/Trees.h (original)
+++ dragonegg/trunk/include/dragonegg/Trees.h Fri Mar  2 15:01:32 2012
@@ -37,6 +37,11 @@
 /// more readable, and have no official status.
 std::string getDescriptiveName(tree t);
 
+/// main_type - Return the main variant of the given tree's type.
+inline tree main_type(tree exp) {
+  return TYPE_MAIN_VARIANT(TREE_TYPE(exp));
+}
+
 /// hasNUW - Return whether overflowing unsigned operations on this type result
 /// in undefined behaviour.
 inline bool hasNUW(tree type) {

Modified: dragonegg/trunk/include/dragonegg/Types.h
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/include/dragonegg/Types.h?rev=151937&r1=151936&r2=151937&view=diff
==============================================================================
--- dragonegg/trunk/include/dragonegg/Types.h (original)
+++ dragonegg/trunk/include/dragonegg/Types.h Fri Mar  2 15:01:32 2012
@@ -72,7 +72,8 @@
 
 /// getRegType - Returns the LLVM type to use for registers that hold a value
 /// of the scalar GCC type 'type'.  All of the EmitReg* routines use this to
-/// determine the LLVM type to return.
+/// determine the LLVM type to return.  Note that this only considers the main
+/// variant of the type.
 extern llvm::Type *getRegType(tree_node *type);
 
 /// getPointerToType - Returns the LLVM register type to use for a pointer to
@@ -81,6 +82,7 @@
 
 /// ConvertType - Returns the LLVM type to use for memory that holds a value
 /// of the given GCC type (getRegType should be used for values in registers).
+/// Note that the conversion only considers the main variant of the type.
 extern llvm::Type *ConvertType(tree_node *type);
 
 /// ConvertFunctionType - Convert the specified FUNCTION_TYPE or METHOD_TYPE

Modified: dragonegg/trunk/src/Constants.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/src/Constants.cpp?rev=151937&r1=151936&r2=151937&view=diff
==============================================================================
--- dragonegg/trunk/src/Constants.cpp (original)
+++ dragonegg/trunk/src/Constants.cpp Fri Mar  2 15:01:32 2012
@@ -526,7 +526,7 @@
   }
 
   case COMPLEX_TYPE: {
-    tree elt_type = TREE_TYPE(type);
+    tree elt_type = main_type(type);
     unsigned Stride = GET_MODE_BITSIZE(TYPE_MODE(elt_type));
     Constant *Vals[2] = {
       ExtractRegisterFromConstantImpl(C, elt_type, StartingBit, Folder),
@@ -546,7 +546,7 @@
     return InterpretAsType(C, getRegType(type), StartingBit, Folder);
 
   case VECTOR_TYPE: {
-    tree elt_type = TREE_TYPE(type);
+    tree elt_type = main_type(type);
     unsigned NumElts = TYPE_VECTOR_SUBPARTS(type);
     unsigned Stride = GET_MODE_BITSIZE(TYPE_MODE(elt_type));
     SmallVector<Constant*, 16> Vals(NumElts);
@@ -584,7 +584,7 @@
 /// register type.
 static Constant *getAsRegister(tree exp, TargetFolder &Folder) {
   Constant *C = ConvertInitializerImpl(exp, Folder);
-  return ExtractRegisterFromConstantImpl(C, TREE_TYPE(exp), 0, Folder);
+  return ExtractRegisterFromConstantImpl(C, main_type(exp), 0, Folder);
 }
 
 /// RepresentAsMemory - Turn a constant of in-register type (corresponding
@@ -619,7 +619,7 @@
   }
 
   case COMPLEX_TYPE: {
-    tree elt_type = TREE_TYPE(type);
+    tree elt_type = main_type(type);
     unsigned Idx[2] = {0, 1};
     Constant *Real = Folder.CreateExtractValue(C, Idx[0]);
     Constant *Imag = Folder.CreateExtractValue(C, Idx[1]);
@@ -645,7 +645,7 @@
     break;
 
   case VECTOR_TYPE: {
-    tree elt_type = TREE_TYPE(type);
+    tree elt_type = main_type(type);
     unsigned NumElts = TYPE_VECTOR_SUBPARTS(type);
     std::vector<Constant*> Vals(NumElts);
     for (unsigned i = 0; i != NumElts; ++i) {
@@ -703,7 +703,7 @@
   // that would not perform a value extension (adding extra zeros or sign bits
   // when casting to a larger integer type for example): any extra bits would
   // wrongly get an undefined value instead.
-  C = ExtractRegisterFromConstantImpl(C, TREE_TYPE(exp), 0, Folder);
+  C = ExtractRegisterFromConstantImpl(C, main_type(exp), 0, Folder);
 
   // Cast to the desired type.
   bool SrcIsSigned = !TYPE_UNSIGNED(TREE_TYPE(exp));
@@ -718,7 +718,7 @@
 /// ConvertCST - Return the given simple constant as an array of bytes.  For the
 /// moment only INTEGER_CST, REAL_CST, COMPLEX_CST and VECTOR_CST are supported.
 static Constant *ConvertCST(tree exp, TargetFolder &) {
-  const tree type = TREE_TYPE(exp);
+  const tree type = main_type(exp);
   unsigned SizeInChars = (TREE_INT_CST_LOW(TYPE_SIZE(type)) + CHAR_BIT - 1) /
     CHAR_BIT;
   // Encode the constant in Buffer in target format.
@@ -777,13 +777,13 @@
   }
 
   unsigned LenInElts = Len /
-          TREE_INT_CST_LOW(TYPE_SIZE_UNIT(TREE_TYPE(TREE_TYPE(exp))));
+          TREE_INT_CST_LOW(TYPE_SIZE_UNIT(main_type(main_type(exp))));
   unsigned ConstantSize = StrTy->getNumElements();
 
   if (LenInElts != ConstantSize) {
     // If this is a variable sized array type, set the length to LenInElts.
     if (ConstantSize == 0) {
-      tree Domain = TYPE_DOMAIN(TREE_TYPE(exp));
+      tree Domain = TYPE_DOMAIN(main_type(exp));
       if (!Domain || !TYPE_MAX_VALUE(Domain)) {
         ConstantSize = LenInElts;
         StrTy = ArrayType::get(ElTy, LenInElts);
@@ -811,10 +811,10 @@
 static Constant *ConvertArrayCONSTRUCTOR(tree exp, TargetFolder &Folder) {
   const TargetData &TD = getTargetData();
 
-  tree init_type = TREE_TYPE(exp);
+  tree init_type = main_type(exp);
   Type *InitTy = ConvertType(init_type);
 
-  tree elt_type = TREE_TYPE(init_type);
+  tree elt_type = main_type(init_type);
   Type *EltTy = ConvertType(elt_type);
 
   // Check that the element type has a known, constant size.
@@ -875,8 +875,8 @@
 
       // Subtract off the lower bound if any to ensure indices start from zero.
       if (lower_bnd != NULL_TREE) {
-        first = fold_build2(MINUS_EXPR, TREE_TYPE(first), first, lower_bnd);
-        last = fold_build2(MINUS_EXPR, TREE_TYPE(last), last, lower_bnd);
+        first = fold_build2(MINUS_EXPR, main_type(first), first, lower_bnd);
+        last = fold_build2(MINUS_EXPR, main_type(last), last, lower_bnd);
       }
 
       assert(host_integerp(first, 1) && host_integerp(last, 1) &&
@@ -886,7 +886,7 @@
     } else {
       // Subtract off the lower bound if any to ensure indices start from zero.
       if (lower_bnd != NULL_TREE)
-        index = fold_build2(MINUS_EXPR, TREE_TYPE(index), index, lower_bnd);
+        index = fold_build2(MINUS_EXPR, main_type(index), index, lower_bnd);
       assert(host_integerp(index, 1));
       FirstIndex = tree_low_cst(index, 1);
       LastIndex = FirstIndex;
@@ -940,7 +940,7 @@
   // If any elements are more aligned than the GCC type then we need to return a
   // packed struct.  This can happen if the user forced a small alignment on the
   // array type.
-  if (MaxAlign * 8 > TYPE_ALIGN(TREE_TYPE(exp)))
+  if (MaxAlign * 8 > TYPE_ALIGN(main_type(exp)))
     return ConstantStruct::getAnon(Context, Elts, /*Packed*/true);
 
   // Return as a struct if the contents are not homogeneous.
@@ -1128,7 +1128,7 @@
   // and probably wrong on big-endian machines.
   IntervalList<FieldContents, int, 8> Layout;
   const TargetData &TD = getTargetData();
-  tree type = TREE_TYPE(exp);
+  tree type = main_type(exp);
   Type *Ty = ConvertType(type);
   uint64_t TypeSize = TD.getTypeAllocSizeInBits(Ty);
 
@@ -1210,7 +1210,7 @@
     assert(TREE_CODE(field) == FIELD_DECL && "Initial value not for a field!");
     assert(OffsetIsLLVMCompatible(field) && "Field position not known!");
     // Turn the initial value for this field into an LLVM constant.
-    Constant *Init = ConvertInitializerWithCast(value, TREE_TYPE(field),
+    Constant *Init = ConvertInitializerWithCast(value, main_type(field),
                                                 Folder);
     // Work out the range of bits occupied by the field.
     uint64_t FirstBit = getFieldOffsetInBits(field);
@@ -1345,13 +1345,13 @@
 static Constant *ConvertMINUS_EXPR(tree exp, TargetFolder &Folder) {
   Constant *LHS = getAsRegister(TREE_OPERAND(exp, 0), Folder);
   Constant *RHS = getAsRegister(TREE_OPERAND(exp, 1), Folder);
-  return RepresentAsMemory(Folder.CreateSub(LHS, RHS), TREE_TYPE(exp), Folder);
+  return RepresentAsMemory(Folder.CreateSub(LHS, RHS), main_type(exp), Folder);
 }
 
 static Constant *ConvertPLUS_EXPR(tree exp, TargetFolder &Folder) {
   Constant *LHS = getAsRegister(TREE_OPERAND(exp, 0), Folder);
   Constant *RHS = getAsRegister(TREE_OPERAND(exp, 1), Folder);
-  return RepresentAsMemory(Folder.CreateAdd(LHS, RHS), TREE_TYPE(exp), Folder);
+  return RepresentAsMemory(Folder.CreateAdd(LHS, RHS), main_type(exp), Folder);
 }
 
 static Constant *ConvertPOINTER_PLUS_EXPR(tree exp, TargetFolder &Folder) {
@@ -1367,7 +1367,7 @@
   // The result may be of a different pointer type.
   Result = Folder.CreateBitCast(Result, getRegType(TREE_TYPE(exp)));
 
-  return RepresentAsMemory(Result, TREE_TYPE(exp), Folder);
+  return RepresentAsMemory(Result, main_type(exp), Folder);
 }
 
 static Constant *ConvertVIEW_CONVERT_EXPR(tree exp, TargetFolder &Folder) {
@@ -1404,7 +1404,7 @@
     break;
   case CONVERT_EXPR:
   case NOP_EXPR:
-    Init = ConvertInitializerWithCast(TREE_OPERAND(exp, 0), TREE_TYPE(exp),
+    Init = ConvertInitializerWithCast(TREE_OPERAND(exp, 0), main_type(exp),
                                       Folder);
     break;
   case MINUS_EXPR:
@@ -1437,11 +1437,11 @@
     uint64_t TypeSize = getTargetData().getTypeAllocSizeInBits(Ty);
     if (InitSize < TypeSize)
       DieAbjectly("Constant too small for type!", exp);
-    if (isInt64(TREE_TYPE(exp), true) && InitSize != TypeSize)
+    if (isInt64(main_type(exp), true) && InitSize != TypeSize)
       DieAbjectly("Constant too big for type!", exp);
   }
   if (getTargetData().getABITypeAlignment(Init->getType()) * 8 >
-      TYPE_ALIGN(TREE_TYPE(exp)))
+      TYPE_ALIGN(main_type(exp)))
     DieAbjectly("Constant over aligned!", exp);
 #endif
 
@@ -1485,7 +1485,7 @@
   // Create a new global variable.
   Slot = new GlobalVariable(*TheModule, Init->getType(), true,
                             GlobalVariable::LinkerPrivateLinkage, Init, ".cst");
-  unsigned align = TYPE_ALIGN(TREE_TYPE(exp));
+  unsigned align = TYPE_ALIGN(main_type(exp));
 #ifdef CONSTANT_ALIGNMENT
   align = CONSTANT_ALIGNMENT(exp, align);
 #endif
@@ -1502,11 +1502,11 @@
 static Constant *AddressOfARRAY_REF(tree exp, TargetFolder &Folder) {
   tree array = TREE_OPERAND(exp, 0);
   tree index = TREE_OPERAND(exp, 1);
-  tree index_type = TREE_TYPE(index);
+  tree index_type = main_type(index);
   assert(TREE_CODE(TREE_TYPE(array)) == ARRAY_TYPE && "Unknown ARRAY_REF!");
 
   // Check for variable sized reference.
-  assert(isSizeCompatible(TREE_TYPE(TREE_TYPE(array))) &&
+  assert(isSizeCompatible(main_type(main_type(array))) &&
          "Global with variable size?");
 
   // Get the index into the array as an LLVM integer constant.
@@ -1524,7 +1524,7 @@
   // Avoid any assumptions about how the array type is represented in LLVM by
   // doing the GEP on a pointer to the first array element.
   Constant *ArrayAddr = AddressOfImpl(array, Folder);
-  Type *EltTy = ConvertType(TREE_TYPE(TREE_TYPE(array)));
+  Type *EltTy = ConvertType(main_type(main_type(array)));
   ArrayAddr = Folder.CreateBitCast(ArrayAddr, EltTy->getPointerTo());
 
   return POINTER_TYPE_OVERFLOW_UNDEFINED ?

Modified: dragonegg/trunk/src/Debug.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/src/Debug.cpp?rev=151937&r1=151936&r2=151937&view=diff
==============================================================================
--- dragonegg/trunk/src/Debug.cpp (original)
+++ dragonegg/trunk/src/Debug.cpp Fri Mar  2 15:01:32 2012
@@ -503,10 +503,8 @@
   if (TREE_CODE (arg_type) != POINTER_TYPE) return false;
   if (TREE_TYPE (arg_type) == TYPE_METHOD_BASETYPE (method_type))
     return true;
-  if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_type))
-      && TYPE_MAIN_VARIANT (TREE_TYPE (arg_type)) != TREE_TYPE (arg_type)
-      && (TYPE_MAIN_VARIANT (TREE_TYPE (arg_type))
-          == TYPE_METHOD_BASETYPE (method_type)))
+  if (main_type (arg_type) && main_type (arg_type) != TREE_TYPE (arg_type)
+      && (main_type (arg_type) == TYPE_METHOD_BASETYPE (method_type)))
     return true;
   return false;
 }

Modified: dragonegg/trunk/src/Types.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/src/Types.cpp?rev=151937&r1=151936&r2=151937&view=diff
==============================================================================
--- dragonegg/trunk/src/Types.cpp (original)
+++ dragonegg/trunk/src/Types.cpp Fri Mar  2 15:01:32 2012
@@ -415,6 +415,9 @@
 /// of the scalar GCC type 'type'.  All of the EmitReg* routines use this to
 /// determine the LLVM type to return.
 Type *getRegType(tree type) {
+  // LLVM doesn't care about variants such as const, volatile, or restrict.
+  type = TYPE_MAIN_VARIANT(type);
+
   // NOTE: Any changes made here need to be reflected in LoadRegisterFromMemory,
   // StoreRegisterToMemory and ExtractRegisterFromConstant.
   assert(!AGGREGATE_TYPE_P(type) && "Registers must have a scalar type!");
@@ -490,7 +493,7 @@
   Type *Ty = ArrayType::get(ElementTy, NumElements);
 
   // If the array is underaligned, wrap it in a packed struct.
-  if (TYPE_ALIGN(type) < TYPE_ALIGN(TYPE_MAIN_VARIANT(TREE_TYPE(type))))
+  if (TYPE_ALIGN(type) < TYPE_ALIGN(main_type(type)))
     Ty = StructType::get(Context, Ty, /*isPacked*/ true);
 
   // If the user increased the alignment of the array element type, then the
@@ -889,7 +892,7 @@
   // This is where self-recursion loops are broken, by not converting the type
   // pointed to if this would cause trouble (the pointer type is turned into
   // {}* instead).
-  tree pointee = TYPE_MAIN_VARIANT(TREE_TYPE(type));
+  tree pointee = main_type(type);
 
   // The pointer type is in the strongly connected component (SCC) currently
   // being converted.  Check whether the pointee is as well.  If there is more
@@ -924,7 +927,7 @@
     // Drill down through nested arrays to the ultimate element type.  Thanks
     // to this we may return S* for a (S[])*, which is better than {}*.
     while (TREE_CODE(pointee) == ARRAY_TYPE)
-      pointee = TYPE_MAIN_VARIANT(TREE_TYPE(pointee));
+      pointee = main_type(pointee);
 
     // If the pointee is a record or union type then return a pointer to its
     // placeholder type.  Otherwise return {}*.
@@ -1363,7 +1366,7 @@
 
   case COMPLEX_TYPE: {
     if (Type *Ty = getCachedType(type)) return Ty;
-    Type *Ty = ConvertTypeNonRecursive(TYPE_MAIN_VARIANT(TREE_TYPE(type)));
+    Type *Ty = ConvertTypeNonRecursive(main_type(type));
     Ty = StructType::get(Ty, Ty, NULL);
     return RememberTypeConversion(type, Ty);
   }
@@ -1413,7 +1416,7 @@
     if (POINTER_TYPE_P(TREE_TYPE(type)))
       Ty = getTargetData().getIntPtrType(Context);
     else
-      Ty = ConvertTypeNonRecursive(TYPE_MAIN_VARIANT(TREE_TYPE(type)));
+      Ty = ConvertTypeNonRecursive(main_type(type));
     Ty = VectorType::get(Ty, TYPE_VECTOR_SUBPARTS(type));
     return RememberTypeConversion(type, Ty);
   }
@@ -1591,7 +1594,7 @@
       for (size_t i = 0, e = SCC.size(); i != e; ++i) {
         tree some_type = SCC[i];
         if (POINTER_TYPE_P(some_type)) {
-          tree pointee = TYPE_MAIN_VARIANT(TREE_TYPE(some_type));
+          tree pointee = main_type(some_type);
           // The pointee cannot have void type since the SCC contains more than
           // one type.
           assert(!VOID_TYPE_P(pointee) && "Self-recursive void*!");

Added: dragonegg/trunk/test/compilator/local/UnderAligned.ii
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/test/compilator/local/UnderAligned.ii?rev=151937&view=auto
==============================================================================
--- dragonegg/trunk/test/compilator/local/UnderAligned.ii (added)
+++ dragonegg/trunk/test/compilator/local/UnderAligned.ii Fri Mar  2 15:01:32 2012
@@ -0,0 +1,26 @@
+typedef long unsigned int size_t;
+extern "C" {
+extern void *memcpy (void *__restrict __dest,
+       __const void *__restrict __src, size_t __n)
+     throw () __attribute__ ((__nonnull__ (1, 2)));
+}
+typedef unsigned long int uint64_t;
+inline uint64_t fetch64(const char *p) {
+  uint64_t result;
+  memcpy(&result, p, sizeof(result));
+  return result;
+}
+const uint64_t bigarr[] = {
+  0xaaaaaaaaababababULL, 0xacacacacbcbcbcbcULL, 0xccddeeffeeddccbbULL,
+  0xdeadbeafdeadbeefULL, 0xfefefefededededeULL, 0xafafafafededededULL,
+  0xffffeeeeddddccccULL, 0xaaaacbcbffffababULL,
+  0xaaaaaaaaababababULL, 0xacacacacbcbcbcbcULL, 0xccddeeffeeddccbbULL,
+  0xdeadbeafdeadbeefULL, 0xfefefefededededeULL, 0xafafafafededededULL,
+  0xffffeeeeddddccccULL, 0xaaaacbcbffffababULL,
+  0xaaaaaaaaababababULL, 0xacacacacbcbcbcbcULL, 0xccddeeffeeddccbbULL,
+  0xdeadbeafdeadbeefULL, 0xfefefefededededeULL, 0xafafafafededededULL,
+  0xffffeeeeddddccccULL, 0xaaaacbcbffffababULL
+};
+const uint64_t *M() {
+  return &bigarr[0];
+}





More information about the llvm-commits mailing list