[llvm-commits] [dragonegg] r138217 - /dragonegg/trunk/src/Types.cpp
Duncan Sands
baldrick at free.fr
Sun Aug 21 05:17:16 PDT 2011
Author: baldrick
Date: Sun Aug 21 07:17:16 2011
New Revision: 138217
URL: http://llvm.org/viewvc/llvm-project?rev=138217&view=rev
Log:
Name tweaks, moving functions around in the file, pulling code out into
its own function etc. No intended functionality changes.
Modified:
dragonegg/trunk/src/Types.cpp
Modified: dragonegg/trunk/src/Types.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/src/Types.cpp?rev=138217&r1=138216&r2=138217&view=diff
==============================================================================
--- dragonegg/trunk/src/Types.cpp (original)
+++ dragonegg/trunk/src/Types.cpp Sun Aug 21 07:17:16 2011
@@ -62,7 +62,7 @@
static const std::vector<tree_node*> *SCCInProgress;
//===----------------------------------------------------------------------===//
-// Viewing types as graphs
+// ... ContainedTypeIterator ...
//===----------------------------------------------------------------------===//
/// ContainedTypeIterator - A convenience class for viewing a type as a graph,
@@ -290,6 +290,16 @@
return set_decl_index(decl, Index);
}
+/// getPointerToType - Returns the LLVM register type to use for a pointer to
+/// the given GCC type.
+Type *getPointerToType(tree type) {
+ if (VOID_TYPE_P(type))
+ // void* -> byte*
+ return GetUnitPointerType(Context);
+ // FIXME: Handle address spaces.
+ return ConvertType(type)->getPointerTo();
+}
+
/// GetUnitType - Returns an integer one address unit wide if 'NumUnits' is 1;
/// otherwise returns an array of such integers with 'NumUnits' elements. For
/// example, on a machine which has 16 bit bytes returns an i16 or an array of
@@ -395,7 +405,7 @@
//===----------------------------------------------------------------------===//
-// Main Type Conversion Routines
+// ... getRegType ...
//===----------------------------------------------------------------------===//
/// getRegType - Returns the LLVM type to use for registers that hold a value
@@ -461,21 +471,39 @@
}
}
-/// getPointerToType - Returns the LLVM register type to use for a pointer to
-/// the given GCC type.
-Type *getPointerToType(tree type) {
- if (VOID_TYPE_P(type))
- // void* -> byte*
- return GetUnitPointerType(Context);
- // FIXME: Handle address spaces.
- return ConvertType(type)->getPointerTo();
-}
-
//===----------------------------------------------------------------------===//
-// FUNCTION/METHOD_TYPE Conversion Routines
+// ... ConvertType ...
//===----------------------------------------------------------------------===//
+static Type *ConvertArrayTypeRecursive(tree type) {
+ Type *ElementTy = ConvertType(TREE_TYPE(type));
+ uint64_t NumElements = ArrayLengthOf(type);
+
+ if (NumElements == NO_LENGTH) // Variable length array?
+ NumElements = 0;
+
+ // Create the array type.
+ Type *Ty = ArrayType::get(ElementTy, NumElements);
+
+ // If the user increased the alignment of the array element type, then the
+ // size of the array is rounded up by that alignment even though the size
+ // of the array element type is not (!). Correct for this if necessary by
+ // adding padding. May also need padding if the element type has variable
+ // size and the array type has variable length, but by a miracle the product
+ // gives a constant size.
+ if (isInt64(TYPE_SIZE(type), true)) {
+ uint64_t PadBits = getInt64(TYPE_SIZE(type), true) -
+ getTargetData().getTypeAllocSizeInBits(Ty);
+ if (PadBits) {
+ Type *Padding = ArrayType::get(Type::getInt8Ty(Context), PadBits / 8);
+ Ty = StructType::get(Ty, Padding, NULL);
+ }
+ }
+
+ return Ty;
+}
+
namespace {
class FunctionTypeConversion : public DefaultABIClient {
Type *&RetTy;
@@ -586,7 +614,6 @@
};
}
-
static Attributes HandleArgumentExtension(tree ArgTy) {
if (TREE_CODE(ArgTy) == BOOLEAN_TYPE) {
if (TREE_INT_CST_LOW(TYPE_SIZE(ArgTy)) < INT_TYPE_SIZE)
@@ -861,6 +888,60 @@
return FunctionType::get(RetTy, ArgTypes, isVarArg);
}
+static Type *ConvertPointerTypeRecursive(tree type) {
+ // 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));
+
+ // The pointer type is in the strongly connected component (SCC) currently
+ // being converted. Check whether the pointee is as well. If there is more
+ // than one type in the SCC then necessarily the pointee type is in the SCC
+ // since any path from the pointer type to the other type necessarily passes
+ // via the pointee. If the pointer type is the only element of the SCC then
+ // the pointee is only in the SCC if it is equal to the pointer.
+ bool bothInSCC = SCCInProgress->size() != 1 || pointee == type;
+
+ Type *PointeeTy;
+ if (!bothInSCC) {
+ // It is safe to convert the pointee. This is the common case, as we get
+ // here for pointers to integers and so on.
+ PointeeTy = ConvertType(pointee);
+ if (PointeeTy->isVoidTy())
+ PointeeTy = GetUnitType(Context); // void* -> byte*.
+ } else {
+ // Both the pointer and the pointee type are in the SCC so it is not safe
+ // to convert the pointee type - otherwise we would get an infinite loop.
+ // However if a type, for example an opaque struct placeholder, has been
+ // registered for the pointee then we can return a pointer to it, giving
+ // nicer IR (this is not needed for correctness). Note that some members
+ // of the SCC may have been converted already at this point (for this to
+ // happen there must be more than one pointer type in the SCC), and thus
+ // will have LLVM types registered for them. Unfortunately which types
+ // have been converted depends on the order in which we visit the SCC, and
+ // that is not an intrinsic property of the SCC. This is why we choose to
+ // only use the types registered for records and unions - these are always
+ // available. As a further attempt to improve the IR, we return an S* for
+ // an array type S[N] if (recursively) S is a record or union type.
+
+ // 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));
+
+ // If the pointee is a record or union type then return a pointer to its
+ // placeholder type. Otherwise return {}*.
+ if (TREE_CODE(pointee) == QUAL_UNION_TYPE ||
+ TREE_CODE(pointee) == RECORD_TYPE ||
+ TREE_CODE(pointee) == UNION_TYPE)
+ PointeeTy = getCachedType(pointee);
+ else
+ PointeeTy = StructType::get(Context);
+ }
+
+ return PointeeTy->getPointerTo();
+}
+
typedef Range<uint64_t> BitRange;
/// TypedRange - A type that applies to a range of bits. Any part of the type
@@ -971,7 +1052,7 @@
Starts = R.getFirst();
}
-static Type *ConvertRecord(tree type) {
+static Type *ConvertRecordTypeRecursive(tree type) {
// FIXME: This new logic, especially the handling of bitfields, is untested
// and probably wrong on big-endian machines.
assert(TYPE_SIZE(type) && "Incomplete types should be handled elsewhere!");
@@ -1186,97 +1267,59 @@
}
}
-/// RecursiveTypeIterator - A convenience class that visits only those nodes
-/// in the type graph that mayRecurse thinks might be self-referential. Note
-/// that dereferencing returns the main variant of the contained type rather
-/// than the contained type itself. See ContainedTypeIterator and mayRecurse
-/// for more information about the type graph and self-referential types.
-namespace {
-
- class RecursiveTypeIterator {
- // This class wraps an iterator that visits all contained types, and just
- // increments the iterator over any contained types that will not recurse.
- ContainedTypeIterator I;
-
- /// SkipNonRecursiveTypes - Increment the wrapped iterator over any types
- /// that mayRecurse says can be converted directly without having to worry
- /// about self-recursion.
- void SkipNonRecursiveTypes() {
- while (I != ContainedTypeIterator::end() &&
- !mayRecurse(TYPE_MAIN_VARIANT(*I)))
- ++I;
- }
-
- /// RecursiveTypeIterator - Convenience constructor for internal use.
- explicit RecursiveTypeIterator(const ContainedTypeIterator& i) : I(i) {}
-
- public:
-
- /// Dereference operator returning the main variant of the contained type.
- tree operator*() {
- return TYPE_MAIN_VARIANT(*I);
- };
-
- /// Comparison operators.
- bool operator==(const RecursiveTypeIterator &other) const {
- return other.I == this->I;
- }
- bool operator!=(const RecursiveTypeIterator &other) const {
- return !(*this == other);
- }
+/// ConvertTypeRecursive - Convert a type when conversion may require breaking
+/// type conversion loops, see mayRecurse. Note that all types used by but not
+/// in the current strongly connected component (SCC) must have been converted
+/// already.
+static Type *ConvertTypeRecursive(tree type) {
+ assert(type == TYPE_MAIN_VARIANT(type) && "Not converting the main variant!");
+ assert(mayRecurse(type) && "Expected a recursive type!");
+ assert(SCCInProgress && "Missing recursion data!");
- /// Postfix increment operator.
- RecursiveTypeIterator operator++(int) {
- RecursiveTypeIterator Result(*this);
- ++(*this);
- return Result;
+#ifndef NDEBUG
+ // Check that the given type is in the current strongly connected component
+ // (SCC) of the type graph. This should always be the case because SCCs are
+ // visited bottom up.
+ bool inSCC = false;
+ for (unsigned i = 0, e = SCCInProgress->size(); i != e; ++i)
+ if ((*SCCInProgress)[i] == type) {
+ inSCC = true;
+ break;
}
+ if (!inSCC)
+ DieAbjectly("Type not in SCC!", type);
+#endif
- /// Prefix increment operator.
- RecursiveTypeIterator& operator++() {
- ++I;
- SkipNonRecursiveTypes();
- return *this;
- }
+ switch (TREE_CODE(type)) {
+ default:
+ DieAbjectly("Unexpected type!", type);
- /// begin - Return an iterator referring to the first type contained in the
- /// given type.
- static RecursiveTypeIterator begin(tree type) {
- RecursiveTypeIterator R(ContainedTypeIterator::begin(type));
- R.SkipNonRecursiveTypes();
- return R;
- }
+ case ARRAY_TYPE:
+ return llvm_set_type(type, ConvertArrayTypeRecursive(type));
- /// end - Return the end iterator for contained type iteration.
- static RecursiveTypeIterator end() {
- return RecursiveTypeIterator(ContainedTypeIterator::end());
- }
- };
+ case FUNCTION_TYPE:
+ case METHOD_TYPE: {
+ CallingConv::ID CallingConv;
+ AttrListPtr PAL;
+ // No declaration to pass through, passing NULL.
+ return llvm_set_type(type, ConvertFunctionType(type, NULL, NULL,
+ CallingConv, PAL));
+ }
-} // Unnamed namespace.
+ case POINTER_TYPE:
+ case REFERENCE_TYPE:
+ return llvm_set_type(type, ConvertPointerTypeRecursive(type));
-// Traits for working with the graph of possibly self-referential type nodes,
-// see RecursiveTypeIterator.
-namespace llvm {
- template <> struct GraphTraits<tree> {
- typedef tree_node NodeType;
- typedef RecursiveTypeIterator ChildIteratorType;
- static inline NodeType *getEntryNode(tree t) {
- assert(TYPE_P(t) && "Expected a type!");
- return t;
- }
- static inline ChildIteratorType child_begin(tree type) {
- return ChildIteratorType::begin(type);
- }
- static inline ChildIteratorType child_end(tree) {
- return ChildIteratorType::end();
- }
- };
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ case QUAL_UNION_TYPE:
+ return llvm_set_type(type, ConvertRecordTypeRecursive(type));
+ }
}
-/// ConvertNonRecursiveType - Convert a type when this is known to not require
+/// ConvertTypeNonRecursive - Convert a type when this is known to not require
/// breaking type conversion loops, see mayRecurse.
-static Type *ConvertNonRecursiveType(tree type) {
+static Type *ConvertTypeNonRecursive(tree type) {
assert(type == TYPE_MAIN_VARIANT(type) && "Not converting the main variant!");
assert(!mayRecurse(type) && "Expected a non-recursive type!");
@@ -1309,7 +1352,7 @@
case COMPLEX_TYPE: {
if (Type *Ty = getCachedType(type)) return Ty;
- Type *Ty = ConvertNonRecursiveType(TYPE_MAIN_VARIANT(TREE_TYPE(type)));
+ Type *Ty = ConvertTypeNonRecursive(TYPE_MAIN_VARIANT(TREE_TYPE(type)));
Ty = StructType::get(Ty, Ty, NULL);
return llvm_set_type(type, Ty);
}
@@ -1356,7 +1399,7 @@
if (POINTER_TYPE_P(TREE_TYPE(type)))
Ty = getTargetData().getIntPtrType(Context);
else
- Ty = ConvertNonRecursiveType(TYPE_MAIN_VARIANT(TREE_TYPE(type)));
+ Ty = ConvertTypeNonRecursive(TYPE_MAIN_VARIANT(TREE_TYPE(type)));
Ty = VectorType::get(Ty, TYPE_VECTOR_SUBPARTS(type));
return llvm_set_type(type, Ty);
}
@@ -1366,130 +1409,92 @@
}
}
-/// ConvertRecursiveType - Convert a type when conversion may require breaking
-/// type conversion loops, see mayRecurse. Note that all types used by but not
-/// in the current strongly connected component (SCC) must have been converted
-/// already.
-static Type *ConvertRecursiveType(tree type) {
- assert(type == TYPE_MAIN_VARIANT(type) && "Not converting the main variant!");
- assert(mayRecurse(type) && "Expected a recursive type!");
- assert(SCCInProgress && "Missing recursion data!");
+/// RecursiveTypeIterator - A convenience class that visits only those nodes
+/// in the type graph that mayRecurse thinks might be self-referential. Note
+/// that dereferencing returns the main variant of the contained type rather
+/// than the contained type itself. See ContainedTypeIterator and mayRecurse
+/// for more information about the type graph and self-referential types.
+namespace {
-#ifndef NDEBUG
- // Check that the given type is in the current strongly connected component
- // (SCC) of the type graph. This should always be the case because SCCs are
- // visited bottom up.
- bool inSCC = false;
- for (unsigned i = 0, e = SCCInProgress->size(); i != e; ++i)
- if ((*SCCInProgress)[i] == type) {
- inSCC = true;
- break;
+ class RecursiveTypeIterator {
+ // This class wraps an iterator that visits all contained types, and just
+ // increments the iterator over any contained types that will not recurse.
+ ContainedTypeIterator I;
+
+ /// SkipNonRecursiveTypes - Increment the wrapped iterator over any types
+ /// that mayRecurse says can be converted directly without having to worry
+ /// about self-recursion.
+ void SkipNonRecursiveTypes() {
+ while (I != ContainedTypeIterator::end() &&
+ !mayRecurse(TYPE_MAIN_VARIANT(*I)))
+ ++I;
}
- if (!inSCC)
- DieAbjectly("Type not in SCC!", type);
-#endif
- switch (TREE_CODE(type)) {
- default:
- DieAbjectly("Unexpected type!", type);
+ /// RecursiveTypeIterator - Convenience constructor for internal use.
+ explicit RecursiveTypeIterator(const ContainedTypeIterator& i) : I(i) {}
- case QUAL_UNION_TYPE:
- case RECORD_TYPE:
- case UNION_TYPE:
- return llvm_set_type(type, ConvertRecord(type));
+ public:
- case POINTER_TYPE:
- case REFERENCE_TYPE: {
- // 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));
-
- // The pointer type is in the strongly connected component (SCC) currently
- // being converted. Check whether the pointee is as well. If there is more
- // than one type in the SCC then necessarily the pointee type is in the SCC
- // since any path from the pointer type to the other type necessarily passes
- // via the pointee. If the pointer type is the only element of the SCC then
- // the pointee is only in the SCC if it is equal to the pointer.
- bool bothInSCC = SCCInProgress->size() != 1 || pointee == type;
-
- Type *PointeeTy;
- if (!bothInSCC) {
- // It is safe to convert the pointee. This is the common case, as we get
- // here for pointers to integers and so on.
- PointeeTy = ConvertType(pointee);
- if (PointeeTy->isVoidTy())
- PointeeTy = GetUnitType(Context); // void* -> byte*.
- } else {
- // Both the pointer and the pointee type are in the SCC so it is not safe
- // to convert the pointee type - otherwise we would get an infinite loop.
- // However if a type, for example an opaque struct placeholder, has been
- // registered for the pointee then we can return a pointer to it, giving
- // nicer IR (this is not needed for correctness). Note that some members
- // of the SCC may have been converted already at this point (for this to
- // happen there must be more than one pointer type in the SCC), and thus
- // will have LLVM types registered for them. Unfortunately which types
- // have been converted depends on the order in which we visit the SCC, and
- // that is not an intrinsic property of the SCC. This is why we choose to
- // only use the types registered for records and unions - these are always
- // available. As a further attempt to improve the IR, we return an S* for
- // an array type S[N] if (recursively) S is a record or union type.
-
- // 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));
-
- // If the pointee is a record or union type then return a pointer to its
- // placeholder type. Otherwise return {}*.
- if (TREE_CODE(pointee) == QUAL_UNION_TYPE ||
- TREE_CODE(pointee) == RECORD_TYPE ||
- TREE_CODE(pointee) == UNION_TYPE)
- PointeeTy = getCachedType(pointee);
- else
- PointeeTy = StructType::get(Context);
+ /// Dereference operator returning the main variant of the contained type.
+ tree operator*() {
+ return TYPE_MAIN_VARIANT(*I);
+ };
+
+ /// Comparison operators.
+ bool operator==(const RecursiveTypeIterator &other) const {
+ return other.I == this->I;
+ }
+ bool operator!=(const RecursiveTypeIterator &other) const {
+ return !(*this == other);
}
- return llvm_set_type(type, PointeeTy->getPointerTo());
- }
+ /// Postfix increment operator.
+ RecursiveTypeIterator operator++(int) {
+ RecursiveTypeIterator Result(*this);
+ ++(*this);
+ return Result;
+ }
- case METHOD_TYPE:
- case FUNCTION_TYPE: {
- CallingConv::ID CallingConv;
- AttrListPtr PAL;
- // No declaration to pass through, passing NULL.
- return llvm_set_type(type, ConvertFunctionType(type, NULL, NULL,
- CallingConv, PAL));
- }
+ /// Prefix increment operator.
+ RecursiveTypeIterator& operator++() {
+ ++I;
+ SkipNonRecursiveTypes();
+ return *this;
+ }
- case ARRAY_TYPE: {
- Type *ElementTy = ConvertType(TREE_TYPE(type));
- uint64_t NumElements = ArrayLengthOf(type);
-
- if (NumElements == NO_LENGTH) // Variable length array?
- NumElements = 0;
-
- // Create the array type.
- Type *Ty = ArrayType::get(ElementTy, NumElements);
-
- // If the user increased the alignment of the array element type, then the
- // size of the array is rounded up by that alignment even though the size
- // of the array element type is not (!). Correct for this if necessary by
- // adding padding. May also need padding if the element type has variable
- // size and the array type has variable length, but by a miracle the product
- // gives a constant size.
- if (isInt64(TYPE_SIZE(type), true)) {
- uint64_t PadBits = getInt64(TYPE_SIZE(type), true) -
- getTargetData().getTypeAllocSizeInBits(Ty);
- if (PadBits) {
- Type *Padding = ArrayType::get(Type::getInt8Ty(Context), PadBits / 8);
- Ty = StructType::get(Ty, Padding, NULL);
- }
+ /// begin - Return an iterator referring to the first type contained in the
+ /// given type.
+ static RecursiveTypeIterator begin(tree type) {
+ RecursiveTypeIterator R(ContainedTypeIterator::begin(type));
+ R.SkipNonRecursiveTypes();
+ return R;
}
- return llvm_set_type(type, Ty);
- }
- }
+ /// end - Return the end iterator for contained type iteration.
+ static RecursiveTypeIterator end() {
+ return RecursiveTypeIterator(ContainedTypeIterator::end());
+ }
+ };
+
+} // Unnamed namespace.
+
+// Traits for working with the graph of possibly self-referential type nodes,
+// see RecursiveTypeIterator.
+namespace llvm {
+ template <> struct GraphTraits<tree> {
+ typedef tree_node NodeType;
+ typedef RecursiveTypeIterator ChildIteratorType;
+ static inline NodeType *getEntryNode(tree t) {
+ assert(TYPE_P(t) && "Expected a type!");
+ return t;
+ }
+ static inline ChildIteratorType child_begin(tree type) {
+ return ChildIteratorType::begin(type);
+ }
+ static inline ChildIteratorType child_end(tree) {
+ return ChildIteratorType::end();
+ }
+ };
}
Type *ConvertType(tree type) {
@@ -1501,11 +1506,11 @@
// If this type can be converted without special action being needed to avoid
// conversion loops coming from self-referential types, then convert it.
if (!mayRecurse(type))
- return ConvertNonRecursiveType(type);
+ return ConvertTypeNonRecursive(type);
// If we already started a possibly looping type conversion, continue with it.
if (SCCInProgress)
- return ConvertRecursiveType(type);
+ return ConvertTypeRecursive(type);
// Begin converting a type for which the conversion may require breaking type
// conversion loops coming from self-referential types, see mayRecurse. First
More information about the llvm-commits
mailing list