[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