[llvm-commits] [llvm-gcc-4.2] r45590 - in /llvm-gcc-4.2/trunk/gcc: llvm-abi.h llvm-convert.cpp llvm-debug.cpp llvm-internal.h llvm-types.cpp
Duncan Sands
baldrick at free.fr
Fri Jan 4 10:09:09 PST 2008
Author: baldrick
Date: Fri Jan 4 12:09:09 2008
New Revision: 45590
URL: http://llvm.org/viewvc/llvm-project?rev=45590&view=rev
Log:
If a struct field is marked as a bitfield but
didn't need to be, treat it like an ordinary
field. The Ada front-end likes to mark fields
as bitfields preemptively, so this can occur
quite often for Ada. What is more, it can
mark non-integer fields as bitfields. In all
examples I came across so far, these non-integer
bitfields can be treated like ordinary fields.
With this patch, the Ada front-end builds (but
does not bootstrap)! It is true that the problem
of non-integer bitfields could be handled in the
Ada front-end, but since ignoring silly bitfields
seems like a good idea for all front-ends I chose
to solve it in the generic code.
Modified:
llvm-gcc-4.2/trunk/gcc/llvm-abi.h
llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp
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-abi.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-abi.h?rev=45590&r1=45589&r2=45590&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-abi.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-abi.h Fri Jan 4 12:09:09 2008
@@ -106,7 +106,7 @@
for (tree Field = TYPE_FIELDS(type); Field; Field = TREE_CHAIN(Field))
if (TREE_CODE(Field) == FIELD_DECL) {
if (!FoundField)
- FoundField = TREE_TYPE(Field);
+ FoundField = getDeclaredType(Field);
else
return 0; // More than one field.
}
@@ -206,9 +206,9 @@
if (TREE_CODE(Field) == FIELD_DECL) {
unsigned FNo = GetFieldIndex(Field);
assert(FNo != ~0U && "Case not handled yet!");
-
+
C.EnterField(FNo, Ty);
- HandleArgument(TREE_TYPE(Field));
+ HandleArgument(getDeclaredType(Field));
C.ExitField();
}
} else if (TREE_CODE(type) == COMPLEX_TYPE) {
Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=45590&r1=45589&r2=45590&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Fri Jan 4 12:09:09 2008
@@ -5071,8 +5071,8 @@
StructAddrLV.Ptr = BitCastToType(StructAddrLV.Ptr,
PointerType::getUnqual(StructTy));
- const Type *FieldTy = ConvertType(TREE_TYPE(FieldDecl));
-
+ const Type *FieldTy = ConvertType(getDeclaredType(FieldDecl));
+
// BitStart - This is the actual offset of the field from the start of the
// struct, in bits. For bitfields this may be on a non-byte boundary.
unsigned BitStart = getComponentRefOffsetInBits(exp);
@@ -5114,7 +5114,7 @@
PointerType::getUnqual(FieldTy));
}
- if (tree DeclaredType = DECL_BIT_FIELD_TYPE(FieldDecl)) {
+ if (isBitfield(FieldDecl)) {
assert(DECL_SIZE(FieldDecl) &&
TREE_CODE(DECL_SIZE(FieldDecl)) == INTEGER_CST &&
"Variable sized bitfield?");
@@ -5124,7 +5124,6 @@
cast<PointerType>(FieldPtr->getType())->getElementType();
// If this is a bitfield, the declared type must be an integral type.
- FieldTy = ConvertType(DeclaredType);
// If the field result is a bool, cast to a ubyte instead. It is not
// possible to access all bits of a memory object with a bool (only the low
// bit) but it is possible to access them with a byte.
@@ -5970,7 +5969,7 @@
// If the field is a bitfield, it could be spread across multiple fields and
// may start at some bit offset.
- if (DECL_BIT_FIELD_TYPE(Field)) {
+ if (isBitfield(Field)) {
ProcessBitFieldInitialization(Field, Val, STy, ResultElts);
} else {
// If not, things are much simpler.
@@ -5978,7 +5977,7 @@
assert(FieldNo < ResultElts.size() && "Invalid struct field number!");
// Example: struct X { int A; char C[]; } x = { 4, "foo" };
- assert(TYPE_SIZE(TREE_TYPE(Field)) ||
+ assert(TYPE_SIZE(getDeclaredType(Field)) ||
(FieldNo == ResultElts.size()-1 &&
isStructWithVarSizeArrayAtEnd(STy))
&& "field with no size is not array at end of struct!");
@@ -5993,7 +5992,7 @@
// integer. The struct field will have type [4 x ubyte] instead of
// "int" for example. If we ignored this, we would lay out the
// initializer wrong.
- if (TYPE_SIZE(TREE_TYPE(Field)) &&
+ if (TYPE_SIZE(getDeclaredType(Field)) &&
Val->getType() != STy->getElementType(FieldNo))
Val = ConvertStructFieldInitializerToType(Val,
STy->getElementType(FieldNo));
@@ -6220,7 +6219,7 @@
StructAddrLV = ConstantExpr::getBitCast(StructAddrLV,
PointerType::getUnqual(StructTy));
- const Type *FieldTy = ConvertType(TREE_TYPE(FieldDecl));
+ const Type *FieldTy = ConvertType(getDeclaredType(FieldDecl));
// BitStart - This is the actual offset of the field from the start of the
// struct, in bits. For bitfields this may be on a non-byte boundary.
@@ -6253,12 +6252,10 @@
FieldPtr = ConstantExpr::getIntToPtr(Ptr, PointerType::getUnqual(FieldTy));
}
- if (DECL_BIT_FIELD_TYPE(FieldDecl)) {
- FieldTy = ConvertType(DECL_BIT_FIELD_TYPE(FieldDecl));
+ if (isBitfield(FieldDecl))
FieldPtr = ConstantExpr::getBitCast(FieldPtr,
PointerType::getUnqual(FieldTy));
- }
-
+
assert(BitStart == 0 &&
"It's a bitfield reference or we didn't get to the field!");
return FieldPtr;
Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp?rev=45590&r1=45589&r2=45590&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp Fri Jan 4 12:09:09 2008
@@ -119,12 +119,7 @@
///
static tree FieldType(tree Field) {
if (TREE_CODE (Field) == ERROR_MARK) return integer_type_node;
-
- tree type = DECL_BIT_FIELD_TYPE (Field);
- if (type == NULL_TREE)
- type = TREE_TYPE (Field);
-
- return type;
+ return getDeclaredType(Field);
}
/// GetNodeName - Returns the name stored in a node regardless of whether the
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=45590&r1=45589&r2=45590&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-internal.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-internal.h Fri Jan 4 12:09:09 2008
@@ -216,6 +216,13 @@
/// corresponds to an LLVM array type.
bool isArrayCompatible(tree_node *type);
+/// isBitfield - Returns whether to treat the specified field as a bitfield.
+bool isBitfield(tree_node *field_decl);
+
+/// getDeclaredType - Get the declared type for the specified field, and
+/// not the shrunk-to-fit type that GCC gives us in TREE_TYPE.
+tree_node *getDeclaredType(tree_node *field_decl);
+
/// ValidateRegisterVariable - Check that a static "asm" variable is
/// well-formed. If not, emit error messages and return true. If so, return
/// false.
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=45590&r1=45589&r2=45590&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-types.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Fri Jan 4 12:09:09 2008
@@ -328,6 +328,42 @@
);
}
+/// isBitfield - Returns whether to treat the specified field as a bitfield.
+bool isBitfield(tree_node *field_decl) {
+ tree type = DECL_BIT_FIELD_TYPE(field_decl);
+ if (!type)
+ return false;
+
+ // A bitfield. But do we need to treat it as one?
+
+ assert(DECL_FIELD_BIT_OFFSET(field_decl) && "Bitfield with no bit offset!");
+ if (TREE_INT_CST_LOW(DECL_FIELD_BIT_OFFSET(field_decl)) & 7)
+ // Does not start on a byte boundary - must treat as a bitfield.
+ return true;
+
+ if (!TYPE_SIZE(type) || !isInt64(TYPE_SIZE (type), true))
+ // No size or variable sized - play safe, treat as a bitfield.
+ return true;
+
+ uint64_t TypeSizeInBits = getInt64(TYPE_SIZE (type), true);
+ assert(!(TypeSizeInBits & 7) && "A type with a non-byte size!");
+
+ assert(DECL_SIZE(field_decl) && "Bitfield with no bit size!");
+ unsigned FieldSizeInBits = TREE_INT_CST_LOW(DECL_SIZE(field_decl));
+ if (FieldSizeInBits < TypeSizeInBits)
+ // Not wide enough to hold the entire type - treat as a bitfield.
+ return true;
+
+ return false;
+}
+
+/// getDeclaredType - Get the declared type for the specified field_decl, and
+/// not the shrunk-to-fit type that GCC gives us in TREE_TYPE.
+tree getDeclaredType(tree_node *field_decl) {
+ return DECL_BIT_FIELD_TYPE(field_decl) ?
+ DECL_BIT_FIELD_TYPE(field_decl) : TREE_TYPE (field_decl);
+}
+
/// refine_type_to - Cause all users of the opaque type old_type to switch
/// to the more concrete type new_type.
void refine_type_to(tree old_type, tree new_type)
@@ -464,6 +500,7 @@
// Helper Routines
//===----------------------------------------------------------------------===//
+
/// getFieldOffsetInBits - Return the offset (in bits) of a FIELD_DECL in a
/// structure.
static unsigned getFieldOffsetInBits(tree Field) {
@@ -474,7 +511,6 @@
return Result;
}
-
/// FindLLVMTypePadding - If the specified struct has any inter-element padding,
/// add it to the Padding array.
static void FindLLVMTypePadding(const Type *Ty, unsigned BitOffset,
@@ -619,7 +655,7 @@
return true;
unsigned FieldBitOffset = getFieldOffsetInBits(Field);
- if (GCCTypeOverlapsWithPadding(TREE_TYPE(Field),
+ if (GCCTypeOverlapsWithPadding(getDeclaredType(Field),
PadStartBits-FieldBitOffset, PadSizeBits))
return true;
}
@@ -1589,7 +1625,7 @@
return;
// Handle bit-fields specially.
- if (DECL_BIT_FIELD_TYPE(Field)) {
+ if (isBitfield(Field)) {
DecodeStructBitField(Field, Info);
return;
}
@@ -1600,8 +1636,8 @@
unsigned StartOffsetInBits = getFieldOffsetInBits(Field);
assert((StartOffsetInBits & 7) == 0 && "Non-bit-field has non-byte offset!");
unsigned StartOffsetInBytes = StartOffsetInBits/8;
-
- const Type *Ty = ConvertType(TREE_TYPE(Field));
+
+ const Type *Ty = ConvertType(getDeclaredType(Field));
// Pop any previous elements out of the struct if they overlap with this one.
// This can happen when the C++ front-end overlaps fields with tail padding in
@@ -1843,24 +1879,24 @@
if (TREE_CODE(Field) == FIELD_DECL &&
TREE_CODE(DECL_FIELD_OFFSET(Field)) == INTEGER_CST) {
unsigned FieldOffsetInBits = getFieldOffsetInBits(Field);
- tree FieldType = TREE_TYPE(Field);
-
+ tree FieldType = getDeclaredType(Field);
+
// If this is a bitfield, we may want to adjust the FieldOffsetInBits to
// produce safe code. In particular, bitfields will be loaded/stored as
// their *declared* type, not the smallest integer type that contains
// them. As such, we need to respect the alignment of the declared type.
- if (tree DeclaredType = DECL_BIT_FIELD_TYPE(Field)) {
+ if (isBitfield(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;
-
- FieldOffsetInBits &= ~(DeclBitAlignment-1ULL);
+ const Type *FieldTy = ConvertType(FieldType);
+ unsigned BitAlignment = Info->getTypeAlignment(FieldTy)*8;
+
+ FieldOffsetInBits &= ~(BitAlignment-1ULL);
// When we fix the field alignment, we must restart the FieldNo search
// because the FieldOffsetInBits can be lower than it was in the
// previous iteration.
CurFieldNo = 0;
}
-
+
// Figure out if this field is zero bits wide, e.g. {} or [0 x int]. Do
// not include variable sized fields here.
bool isZeroSizeField = !TYPE_SIZE(FieldType) ||
More information about the llvm-commits
mailing list