Author: dpatel Date: Mon Jan 21 16:19:26 2008 New Revision: 46221 URL: http://llvm.org/viewvc/llvm-project?rev=46221&view=rev Log: Instead of converting llvm struct as packed llvm struct on the fly (through converToPacked()), redecode struct fields again after marking struct as packed struct.
This fixes http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20080121/057406.html Modified: llvm-gcc-4.2/trunk/gcc/llvm-internal.h llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-internal.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-internal.h?rev=46221&r1=46220&r2=46221&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-internal.h (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-internal.h Mon Jan 21 16:19:26 2008 @@ -172,7 +172,7 @@ const Type *ConvertRECORD(tree_node *type, tree_node *orig_type); const Type *ConvertUNION(tree_node *type, tree_node *orig_type); void SetFieldIndex(tree_node *field_decl, unsigned int Index); - void DecodeStructFields(tree_node *Field, StructTypeConversionInfo &Info); + bool DecodeStructFields(tree_node *Field, StructTypeConversionInfo &Info); void DecodeStructBitField(tree_node *Field, StructTypeConversionInfo &Info); }; Modified: llvm-gcc-4.2/trunk/gcc/llvm-types.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-types.cpp?rev=46221&r1=46220&r2=46221&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-types.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Mon Jan 21 16:19:26 2008 @@ -1509,37 +1509,9 @@ void addNewBitField(unsigned Size, unsigned FirstUnallocatedByte); - void convertToPacked(); - void dump() const; }; -// LLVM disagrees as to where to put field natural field ordering. -// ordering. Therefore convert to a packed struct. -void StructTypeConversionInfo::convertToPacked() { - assert (!Packed && "Packing a packed struct!"); - Packed = true; - - // Fill the padding that existed from alignment restrictions - // with byte arrays to ensure the same layout when converting - // to a packed struct. - for (unsigned x = 1; x < ElementOffsetInBytes.size(); ++x) { - if (ElementOffsetInBytes[x-1] + ElementSizeInBytes[x-1] - < ElementOffsetInBytes[x]) { - uint64_t padding = ElementOffsetInBytes[x] - - ElementOffsetInBytes[x-1] - ElementSizeInBytes[x-1]; - const Type *Pad = Type::Int8Ty; - Pad = ArrayType::get(Pad, padding); - ElementOffsetInBytes.insert(ElementOffsetInBytes.begin() + x, - ElementOffsetInBytes[x-1] + - ElementSizeInBytes[x-1]); - ElementSizeInBytes.insert(ElementSizeInBytes.begin() + x, padding); - Elements.insert(Elements.begin() + x, Pad); - PaddingElement.insert(PaddingElement.begin() + x, true); - } - } -} - // Add new element which is a bit field. Size is not the size of bit filed, // but size of bits required to determine type of new Field which will be // used to access this bit field. @@ -1765,17 +1737,18 @@ /// DecodeStructFields - This method decodes the specified field, if it is a /// FIELD_DECL, adding or updating the specified StructTypeConversionInfo to -/// reflect it. -void TypeConverter::DecodeStructFields(tree Field, +/// reflect it. Return tree if field is decoded correctly. Otherwise return +/// false. +bool TypeConverter::DecodeStructFields(tree Field, StructTypeConversionInfo &Info) { if (TREE_CODE(Field) != FIELD_DECL || TREE_CODE(DECL_FIELD_OFFSET(Field)) != INTEGER_CST) - return; + return true; // Handle bit-fields specially. if (isBitfield(Field)) { DecodeStructBitField(Field, Info); - return; + return true; } Info.allFieldsAreNotBitFields(); @@ -1793,20 +1766,19 @@ if (!Info.ResizeLastElementIfOverlapsWith(StartOffsetInBytes, Field, Ty)) { // LLVM disagrees as to where this field should go in the natural field // ordering. Therefore convert to a packed struct and try again. - Info.convertToPacked(); - DecodeStructFields(Field, Info); + return false; } else if (TYPE_USER_ALIGN(TREE_TYPE(Field)) && DECL_ALIGN_UNIT(Field) != Info.getTypeAlignment(Ty) && !Info.isPacked()) { // If Field has user defined alignment and it does not match Ty alignment // then convert to a packed struct and try again. - Info.convertToPacked(); - DecodeStructFields(Field, Info); + return false; } else // At this point, we know that adding the element will happen at the right // offset. Add it. Info.addElement(Ty, StartOffsetInBytes, Info.getTypeSize(Ty)); + return true; } /// DecodeStructBitField - This method decodes the specified bit-field, adding @@ -1984,8 +1956,24 @@ FixBaseClassFields(type); // Convert over all of the elements of the struct. - for (tree Field = TYPE_FIELDS(type); Field; Field = TREE_CHAIN(Field)) - DecodeStructFields(Field, *Info); + bool retryAsPackedStruct = false; + for (tree Field = TYPE_FIELDS(type); Field; Field = TREE_CHAIN(Field)) { + if (DecodeStructFields(Field, *Info) == false) { + retryAsPackedStruct = true; + break; + } + } + + if (retryAsPackedStruct) { + delete Info; + Info = new StructTypeConversionInfo(*TheTarget, TYPE_ALIGN_UNIT(type), + true); + for (tree Field = TYPE_FIELDS(type); Field; Field = TREE_CHAIN(Field)) { + if (DecodeStructFields(Field, *Info) == false) { + assert(0 && "Unable to decode struct fields."); + } + } + } // If the LLVM struct requires explicit tail padding to be the same size as // the GCC struct, insert tail padding now. This handles, e.g., "{}" in C++. _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits