[llvm-commits] [126997] Fix PR1278.
dpatel at apple.com
dpatel at apple.com
Mon May 7 23:15:09 PDT 2007
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);
More information about the llvm-commits
mailing list