Revision: 126997 Author: dpatel Date: 2007-05-07 23:15:09 -0700 (Mon, 07 May 2007)
Log Message: ----------- Fix PR1278. - While adding padding elements at the end of LLVM struct use an array of i32 (instead of an array of i8) if possible. - Keep track of padding elements at the end of LLVM struct. Do not copy them while copying aggregates. Modified Paths: -------------- apple-local/branches/llvm/gcc/llvm-convert.cpp apple-local/branches/llvm/gcc/llvm-internal.h apple-local/branches/llvm/gcc/llvm-types.cpp Modified: apple-local/branches/llvm/gcc/llvm-convert.cpp =================================================================== --- apple-local/branches/llvm/gcc/llvm-convert.cpp 2007-05-08 05:09:41 UTC (rev 126996) +++ apple-local/branches/llvm/gcc/llvm-convert.cpp 2007-05-08 06:15:09 UTC (rev 126997) @@ -1085,6 +1085,8 @@ } else if (const StructType *STy = dyn_cast<StructType>(ElTy)) { Constant *Zero = ConstantInt::get(Type::Int32Ty, 0); for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { + if (isPaddingElement(STy, i)) + continue; Constant *Idx = ConstantInt::get(Type::Int32Ty, i); Value *DElPtr = new GetElementPtrInst(DestPtr, Zero, Idx, "tmp", CurBB); Value *SElPtr = new GetElementPtrInst(SrcPtr, Zero, Idx, "tmp", CurBB); Modified: apple-local/branches/llvm/gcc/llvm-internal.h =================================================================== --- apple-local/branches/llvm/gcc/llvm-internal.h 2007-05-08 05:09:41 UTC (rev 126996) +++ apple-local/branches/llvm/gcc/llvm-internal.h 2007-05-08 06:15:09 UTC (rev 126997) @@ -96,6 +96,10 @@ struct StructTypeConversionInfo; +/// Return true if and only if field no. N from struct type T is a padding +/// element added to match llvm struct type size and gcc struct type size. +bool isPaddingElement(const Type *T, unsigned N); + /// TypeConverter - Implement the converter from GCC types to LLVM types. /// class TypeConverter { Modified: apple-local/branches/llvm/gcc/llvm-types.cpp =================================================================== --- apple-local/branches/llvm/gcc/llvm-types.cpp 2007-05-08 05:09:41 UTC (rev 126996) +++ apple-local/branches/llvm/gcc/llvm-types.cpp 2007-05-08 06:15:09 UTC (rev 126997) @@ -893,6 +893,7 @@ std::vector<const Type*> Elements; std::vector<uint64_t> ElementOffsetInBytes; std::vector<uint64_t> ElementSizeInBytes; + std::vector<bool> PaddingElement; // True if field is used for padding const TargetData &TD; unsigned GCCStructAlignmentInBytes; bool Packed; // True if struct is packed @@ -1071,10 +1072,12 @@ /// addElement - Add an element to the structure with the specified type, /// offset and size. - void addElement(const Type *Ty, uint64_t Offset, uint64_t Size) { + void addElement(const Type *Ty, uint64_t Offset, uint64_t Size, + bool ExtraPadding = false) { Elements.push_back(Ty); ElementOffsetInBytes.push_back(Offset); ElementSizeInBytes.push_back(Size); + PaddingElement.push_back(ExtraPadding); lastFieldStartsAtNonByteBoundry(false); ExtraBitsAvailable = 0; } @@ -1223,7 +1226,25 @@ } } +std::map<const Type *, StructTypeConversionInfo *> StructTypeInfoMap; +/// Return true if and only if field no. N from struct type T is a padding +/// element added to match llvm struct type size and gcc struct type size. +bool isPaddingElement(const Type *Ty, unsigned index) { + + StructTypeConversionInfo *Info = StructTypeInfoMap[Ty]; + + // If info is not available then be conservative and return false. + if (!Info) + return false; + + assert ( Info->Elements.size() == Info->PaddingElement.size() + && "Invalid StructTypeConversionInfo"); + assert ( index < Info->PaddingElement.size() + && "Invalid PaddingElement index"); + return Info->PaddingElement[index]; +} + /// getFieldOffsetInBits - Return the offset (in bits) of a FIELD_DECL in a /// structure. static unsigned getFieldOffsetInBits(tree Field) { @@ -1417,29 +1438,46 @@ ConvertType(BINFO_TYPE(BINFO_BASE_BINFO(binfo, i))); } - StructTypeConversionInfo Info(*TheTarget, TYPE_ALIGN_UNIT(type), - TYPE_PACKED(type)); + StructTypeConversionInfo *Info = + new StructTypeConversionInfo(*TheTarget, TYPE_ALIGN_UNIT(type), + TYPE_PACKED(type)); + // Convert over all of the elements of the struct. for (tree Field = TYPE_FIELDS(type); Field; Field = TREE_CHAIN(Field)) - DecodeStructFields(Field, Info); + DecodeStructFields(Field, *Info); - Info.RemoveExtraBytes(); + Info->RemoveExtraBytes(); // 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++. if (TYPE_SIZE(type) && TREE_CODE(TYPE_SIZE(type)) == INTEGER_CST) { - uint64_t LLVMStructSize = Info.getSizeAsLLVMStruct(); + uint64_t LLVMStructSize = Info->getSizeAsLLVMStruct(); uint64_t GCCTypeSize = ((uint64_t)TREE_INT_CST_LOW(TYPE_SIZE(type))+7)/8; if (LLVMStructSize != GCCTypeSize) { assert(LLVMStructSize < GCCTypeSize && "LLVM type size doesn't match GCC type size!"); - uint64_t LLVMLastElementEnd = Info.getNewElementByteOffset(1); - const Type *PadTy = Type::Int8Ty; - if (GCCTypeSize-LLVMLastElementEnd != 1) - PadTy = ArrayType::get(PadTy, GCCTypeSize-LLVMStructSize); - Info.addElement(PadTy, GCCTypeSize-LLVMLastElementEnd, - GCCTypeSize-LLVMLastElementEnd); + uint64_t LLVMLastElementEnd = Info->getNewElementByteOffset(1); + + // If only one byte is needed then insert i8. + if (GCCTypeSize-LLVMLastElementEnd == 1) + Info->addElement(Type::Int8Ty, 1, 1); + else { + if ( ((GCCTypeSize-LLVMStructSize) % 4) == 0) { + // insert array of i32 + unsigned Int32ArraySize = (GCCTypeSize-LLVMStructSize)/4; + const Type *PadTy = ArrayType::get(Type::Int32Ty, Int32ArraySize); + Info->addElement(PadTy, GCCTypeSize - LLVMLastElementEnd, + Int32ArraySize, true /* Padding Element */); + } else { + const Type *PadTy = + ArrayType::get(Type::Int8Ty, GCCTypeSize-LLVMStructSize); + Info->addElement(PadTy, GCCTypeSize - LLVMLastElementEnd, + GCCTypeSize - LLVMLastElementEnd, + true /* Padding Element */); + + } + } } } @@ -1460,7 +1498,7 @@ if (tree DeclaredType = DECL_BIT_FIELD_TYPE(Field)) { // If this is a bitfield, the declared type must be an integral type. const Type *DeclFieldTy = ConvertType(DeclaredType); - unsigned DeclBitAlignment = Info.getTypeAlignment(DeclFieldTy)*8; + unsigned DeclBitAlignment = Info->getTypeAlignment(DeclFieldTy)*8; FieldOffsetInBits &= ~(DeclBitAlignment-1ULL); } @@ -1471,11 +1509,12 @@ integer_zerop(TYPE_SIZE(FieldType)); unsigned FieldNo = - Info.getLLVMFieldFor(FieldOffsetInBits, CurFieldNo, isZeroSizeField); + Info->getLLVMFieldFor(FieldOffsetInBits, CurFieldNo, isZeroSizeField); SET_DECL_LLVM(Field, ConstantInt::get(Type::Int32Ty, FieldNo)); } - const Type *ResultTy = Info.getLLVMType(); + const Type *ResultTy = Info->getLLVMType(); + StructTypeInfoMap[ResultTy] = Info; const OpaqueType *OldTy = cast_or_null<OpaqueType>(GET_TYPE_LLVM(type)); TypeDB.setType(type, ResultTy); _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits