blob: 8239f2b6e1cfd6e31d4c383ec60ec78540be4754 [file] [log] [blame]
diff -r -u -N dragonegg-2.9-old/ABI.h dragonegg-2.9-new/ABI.h
--- dragonegg-2.9-old/ABI.h 2011-03-10 17:05:54.000000000 +0100
+++ dragonegg-2.9-new/ABI.h 1970-01-01 01:00:00.000000000 +0100
@@ -1,351 +0,0 @@
-//===--------- ABI.h - Processor ABI customization hooks --------*- C++ -*-===//
-//
-// Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Chris Lattner,
-// Duncan Sands et al.
-//
-// This file is part of DragonEgg.
-//
-// DragonEgg is free software; you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free Software
-// Foundation; either version 2, or (at your option) any later version.
-//
-// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along with
-// DragonEgg; see the file COPYING. If not, write to the Free Software
-// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
-//
-//===----------------------------------------------------------------------===//
-// This file specifies how argument values are passed and returned from function
-// calls. This allows the target to specialize handling of things like how
-// structures are passed by-value.
-//===----------------------------------------------------------------------===//
-
-#ifndef DRAGONEGG_ABI_H
-#define DRAGONEGG_ABI_H
-
-// Plugin headers
-#include "Internals.h"
-#include "Target.h"
-
-// LLVM headers
-#include "llvm/LLVMContext.h"
-#include "llvm/Target/TargetData.h"
-
-namespace llvm {
- class BasicBlock;
-}
-
-/// DefaultABIClient - This is a simple implementation of the ABI client
-/// interface that can be subclassed.
-struct DefaultABIClient {
- virtual ~DefaultABIClient() {}
- virtual CallingConv::ID& getCallingConv(void) = 0;
- virtual bool isShadowReturn() const { return false; }
-
- /// HandleScalarResult - This callback is invoked if the function returns a
- /// simple scalar result value, which is of type RetTy.
- virtual void HandleScalarResult(const Type * /*RetTy*/) {}
-
- /// HandleAggregateResultAsScalar - This callback is invoked if the function
- /// returns an aggregate value by bit converting it to the specified scalar
- /// type and returning that. The bit conversion should start at byte Offset
- /// within the struct, and ScalarTy is not necessarily big enough to cover
- /// the entire struct.
- virtual void HandleAggregateResultAsScalar(const Type * /*ScalarTy*/,
- unsigned /*Offset*/ = 0) {}
-
- /// HandleAggregateResultAsAggregate - This callback is invoked if the function
- /// returns an aggregate value using multiple return values.
- virtual void HandleAggregateResultAsAggregate(const Type * /*AggrTy*/) {}
-
- /// HandleAggregateShadowResult - This callback is invoked if the function
- /// returns an aggregate value by using a "shadow" first parameter, which is
- /// a pointer to the aggregate, of type PtrArgTy. If RetPtr is set to true,
- /// the pointer argument itself is returned from the function.
- virtual void HandleAggregateShadowResult(const PointerType * /*PtrArgTy*/,
- bool /*RetPtr*/) {}
-
- /// HandleScalarShadowResult - This callback is invoked if the function
- /// returns a scalar value by using a "shadow" first parameter, which is a
- /// pointer to the scalar, of type PtrArgTy. If RetPtr is set to true,
- /// the pointer argument itself is returned from the function.
- virtual void HandleScalarShadowResult(const PointerType * /*PtrArgTy*/,
- bool /*RetPtr*/) {}
-
-
- /// HandleScalarArgument - This is the primary callback that specifies an
- /// LLVM argument to pass. It is only used for first class types.
- /// If RealSize is non Zero then it specifies number of bytes to access
- /// from LLVMTy.
- virtual void HandleScalarArgument(const llvm::Type * /*LLVMTy*/,
- tree_node * /*type*/,
- unsigned /*RealSize*/ = 0) {}
-
- /// HandleByInvisibleReferenceArgument - This callback is invoked if a pointer
- /// (of type PtrTy) to the argument is passed rather than the argument itself.
- virtual void HandleByInvisibleReferenceArgument(const llvm::Type * /*PtrTy*/,
- tree_node * /*type*/) {}
-
- /// HandleByValArgument - This callback is invoked if the aggregate function
- /// argument is passed by value.
- virtual void HandleByValArgument(const llvm::Type * /*LLVMTy*/,
- tree_node * /*type*/) {}
-
- /// HandleFCAArgument - This callback is invoked if the aggregate function
- /// argument is passed by value as a first class aggregate.
- virtual void HandleFCAArgument(const llvm::Type * /*LLVMTy*/,
- tree_node * /*type*/) {}
-
- /// EnterField - Called when we're about the enter the field of a struct
- /// or union. FieldNo is the number of the element we are entering in the
- /// LLVM Struct, StructTy is the LLVM type of the struct we are entering.
- virtual void EnterField(unsigned /*FieldNo*/,
- const llvm::Type * /*StructTy*/) {}
- virtual void ExitField() {}
- virtual void HandlePad(const llvm::Type * /*LLVMTy*/) {}
-};
-
-// LLVM_SHOULD_NOT_RETURN_COMPLEX_IN_MEMORY - A hook to allow
-// special _Complex handling. Return true if X should be returned using
-// multiple value return instruction.
-#ifndef LLVM_SHOULD_NOT_RETURN_COMPLEX_IN_MEMORY
-#define LLVM_SHOULD_NOT_RETURN_COMPLEX_IN_MEMORY(X) \
- false
-#endif
-
-// LLVM_SHOULD_NOT_USE_SHADOW_RETURN - A hook to allow aggregates to be
-// returned in registers.
-#ifndef LLVM_SHOULD_NOT_USE_SHADOW_RETURN
-#define LLVM_SHOULD_NOT_USE_SHADOW_RETURN(X, CC) \
- false
-#endif
-
-// doNotUseShadowReturn - Return true if the specified GCC type
-// should not be returned using a pointer to struct parameter.
-extern bool doNotUseShadowReturn(tree_node *type, tree_node *fndecl,
- CallingConv::ID CC);
-
-/// isSingleElementStructOrArray - If this is (recursively) a structure with one
-/// field or an array with one element, return the field type, otherwise return
-/// null. Returns null for complex number types. If ignoreZeroLength, the
-/// struct (recursively) may include zero-length fields in addition to the
-/// single element that has data. If rejectFatBitField, and the single element
-/// is a bitfield of a type that's bigger than the struct, return null anyway.
-extern tree_node *isSingleElementStructOrArray(tree_node *type,
- bool ignoreZeroLength,
- bool rejectFatBitfield);
-
-/// isZeroSizedStructOrUnion - Returns true if this is a struct or union
-/// which is zero bits wide.
-extern bool isZeroSizedStructOrUnion(tree_node *type);
-
-// getLLVMScalarTypeForStructReturn - Return LLVM Type if TY can be
-// returned as a scalar, otherwise return NULL. This is the default
-// target independent implementation.
-static inline
-const Type* getLLVMScalarTypeForStructReturn(tree_node *type, unsigned *Offset) {
- const Type *Ty = ConvertType(type);
- unsigned Size = getTargetData().getTypeAllocSize(Ty);
- *Offset = 0;
- if (Size == 0)
- return Type::getVoidTy(getGlobalContext());
- else if (Size == 1)
- return Type::getInt8Ty(getGlobalContext());
- else if (Size == 2)
- return Type::getInt16Ty(getGlobalContext());
- else if (Size <= 4)
- return Type::getInt32Ty(getGlobalContext());
- else if (Size <= 8)
- return Type::getInt64Ty(getGlobalContext());
- else if (Size <= 16)
- return IntegerType::get(getGlobalContext(), 128);
- else if (Size <= 32)
- return IntegerType::get(getGlobalContext(), 256);
-
- return NULL;
-}
-
-// getLLVMAggregateTypeForStructReturn - Return LLVM type if TY can be
-// returns as multiple values, otherwise return NULL. This is the default
-// target independent implementation.
-static inline
-const Type* getLLVMAggregateTypeForStructReturn(tree_node * /*type*/) {
- return NULL;
-}
-
-#ifndef LLVM_TRY_PASS_AGGREGATE_CUSTOM
-#define LLVM_TRY_PASS_AGGREGATE_CUSTOM(T, E, CC, C) \
- false
-#endif
-
-// LLVM_SHOULD_PASS_VECTOR_IN_INTEGER_REGS - Return true if this vector
-// type should be passed as integer registers. Generally vectors which are
-// not part of the target architecture should do this.
-#ifndef LLVM_SHOULD_PASS_VECTOR_IN_INTEGER_REGS
-#define LLVM_SHOULD_PASS_VECTOR_IN_INTEGER_REGS(TY) \
- false
-#endif
-
-// LLVM_SHOULD_PASS_VECTOR_USING_BYVAL_ATTR - Return true if this vector
-// type should be passed byval. Used for generic vectors on x86-64.
-#ifndef LLVM_SHOULD_PASS_VECTOR_USING_BYVAL_ATTR
-#define LLVM_SHOULD_PASS_VECTOR_USING_BYVAL_ATTR(X) \
- false
-#endif
-
-// LLVM_SHOULD_PASS_AGGREGATE_USING_BYVAL_ATTR - Return true if this aggregate
-// value should be passed by value, i.e. passing its address with the byval
-// attribute bit set. The default is false.
-#ifndef LLVM_SHOULD_PASS_AGGREGATE_USING_BYVAL_ATTR
-#define LLVM_SHOULD_PASS_AGGREGATE_USING_BYVAL_ATTR(X, TY) \
- false
-#endif
-
-// LLVM_SHOULD_PASS_AGGREGATE_AS_FCA - Return true if this aggregate value
-// should be passed by value as a first class aggregate. The default is false.
-#ifndef LLVM_SHOULD_PASS_AGGREGATE_AS_FCA
-#define LLVM_SHOULD_PASS_AGGREGATE_AS_FCA(X, TY) \
- false
-#endif
-
-// LLVM_SHOULD_PASS_AGGREGATE_IN_MIXED_REGS - Return true if this aggregate
-// value should be passed in a mixture of integer, floating point, and vector
-// registers. The routine should also return by reference a vector of the
-// types of the registers being used. The default is false.
-#ifndef LLVM_SHOULD_PASS_AGGREGATE_IN_MIXED_REGS
-#define LLVM_SHOULD_PASS_AGGREGATE_IN_MIXED_REGS(T, TY, CC, E) \
- false
-#endif
-
-// LLVM_AGGREGATE_PARTIALLY_PASSED_IN_REGS - Only called if
-// LLVM_SHOULD_PASS_AGGREGATE_IN_MIXED_REGS returns true. This returns true if
-// there are only enough unused argument passing registers to pass a part of
-// the aggregate. Note, this routine should return false if none of the needed
-// registers are available.
-#ifndef LLVM_AGGREGATE_PARTIALLY_PASSED_IN_REGS
-#define LLVM_AGGREGATE_PARTIALLY_PASSED_IN_REGS(E, SE, ISR, CC) \
- false
-#endif
-
-// LLVM_BYVAL_ALIGNMENT - Returns the alignment of the type in bytes, if known,
-// in the getGlobalContext() of its use as a function parameter.
-// Note that the alignment in the TYPE node is usually the alignment appropriate
-// when the type is used within a struct, which may or may not be appropriate
-// here.
-#ifndef LLVM_BYVAL_ALIGNMENT
-#define LLVM_BYVAL_ALIGNMENT(T) 0
-#endif
-
-// LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS - Return true if this aggregate
-// value should be passed in integer registers. By default, we do this for all
-// values that are not single-element structs. This ensures that things like
-// {short,short} are passed in one 32-bit chunk, not as two arguments (which
-// would often be 64-bits). We also do it for single-element structs when the
-// single element is a bitfield of a type bigger than the struct; the code
-// for field-by-field struct passing does not handle this one right.
-#ifndef LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS
-#define LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS(X, Y, Z) \
- !isSingleElementStructOrArray((X), false, true)
-#endif
-
-// LLVM_SHOULD_RETURN_SELT_STRUCT_AS_SCALAR - Return a TYPE tree if this single
-// element struct should be returned using the convention for that scalar TYPE,
-// 0 otherwise.
-// The returned TYPE must be the same size as X for this to work; that is
-// checked elsewhere. (Structs where this is not the case can be constructed
-// by abusing the __aligned__ attribute.)
-#ifndef LLVM_SHOULD_RETURN_SELT_STRUCT_AS_SCALAR
-#define LLVM_SHOULD_RETURN_SELT_STRUCT_AS_SCALAR(X) \
- isSingleElementStructOrArray(X, false, false)
-#endif
-
-// LLVM_SHOULD_RETURN_VECTOR_AS_SCALAR - Return a TYPE tree if this vector type
-// should be returned using the convention for that scalar TYPE, 0 otherwise.
-// X may be evaluated more than once.
-#ifndef LLVM_SHOULD_RETURN_VECTOR_AS_SCALAR
-#define LLVM_SHOULD_RETURN_VECTOR_AS_SCALAR(X,Y) 0
-#endif
-
-// LLVM_SHOULD_RETURN_VECTOR_AS_SHADOW - Return true if this vector type
-// should be returned using the aggregate shadow (sret) convention, 0 otherwise.
-// X may be evaluated more than once.
-#ifndef LLVM_SHOULD_RETURN_VECTOR_AS_SHADOW
-#define LLVM_SHOULD_RETURN_VECTOR_AS_SHADOW(X,Y) 0
-#endif
-
-// LLVM_SCALAR_TYPE_FOR_STRUCT_RETURN - Return LLVM Type if X can be
-// returned as a scalar, otherwise return NULL.
-#ifndef LLVM_SCALAR_TYPE_FOR_STRUCT_RETURN
-#define LLVM_SCALAR_TYPE_FOR_STRUCT_RETURN(X, Y) \
- getLLVMScalarTypeForStructReturn((X), (Y))
-#endif
-
-// LLVM_AGGR_TYPE_FOR_STRUCT_RETURN - Return LLVM Type if X can be
-// returned as an aggregate, otherwise return NULL.
-#ifndef LLVM_AGGR_TYPE_FOR_STRUCT_RETURN
-#define LLVM_AGGR_TYPE_FOR_STRUCT_RETURN(X, CC) \
- getLLVMAggregateTypeForStructReturn(X)
-#endif
-
-// LLVM_EXTRACT_MULTIPLE_RETURN_VALUE - Extract multiple return value from
-// SRC and assign it to DEST. Each target that supports multiple return
-// value must implement this hook.
-#ifndef LLVM_EXTRACT_MULTIPLE_RETURN_VALUE
-#define LLVM_EXTRACT_MULTIPLE_RETURN_VALUE(Src,Dest,V,B) \
- llvm_default_extract_multiple_return_value((Src),(Dest),(V),(B))
-#endif
-static inline
-void llvm_default_extract_multiple_return_value(Value * /*Src*/, Value * /*Dest*/,
- bool /*isVolatile*/,
- LLVMBuilder &/*Builder*/) {
- assert (0 && "LLVM_EXTRACT_MULTIPLE_RETURN_VALUE is not implemented!");
-}
-
-/// DefaultABI - This class implements the default LLVM ABI where structures are
-/// passed by decimating them into individual components and unions are passed
-/// by passing the largest member of the union.
-///
-class DefaultABI {
-protected:
- DefaultABIClient &C;
-public:
- DefaultABI(DefaultABIClient &c);
-
- bool isShadowReturn() const;
-
- /// HandleReturnType - This is invoked by the target-independent code for the
- /// return type. It potentially breaks down the argument and invokes methods
- /// on the client that indicate how its pieces should be handled. This
- /// handles things like returning structures via hidden parameters.
- void HandleReturnType(tree_node *type, tree_node *fn, bool isBuiltin);
-
- /// HandleArgument - This is invoked by the target-independent code for each
- /// argument type passed into the function. It potentially breaks down the
- /// argument and invokes methods on the client that indicate how its pieces
- /// should be handled. This handles things like decimating structures into
- /// their fields.
- void HandleArgument(tree_node *type, std::vector<const Type*> &ScalarElts,
- Attributes *Attributes = NULL);
-
- /// HandleUnion - Handle a UNION_TYPE or QUAL_UNION_TYPE tree.
- ///
- void HandleUnion(tree_node *type, std::vector<const Type*> &ScalarElts);
-
- /// PassInIntegerRegisters - Given an aggregate value that should be passed in
- /// integer registers, convert it to a structure containing ints and pass all
- /// of the struct elements in. If Size is set we pass only that many bytes.
- void PassInIntegerRegisters(tree_node *type,
- std::vector<const Type*> &ScalarElts,
- unsigned origSize, bool DontCheckAlignment);
-
- /// PassInMixedRegisters - Given an aggregate value that should be passed in
- /// mixed integer, floating point, and vector registers, convert it to a
- /// structure containing the specified struct elements in.
- void PassInMixedRegisters(const Type *Ty, std::vector<const Type*> &OrigElts,
- std::vector<const Type*> &ScalarElts);
-};
-
-#endif /* DRAGONEGG_ABI_H */
diff -r -u -N dragonegg-2.9-old/ADT/IntervalList.h dragonegg-2.9-new/ADT/IntervalList.h
--- dragonegg-2.9-old/ADT/IntervalList.h 2011-03-28 21:44:58.000000000 +0200
+++ dragonegg-2.9-new/ADT/IntervalList.h 1970-01-01 01:00:00.000000000 +0100
@@ -1,215 +0,0 @@
-//=--------- IntervalList.h - List of disjoint intervals ----------*- C++ -*-=//
-//
-// Copyright (C) 2011 Duncan Sands.
-//
-// This file is part of DragonEgg.
-//
-// DragonEgg is free software; you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free Software
-// Foundation; either version 2, or (at your option) any later version.
-//
-// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along with
-// DragonEgg; see the file COPYING. If not, write to the Free Software
-// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
-//
-//===----------------------------------------------------------------------===//
-// This file declares a utility class for maintaining a collection of pairwise
-// disjoint intervals.
-//===----------------------------------------------------------------------===//
-
-#ifndef DRAGONEGG_INTERVALLIST_H
-#define DRAGONEGG_INTERVALLIST_H
-
-#include "Range.h"
-#include "llvm/ADT/SmallVector.h"
-
-/// IntervalList - Maintains a list of disjoint intervals. Type 'T' represents
-/// an interval, and should have a getRange method which returns a range of 'U'
-/// values. In addition it should provide ChangeRangeTo for growing, shrinking
-/// and otherwise changing the shape of the interval; and JoinWith for replacing
-/// the interval with the convex hull of its union with another interval (which
-/// is guaranteed to be disjoint from the original).
-template <class T, typename U, unsigned N>
-class IntervalList {
- typedef typename llvm::SmallVector<T, N> List;
- typedef typename List::iterator iterator;
-
- List Intervals;
- // The actual intervals. Always disjoint, sorted and non-empty.
-
- /// CmpFirst - Compare intervals based on where they start.
- static bool CmpFirst(const T &L, const T &R) {
- return L.getRange().getFirst() < R.getRange().getFirst();
- }
-
- /// CmpLast - Compare intervals based on where they stop.
- static bool CmpLast(const T &L, const T &R) {
- return L.getRange().getLast() < R.getRange().getLast();
- }
-
- /// isSane - Return true if the intervals are non-empty, disjoint and
- /// sorted.
- bool isSane() const {
- for (unsigned i = 0, e = Intervals.size(); i < e; ++i) {
- if (Intervals[i].getRange().empty())
- return false;
- if (i && Intervals[i].getRange().getFirst() <
- Intervals[i-1].getRange().getLast())
- return false;
- }
- return true;
- }
-
-public:
-
- /// AddInterval - Add the given interval to the list. If it overlaps any
- /// existing intervals then the existing intervals are pruned by removing
- /// exactly the parts of them that overlap the new interval. If the added
- /// interval is empty then it will be discarded.
- void AddInterval(const T &S);
-
- /// getNumIntervals - Return the number of intervals in the list.
- unsigned getNumIntervals() const {
- return Intervals.size();
- }
-
- /// getInterval - Return the interval with the given index.
- T getInterval(unsigned Idx) {
- return Intervals[Idx];
- }
-
- /// AlignBoundaries - Ensure that all intervals begin and end on a multiple of
- /// the given value.
- void AlignBoundaries(unsigned Alignment);
-};
-
-/// AddInterval - Add the given interval to the list. If it overlaps any
-/// existing intervals then the existing intervals are pruned by removing
-/// exactly the parts of them that overlap the new interval. If the added
-/// interval is empty then it will be discarded.
-template <class T, typename U, unsigned N>
-void IntervalList<T, U, N>::AddInterval(const T &Interval) {
- const Range<U> NewRange = Interval.getRange();
-
- // If the new interval is empty then there is no point in adding it.
- if (NewRange.empty())
- return;
-
- // If this is the first interval then it cannot overlap any others.
- if (Intervals.empty()) {
- Intervals.push_back(Interval);
- return;
- }
-
- // Check for overlap with existing intervals.
- iterator Lo = std::lower_bound(Intervals.begin(), Intervals.end(), Interval,
- CmpFirst);
- iterator Hi = std::upper_bound(Intervals.begin(), Intervals.end(), Interval,
- CmpLast);
- if (Lo < Hi) {
- // Intervals with index in [Lo, Hi) are those completely covered by the new
- // interval. Throw them away.
- for (iterator I = Lo; I != Hi; ++I)
- assert(NewRange.contains(I->getRange()) && "Old interval not covered!");
- Intervals.erase(Lo, Hi);
- Hi = Lo;
- } else if (Hi < Lo) {
- // The new interval is contained in Hi with an excedent at each end. Chop
- // the old interval into two pieces (the lower and upper parts) and insert
- // the new interval between them.
- const Range<U> OldRange = Hi->getRange();
- assert(OldRange.contains(NewRange) && "New interval not contained in old!");
- const Range<U> LowerRange(OldRange.getFirst(), NewRange.getFirst());
- const Range<U> UpperRange(NewRange.getLast(), OldRange.getLast());
- assert(!LowerRange.empty() && !UpperRange.empty() && "Degenerate end!");
- T UpperPart = *Hi;
- Hi->ChangeRangeTo(LowerRange);
- UpperPart.ChangeRangeTo(UpperRange);
- Lo = Intervals.insert(Lo, UpperPart);
- Intervals.insert(Lo, Interval);
- assert(isSane() && "Interval added wrong!");
- return;
- }
- assert(Lo == Hi);
- // Check for overlap with the preceding interval.
- if (Lo != Intervals.begin()) {
- const iterator Prev = Lo - 1;
- const Range<U> PrevRange = Prev->getRange();
- if (NewRange.getFirst() < PrevRange.getLast())
- // Shrink the previous interval to remove the overlap.
- Prev->ChangeRangeTo(Range<U>(PrevRange.getFirst(), NewRange.getFirst()));
- }
- // Check for overlap with the following interval.
- if (Lo != Intervals.end()) {
- const iterator Next = Lo;
- const Range<U> NextRange = Next->getRange();
- if (NextRange.getFirst() < NewRange.getLast())
- // Shrink the next interval to remove the overlap.
- Next->ChangeRangeTo(Range<U>(NewRange.getLast(), NextRange.getLast()));
- }
- // The new interval is now disjoint from any existing intervals. Insert it.
- Intervals.insert(Lo, Interval);
- assert(isSane() && "Interval added wrong!");
-}
-
-/// AlignBoundaries - Ensure that all intervals begin and end on a multiple of
-/// the given value.
-template <class T, typename U, unsigned N>
-void IntervalList<T, U, N>::AlignBoundaries(unsigned Alignment) {
- assert(Alignment > 0 && "Alignment should be positive!");
- for (iterator SI = Intervals.begin(); SI != Intervals.end(); ++SI) {
- T &Interval = *SI;
- Range<U> OrigRange = Interval.getRange();
-
- // Round the start of the interval down and the end of the interval up to
- // the nearest multiple of the alignment.
- U RoundedFirst = OrigRange.getFirst() - (OrigRange.getFirst() % Alignment);
- U RoundedLast = OrigRange.getLast() + Alignment - 1;
- RoundedLast -= RoundedLast % Alignment;
- Range<U> AlignedRange(RoundedFirst, RoundedLast);
-
- // There is nothing to do if the interval is already aligned.
- if (OrigRange == AlignedRange)
- continue;
-
- // Merge in all following intervals that start before RoundedLast.
- iterator Next = SI + 1;
- for (; Next != Intervals.end() && Next->getRange().getFirst() < RoundedLast;
- ++Next)
- Interval.JoinWith(*Next);
- assert(Interval.getRange().getFirst() == OrigRange.getFirst() &&
- "Merging at end changed start!");
-
- // If merging caused the interval to extend beyond RoundedLast then chop the
- // interval in two at RoundedLast. This stops intervals getting huge due to
- // repeated merging.
- if (Interval.getRange().getLast() > RoundedLast) {
- Range<U> LowerR(OrigRange.getFirst(), RoundedLast);
- Range<U> UpperR(RoundedLast, Interval.getRange().getLast());
- // We must have merged in at least the next interval. Reuse it to hold
- // the part we chop off the end.
- T &J = *(SI + 1) = Interval;
- // Chop the end off the original interval so that it stops at RoundedLast
- // and at the same time extend the start of the original interval down to
- // the alignment boundary.
- Interval.ChangeRangeTo(AlignedRange);
- // Chop the start off the new (following) interval so that it begins at
- // RoundedLast.
- J.ChangeRangeTo(UpperR);
- // Delete any other merged intervals.
- Intervals.erase(SI + 2, Next);
- } else {
- // The interval didn't grow beyond the original alignment boundary. Round
- // it to those boundaries.
- Interval.ChangeRangeTo(AlignedRange);
- // Delete any merged intervals.
- Intervals.erase(SI + 1, Next);
- }
- }
-}
-
-#endif /* DRAGONEGG_INTERVALLIST_H */
diff -r -u -N dragonegg-2.9-old/ADT/Range.h dragonegg-2.9-new/ADT/Range.h
--- dragonegg-2.9-old/ADT/Range.h 2011-03-28 21:44:58.000000000 +0200
+++ dragonegg-2.9-new/ADT/Range.h 1970-01-01 01:00:00.000000000 +0100
@@ -1,106 +0,0 @@
-//=------------------ Range.h - Interval of values ----------------*- C++ -*-=//
-//
-// Copyright (C) 2011 Duncan Sands.
-//
-// This file is part of DragonEgg.
-//
-// DragonEgg is free software; you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free Software
-// Foundation; either version 2, or (at your option) any later version.
-//
-// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along with
-// DragonEgg; see the file COPYING. If not, write to the Free Software
-// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
-//
-//===----------------------------------------------------------------------===//
-// This file declares a utility class for representing an interval of values.
-//===----------------------------------------------------------------------===//
-
-#ifndef DRAGONEGG_RANGE_H
-#define DRAGONEGG_RANGE_H
-
-/// Range - Represents the interval [First, Last).
-template<typename T>
-class Range {
- T First, Last;
-public:
- Range() : First(0), Last(0) {}
- Range(T first, T last) : First(first), Last(last) {}
-
- bool operator==(const Range &other) const {
- return (empty() && other.empty()) ||
- (First == other.First && Last == other.Last);
- }
-
- /// empty - Return whether the range is empty.
- bool empty() const {
- return Last <= First;
- }
-
- /// getFirst - Return the value defining the start of the range.
- T getFirst() const {
- assert(!empty() && "An empty range has no starting value!");
- return First;
- }
-
- /// getLast - Return the value defining the end of the range.
- T getLast() const {
- assert(!empty() && "An empty range has no ending value!");
- return Last;
- }
-
- /// getWidth - Return the number of values in the range.
- T getWidth() const {
- return empty() ? 0 : Last - First;
- }
-
- /// contains - Return true if the given range is contained in this one.
- bool contains(Range r) const {
- if (r.empty())
- return true;
- if (empty())
- return false;
- return First <= r.First && Last >= r.Last;
- }
-
- /// intersects - Return true if the given range intersects this one.
- bool intersects(Range r) const {
- if (empty() || r.empty())
- return false;
- return r.First < Last && r.Last > First;
- }
-
- /// Displace - Return the range obtained by adding the given offset.
- Range Displace(T Offset) const {
- if (empty())
- return Range();
- assert(((Offset >= 0 && First + Offset >= First && Last + Offset >= Last) ||
- (Offset < 0 && First + Offset < First && Last + Offset < Last)) &&
- "Displacement wrapped range!");
- return Range(First + Offset, Last + Offset);
- }
-
- /// Join - Return the smallest range containing this range and the given one.
- Range Join(Range other) const {
- if (empty())
- return other;
- if (other.empty())
- return *this;
- return Range(First < other.First ? First : other.First,
- Last > other.Last ? Last : other.Last);
- }
-
- /// Meet - Return the intersection of this range and the given one.
- Range Meet(Range other) const {
- if (empty() || other.empty())
- return Range();
- return Range(First > other.First ? First : other.First,
- Last < other.Last ? Last : other.Last);
- }
-};
-
-#endif /* DRAGONEGG_RANGE_H */
diff -r -u -N dragonegg-2.9-old/Backend.cpp dragonegg-2.9-new/Backend.cpp
--- dragonegg-2.9-old/Backend.cpp 2011-03-30 08:30:55.000000000 +0200
+++ dragonegg-2.9-new/Backend.cpp 2011-04-09 00:38:06.620098051 +0200
@@ -23,12 +23,12 @@
// Plugin headers
extern "C" {
-#include "cache.h"
+#include "dragonegg/cache.h"
}
-#include "Constants.h"
-#include "Debug.h"
-#include "OS.h"
-#include "Target.h"
+#include "dragonegg/Constants.h"
+#include "dragonegg/Debug.h"
+#include "dragonegg/OS.h"
+#include "dragonegg/Target.h"
// LLVM headers
#define DEBUG_TYPE "plugin"
diff -r -u -N dragonegg-2.9-old/cache.c dragonegg-2.9-new/cache.c
--- dragonegg-2.9-old/cache.c 2011-03-10 17:05:54.000000000 +0100
+++ dragonegg-2.9-new/cache.c 2011-04-09 00:38:06.620098051 +0200
@@ -25,7 +25,7 @@
===----------------------------------------------------------------------===*/
/* Plugin headers. */
-#include "cache.h"
+#include "dragonegg/cache.h"
/* GCC headers. */
#include "config.h"
@@ -49,7 +49,7 @@
htab_t llvm_cache;
/* Garbage collector header. */
-#include "gt-cache.h"
+#include "dragonegg/gt-cache.h"
/* llvm_has_cached - Returns whether a value has been associated with the
tree. */
diff -r -u -N dragonegg-2.9-old/cache.h dragonegg-2.9-new/cache.h
--- dragonegg-2.9-old/cache.h 2011-03-10 17:05:54.000000000 +0100
+++ dragonegg-2.9-new/cache.h 1970-01-01 01:00:00.000000000 +0100
@@ -1,45 +0,0 @@
-/*===----------- cache.h - Caching values "in" GCC trees ----------*- C -*-===*\
-|* *|
-|* Copyright (C) 2009, 2010, 2011 Duncan Sands. *|
-|* *|
-|* This file is part of DragonEgg. *|
-|* *|
-|* DragonEgg is free software; you can redistribute it and/or modify it under *|
-|* the terms of the GNU General Public License as published by the Free *|
-|* Software Foundation; either version 2, or (at your option) any later *|
-|* version. *|
-|* *|
-|* DragonEgg is distributed in the hope that it will be useful, but WITHOUT *|
-|* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *|
-|* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *|
-|* more details. *|
-|* You should have received a copy of the GNU General Public License along *|
-|* with DragonEgg; see the file COPYING. If not, write to the Free Software *|
-|* Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. *|
-|* *|
-|*===----------------------------------------------------------------------===*|
-|* This code lets you to associate a void* with a tree, as if it were cached *|
-|* inside the tree: if the tree is garbage collected and reallocated, then *|
-|* the cached value will have been cleared. *|
-\*===----------------------------------------------------------------------===*/
-
-#ifndef DRAGONEGG_CACHE_H
-#define DRAGONEGG_CACHE_H
-
-union tree_node;
-
-/* llvm_has_cached - Returns whether a value has been associated with the
- tree. */
-extern int llvm_has_cached(union tree_node *tree);
-
-/* llvm_get_cached - Returns the value associated with the tree, or NULL. */
-extern const void *llvm_get_cached(union tree_node *tree);
-
-/* llvm_set_cached - Associates the given value with the tree (and returns it).
- To delete an association, pass NULL for the value. */
-extern const void *llvm_set_cached(union tree_node *tree, const void *val);
-
-/* llvm_replace_cached - Replaces all occurrences of old_val with new_val. */
-extern void llvm_replace_cached(const void *old_val, const void *new_val);
-
-#endif /* DRAGONEGG_CACHE_H */
diff -r -u -N dragonegg-2.9-old/Constants.cpp dragonegg-2.9-new/Constants.cpp
--- dragonegg-2.9-old/Constants.cpp 2011-03-31 17:57:30.000000000 +0200
+++ dragonegg-2.9-new/Constants.cpp 2011-04-09 00:38:06.620098051 +0200
@@ -21,11 +21,11 @@
//===----------------------------------------------------------------------===//
// Plugin headers
-#include "Constants.h"
-#include "Internals.h"
-#include "Trees.h"
-#include "ADT/IntervalList.h"
-#include "ADT/Range.h"
+#include "dragonegg/Constants.h"
+#include "dragonegg/Internals.h"
+#include "dragonegg/Trees.h"
+#include "dragonegg/ADT/IntervalList.h"
+#include "dragonegg/ADT/Range.h"
// LLVM headers
#include "llvm/GlobalVariable.h"
diff -r -u -N dragonegg-2.9-old/Constants.h dragonegg-2.9-new/Constants.h
--- dragonegg-2.9-old/Constants.h 2011-03-29 20:44:32.000000000 +0200
+++ dragonegg-2.9-new/Constants.h 1970-01-01 01:00:00.000000000 +0100
@@ -1,60 +0,0 @@
-//=----- Constants.h - Converting and working with constants ------*- C++ -*-=//
-//
-// Copyright (C) 2011 Duncan Sands.
-//
-// This file is part of DragonEgg.
-//
-// DragonEgg is free software; you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free Software
-// Foundation; either version 2, or (at your option) any later version.
-//
-// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along with
-// DragonEgg; see the file COPYING. If not, write to the Free Software
-// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
-//
-//===----------------------------------------------------------------------===//
-// This file declares functions for converting GCC constants to LLVM and working
-// with them.
-//===----------------------------------------------------------------------===//
-
-#ifndef DRAGONEGG_CONSTANTS_H
-#define DRAGONEGG_CONSTANTS_H
-
-// Forward declarations.
-namespace llvm {
- class Constant;
- class Type;
-}
-union tree_node;
-
-/// AddressOf - Given an expression with a constant address such as a constant,
-/// a global variable or a label, returns the address. The type of the returned
-/// is always a pointer type and, as long as 'exp' does not have void type, the
-/// type of the pointee is the memory type that corresponds to the type of exp
-/// (see ConvertType).
-extern llvm::Constant *AddressOf(tree_node *exp);
-
-/// ConvertInitializer - Convert the initial value for a global variable to an
-/// 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.
-extern llvm::Constant *ConvertInitializer(tree_node *exp);
-
-/// InterpretAsType - Interpret the bits of the given constant (starting from
-/// StartingBit) as representing a constant of type 'Ty'. This results in the
-/// same constant as you would get by storing the bits of 'C' to memory (with
-/// the first bit stored being 'StartingBit') and then loading out a (constant)
-/// value of type 'Ty' from the stored to memory location.
-extern llvm::Constant *InterpretAsType(llvm::Constant *C, const llvm::Type* Ty,
- int StartingBit);
-
-#endif /* DRAGONEGG_CONSTANTS_H */
diff -r -u -N dragonegg-2.9-old/Convert.cpp dragonegg-2.9-new/Convert.cpp
--- dragonegg-2.9-old/Convert.cpp 2011-03-31 17:59:19.000000000 +0200
+++ dragonegg-2.9-new/Convert.cpp 2011-04-09 00:38:06.620098051 +0200
@@ -22,10 +22,10 @@
//===----------------------------------------------------------------------===//
// Plugin headers
-#include "ABI.h"
-#include "Constants.h"
-#include "Debug.h"
-#include "Trees.h"
+#include "dragonegg/ABI.h"
+#include "dragonegg/Constants.h"
+#include "dragonegg/Debug.h"
+#include "dragonegg/Trees.h"
// LLVM headers
#include "llvm/Module.h"
diff -r -u -N dragonegg-2.9-old/darwin/dragonegg/OS.h dragonegg-2.9-new/darwin/dragonegg/OS.h
--- dragonegg-2.9-old/darwin/dragonegg/OS.h 1970-01-01 01:00:00.000000000 +0100
+++ dragonegg-2.9-new/darwin/dragonegg/OS.h 2011-04-09 00:38:06.620098051 +0200
@@ -0,0 +1,56 @@
+//===------------ OS.h - Darwin specific definitions ------------*- C++ -*-===//
+//
+// Copyright (C) 2009, 2010, 2011 Duncan Sands et al.
+//
+// This file is part of DragonEgg.
+//
+// DragonEgg is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free Software
+// Foundation; either version 2, or (at your option) any later version.
+//
+// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along with
+// DragonEgg; see the file COPYING. If not, write to the Free Software
+// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
+//
+//===----------------------------------------------------------------------===//
+// This file provides Darwin specific declarations.
+//===----------------------------------------------------------------------===//
+
+#ifndef DRAGONEGG_OS_H
+#define DRAGONEGG_OS_H
+
+/* Darwin X86-64 only supports PIC code generation. */
+#if defined (TARGET_386)
+#define LLVM_SET_TARGET_OPTIONS(argvec) \
+ if ((TARGET_64BIT) || flag_pic) \
+ argvec.push_back ("--relocation-model=pic"); \
+ else if (!MACHO_DYNAMIC_NO_PIC_P) \
+ argvec.push_back ("--relocation-model=static")
+#elif defined (TARGET_ARM)
+#define LLVM_SET_TARGET_OPTIONS(argvec) \
+ if (flag_pic) \
+ argvec.push_back ("--relocation-model=pic"); \
+ else if (!MACHO_DYNAMIC_NO_PIC_P) \
+ argvec.push_back ("--relocation-model=static"); \
+#else /* !TARGET_386 && !TARGET_ARM */
+#define LLVM_SET_TARGET_OPTIONS(argvec) \
+ if (flag_pic) \
+ argvec.push_back ("--relocation-model=pic"); \
+ else if (!MACHO_DYNAMIC_NO_PIC_P) \
+ argvec.push_back ("--relocation-model=static")
+#endif /* !TARGET_386 && !TARGET_ARM */
+
+/* Give a constant string a sufficient alignment for the platform. */
+/* radar 7291825 */
+#define TARGET_ADJUST_CSTRING_ALIGN(GV) \
+ do { \
+ if (GV->hasInternalLinkage()) { \
+ GV->setAlignment(TARGET_64BIT ? 8 : 4); \
+ } \
+ } while (0)
+
+#endif /* DRAGONEGG_OS_H */
diff -r -u -N dragonegg-2.9-old/darwin/OS.h dragonegg-2.9-new/darwin/OS.h
--- dragonegg-2.9-old/darwin/OS.h 2011-03-10 17:05:54.000000000 +0100
+++ dragonegg-2.9-new/darwin/OS.h 1970-01-01 01:00:00.000000000 +0100
@@ -1,56 +0,0 @@
-//===------------ OS.h - Darwin specific definitions ------------*- C++ -*-===//
-//
-// Copyright (C) 2009, 2010, 2011 Duncan Sands et al.
-//
-// This file is part of DragonEgg.
-//
-// DragonEgg is free software; you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free Software
-// Foundation; either version 2, or (at your option) any later version.
-//
-// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along with
-// DragonEgg; see the file COPYING. If not, write to the Free Software
-// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
-//
-//===----------------------------------------------------------------------===//
-// This file provides Darwin specific declarations.
-//===----------------------------------------------------------------------===//
-
-#ifndef DRAGONEGG_OS_H
-#define DRAGONEGG_OS_H
-
-/* Darwin X86-64 only supports PIC code generation. */
-#if defined (TARGET_386)
-#define LLVM_SET_TARGET_OPTIONS(argvec) \
- if ((TARGET_64BIT) || flag_pic) \
- argvec.push_back ("--relocation-model=pic"); \
- else if (!MACHO_DYNAMIC_NO_PIC_P) \
- argvec.push_back ("--relocation-model=static")
-#elif defined (TARGET_ARM)
-#define LLVM_SET_TARGET_OPTIONS(argvec) \
- if (flag_pic) \
- argvec.push_back ("--relocation-model=pic"); \
- else if (!MACHO_DYNAMIC_NO_PIC_P) \
- argvec.push_back ("--relocation-model=static"); \
-#else /* !TARGET_386 && !TARGET_ARM */
-#define LLVM_SET_TARGET_OPTIONS(argvec) \
- if (flag_pic) \
- argvec.push_back ("--relocation-model=pic"); \
- else if (!MACHO_DYNAMIC_NO_PIC_P) \
- argvec.push_back ("--relocation-model=static")
-#endif /* !TARGET_386 && !TARGET_ARM */
-
-/* Give a constant string a sufficient alignment for the platform. */
-/* radar 7291825 */
-#define TARGET_ADJUST_CSTRING_ALIGN(GV) \
- do { \
- if (GV->hasInternalLinkage()) { \
- GV->setAlignment(TARGET_64BIT ? 8 : 4); \
- } \
- } while (0)
-
-#endif /* DRAGONEGG_OS_H */
diff -r -u -N dragonegg-2.9-old/Debug.cpp dragonegg-2.9-new/Debug.cpp
--- dragonegg-2.9-old/Debug.cpp 2011-03-10 17:05:54.000000000 +0100
+++ dragonegg-2.9-new/Debug.cpp 2011-04-09 00:38:06.620098051 +0200
@@ -22,7 +22,7 @@
//===----------------------------------------------------------------------===//
// Plugin headers
-#include "Debug.h"
+#include "dragonegg/Debug.h"
// LLVM headers
#include "llvm/Module.h"
diff -r -u -N dragonegg-2.9-old/Debug.h dragonegg-2.9-new/Debug.h
--- dragonegg-2.9-old/Debug.h 2011-03-29 12:46:17.000000000 +0200
+++ dragonegg-2.9-new/Debug.h 1970-01-01 01:00:00.000000000 +0100
@@ -1,367 +0,0 @@
-//===------ Debug.h - Interface for generating debug info -------*- C++ -*-===//
-//
-// Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Jim Laskey, Duncan Sands
-// et al.
-//
-// This file is part of DragonEgg.
-//
-// DragonEgg is free software; you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free Software
-// Foundation; either version 2, or (at your option) any later version.
-//
-// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along with
-// DragonEgg; see the file COPYING. If not, write to the Free Software
-// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
-//
-//===----------------------------------------------------------------------===//
-// This file declares the debug interfaces shared among the dragonegg files.
-//===----------------------------------------------------------------------===//
-
-#ifndef DRAGONEGG_DEBUG_H
-#define DRAGONEGG_DEBUG_H
-
-// Plugin headers
-#include "Internals.h"
-
-// LLVM headers
-#include "llvm/Analysis/DebugInfo.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/ValueHandle.h"
-
-// System headers
-#include <map>
-
-namespace llvm {
-
-// Forward declarations
-class AllocaInst;
-class BasicBlock;
-class CallInst;
-class Function;
-class Module;
-
-/// DIFactory - This object assists with the construction of the various
-/// descriptors.
-class DIFactory {
- Module &M;
- LLVMContext& VMContext;
-
- Function *DeclareFn; // llvm.dbg.declare
- Function *ValueFn; // llvm.dbg.value
-
- DIFactory(const DIFactory &); // DO NOT IMPLEMENT
- void operator=(const DIFactory&); // DO NOT IMPLEMENT
- public:
- enum ComplexAddrKind { OpPlus=1, OpDeref };
-
- explicit DIFactory(Module &m);
-
- /// GetOrCreateArray - Create an descriptor for an array of descriptors.
- /// This implicitly uniques the arrays created.
- DIArray GetOrCreateArray(DIDescriptor *Tys, unsigned NumTys);
-
- /// GetOrCreateSubrange - Create a descriptor for a value range. This
- /// implicitly uniques the values returned.
- DISubrange GetOrCreateSubrange(int64_t Lo, int64_t Hi);
-
- /// CreateUnspecifiedParameter - Create unspeicified type descriptor
- /// for a subroutine type.
- DIDescriptor CreateUnspecifiedParameter();
-
- /// CreateCompileUnit - Create a new descriptor for the specified compile
- /// unit.
- DICompileUnit CreateCompileUnit(unsigned LangID,
- StringRef Filename,
- StringRef Directory,
- StringRef Producer,
- bool isMain = false,
- bool isOptimized = false,
- StringRef Flags = "",
- unsigned RunTimeVer = 0);
-
- /// CreateFile - Create a new descriptor for the specified file.
- DIFile CreateFile(StringRef Filename, StringRef Directory,
- DICompileUnit CU);
-
- /// CreateEnumerator - Create a single enumerator value.
- DIEnumerator CreateEnumerator(StringRef Name, uint64_t Val);
-
- /// CreateBasicType - Create a basic type like int, float, etc.
- DIBasicType CreateBasicType(DIDescriptor Context, StringRef Name,
- DIFile F, unsigned LineNumber,
- uint64_t SizeInBits, uint64_t AlignInBits,
- uint64_t OffsetInBits, unsigned Flags,
- unsigned Encoding);
-
- /// CreateBasicType - Create a basic type like int, float, etc.
- DIBasicType CreateBasicTypeEx(DIDescriptor Context, StringRef Name,
- DIFile F, unsigned LineNumber,
- Constant *SizeInBits, Constant *AlignInBits,
- Constant *OffsetInBits, unsigned Flags,
- unsigned Encoding);
-
- /// CreateDerivedType - Create a derived type like const qualified type,
- /// pointer, typedef, etc.
- DIDerivedType CreateDerivedType(unsigned Tag, DIDescriptor Context,
- StringRef Name,
- DIFile F,
- unsigned LineNumber,
- uint64_t SizeInBits, uint64_t AlignInBits,
- uint64_t OffsetInBits, unsigned Flags,
- DIType DerivedFrom);
-
- /// CreateDerivedType - Create a derived type like const qualified type,
- /// pointer, typedef, etc.
- DIDerivedType CreateDerivedTypeEx(unsigned Tag, DIDescriptor Context,
- StringRef Name,
- DIFile F,
- unsigned LineNumber,
- Constant *SizeInBits,
- Constant *AlignInBits,
- Constant *OffsetInBits, unsigned Flags,
- DIType DerivedFrom);
-
- /// CreateCompositeType - Create a composite type like array, struct, etc.
- DICompositeType CreateCompositeType(unsigned Tag, DIDescriptor Context,
- StringRef Name,
- DIFile F,
- unsigned LineNumber,
- uint64_t SizeInBits,
- uint64_t AlignInBits,
- uint64_t OffsetInBits, unsigned Flags,
- DIType DerivedFrom,
- DIArray Elements,
- unsigned RunTimeLang = 0,
- MDNode *ContainingType = 0);
-
- /// CreateTemporaryType - Create a temporary forward-declared type.
- DIType CreateTemporaryType();
- DIType CreateTemporaryType(DIFile F);
-
- /// CreateArtificialType - Create a new DIType with "artificial" flag set.
- DIType CreateArtificialType(DIType Ty);
-
- /// CreateCompositeType - Create a composite type like array, struct, etc.
- DICompositeType CreateCompositeTypeEx(unsigned Tag, DIDescriptor Context,
- StringRef Name,
- DIFile F,
- unsigned LineNumber,
- Constant *SizeInBits,
- Constant *AlignInBits,
- Constant *OffsetInBits,
- unsigned Flags,
- DIType DerivedFrom,
- DIArray Elements,
- unsigned RunTimeLang = 0,
- MDNode *ContainingType = 0);
-
- /// CreateSubprogram - Create a new descriptor for the specified subprogram.
- /// See comments in DISubprogram for descriptions of these fields.
- DISubprogram CreateSubprogram(DIDescriptor Context, StringRef Name,
- StringRef DisplayName,
- StringRef LinkageName,
- DIFile F, unsigned LineNo,
- DIType Ty, bool isLocalToUnit,
- bool isDefinition,
- unsigned VK = 0,
- unsigned VIndex = 0,
- DIType ContainingType = DIType(),
- unsigned Flags = 0,
- bool isOptimized = false,
- Function *Fn = 0);
-
- /// CreateSubprogramDefinition - Create new subprogram descriptor for the
- /// given declaration.
- DISubprogram CreateSubprogramDefinition(DISubprogram &SPDeclaration);
-
- /// CreateGlobalVariable - Create a new descriptor for the specified global.
- DIGlobalVariable
- CreateGlobalVariable(DIDescriptor Context, StringRef Name,
- StringRef DisplayName,
- StringRef LinkageName,
- DIFile F,
- unsigned LineNo, DIType Ty, bool isLocalToUnit,
- bool isDefinition, llvm::GlobalVariable *GV);
-
- /// CreateGlobalVariable - Create a new descriptor for the specified constant.
- DIGlobalVariable
- CreateGlobalVariable(DIDescriptor Context, StringRef Name,
- StringRef DisplayName,
- StringRef LinkageName,
- DIFile F,
- unsigned LineNo, DIType Ty, bool isLocalToUnit,
- bool isDefinition, llvm::Constant *C);
-
- /// CreateVariable - Create a new descriptor for the specified variable.
- DIVariable CreateVariable(unsigned Tag, DIDescriptor Context,
- StringRef Name,
- DIFile F, unsigned LineNo,
- DIType Ty, bool AlwaysPreserve = false,
- unsigned Flags = 0);
-
- /// CreateComplexVariable - Create a new descriptor for the specified
- /// variable which has a complex address expression for its address.
- DIVariable CreateComplexVariable(unsigned Tag, DIDescriptor Context,
- StringRef Name, DIFile F, unsigned LineNo,
- DIType Ty, Value *const *Addr,
- unsigned NumAddr);
-
- /// CreateLexicalBlock - This creates a descriptor for a lexical block
- /// with the specified parent context.
- DILexicalBlock CreateLexicalBlock(DIDescriptor Context, DIFile F,
- unsigned Line = 0, unsigned Col = 0);
-
- /// CreateNameSpace - This creates new descriptor for a namespace
- /// with the specified parent context.
- DINameSpace CreateNameSpace(DIDescriptor Context, StringRef Name,
- DIFile F, unsigned LineNo);
-
- /// CreateLocation - Creates a debug info location.
- DILocation CreateLocation(unsigned LineNo, unsigned ColumnNo,
- DIScope S, DILocation OrigLoc);
-
- /// CreateLocation - Creates a debug info location.
- DILocation CreateLocation(unsigned LineNo, unsigned ColumnNo,
- DIScope S, MDNode *OrigLoc = 0);
-
- /// InsertDeclare - Insert a new llvm.dbg.declare intrinsic call.
- Instruction *InsertDeclare(llvm::Value *Storage, DIVariable D,
- BasicBlock *InsertAtEnd);
-
- /// InsertDeclare - Insert a new llvm.dbg.declare intrinsic call.
- Instruction *InsertDeclare(llvm::Value *Storage, DIVariable D,
- Instruction *InsertBefore);
-
- /// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
- Instruction *InsertDbgValueIntrinsic(llvm::Value *V, uint64_t Offset,
- DIVariable D, BasicBlock *InsertAtEnd);
-
- /// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
- Instruction *InsertDbgValueIntrinsic(llvm::Value *V, uint64_t Offset,
- DIVariable D, Instruction *InsertBefore);
-
- // RecordType - Record DIType in a module such that it is not lost even if
- // it is not referenced through debug info anchors.
- void RecordType(DIType T);
-
- private:
- Constant *GetTagConstant(unsigned TAG);
-};
-
-/// DebugInfo - This class gathers all debug information during compilation and
-/// is responsible for emitting to llvm globals or pass directly to the backend.
-class DebugInfo {
-private:
- Module *M; // The current module.
- DIFactory DebugFactory;
- const char *CurFullPath; // Previous location file encountered.
- int CurLineNo; // Previous location line# encountered.
- const char *PrevFullPath; // Previous location file encountered.
- int PrevLineNo; // Previous location line# encountered.
- BasicBlock *PrevBB; // Last basic block encountered.
-
- DICompileUnit TheCU; // The compile unit.
-
- std::map<tree_node *, WeakVH > TypeCache;
- // Cache of previously constructed
- // Types.
- std::map<tree_node *, WeakVH > SPCache;
- // Cache of previously constructed
- // Subprograms.
- std::map<tree_node *, WeakVH> NameSpaceCache;
- // Cache of previously constructed name
- // spaces.
-
- SmallVector<WeakVH, 4> RegionStack;
- // Stack to track declarative scopes.
-
- std::map<tree_node *, WeakVH> RegionMap;
-
- /// FunctionNames - This is a storage for function names that are
- /// constructed on demand. For example, C++ destructors, C++ operators etc..
- llvm::BumpPtrAllocator FunctionNames;
-
-public:
- DebugInfo(Module *m);
-
- /// Initialize - Initialize debug info by creating compile unit for
- /// main_input_filename. This must be invoked after language dependent
- /// initialization is done.
- void Initialize();
-
- // Accessors.
- void setLocationFile(const char *FullPath) { CurFullPath = FullPath; }
- void setLocationLine(int LineNo) { CurLineNo = LineNo; }
-
- /// EmitFunctionStart - Constructs the debug code for entering a function -
- /// "llvm.dbg.func.start."
- void EmitFunctionStart(tree_node *FnDecl, Function *Fn);
-
- /// EmitFunctionEnd - Constructs the debug code for exiting a declarative
- /// region - "llvm.dbg.region.end."
- void EmitFunctionEnd(bool EndFunction);
-
- /// EmitDeclare - Constructs the debug code for allocation of a new variable.
- /// region - "llvm.dbg.declare."
- void EmitDeclare(tree_node *decl, unsigned Tag, const char *Name,
- tree_node *type, Value *AI, LLVMBuilder &Builder);
-
- /// EmitStopPoint - Emit a call to llvm.dbg.stoppoint to indicate a change of
- /// source line.
- void EmitStopPoint(BasicBlock *CurBB, LLVMBuilder &Builder);
-
- /// EmitGlobalVariable - Emit information about a global variable.
- ///
- void EmitGlobalVariable(GlobalVariable *GV, tree_node *decl);
-
- /// getOrCreateType - Get the type from the cache or create a new type if
- /// necessary.
- DIType getOrCreateType(tree_node *type);
-
- /// createBasicType - Create BasicType.
- DIType createBasicType(tree_node *type);
-
- /// createMethodType - Create MethodType.
- DIType createMethodType(tree_node *type);
-
- /// createPointerType - Create PointerType.
- DIType createPointerType(tree_node *type);
-
- /// createArrayType - Create ArrayType.
- DIType createArrayType(tree_node *type);
-
- /// createEnumType - Create EnumType.
- DIType createEnumType(tree_node *type);
-
- /// createStructType - Create StructType for struct or union or class.
- DIType createStructType(tree_node *type);
-
- /// createVarinatType - Create variant type or return MainTy.
- DIType createVariantType(tree_node *type, DIType MainTy);
-
- /// getOrCreateCompileUnit - Create a new compile unit.
- DICompileUnit getOrCreateCompileUnit(const char *FullPath,
- bool isMain = false);
-
- /// getOrCreateFile - Get DIFile descriptor.
- DIFile getOrCreateFile(const char *FullPath);
-
- /// findRegion - Find tree_node N's region.
- DIDescriptor findRegion(tree_node *n);
-
- /// getOrCreateNameSpace - Get name space descriptor for the tree node.
- DINameSpace getOrCreateNameSpace(tree_node *Node, DIDescriptor Context);
-
- /// getFunctionName - Get function name for the given FnDecl. If the
- /// name is constructred on demand (e.g. C++ destructor) then the name
- /// is stored on the side.
- StringRef getFunctionName(tree_node *FnDecl);
-};
-
-} // end namespace llvm
-
-#endif /* DRAGONEGG_DEBUG_H */
diff -r -u -N dragonegg-2.9-old/DefaultABI.cpp dragonegg-2.9-new/DefaultABI.cpp
--- dragonegg-2.9-old/DefaultABI.cpp 2011-03-10 17:05:54.000000000 +0100
+++ dragonegg-2.9-new/DefaultABI.cpp 2011-04-09 00:38:06.620098051 +0200
@@ -21,7 +21,7 @@
//===----------------------------------------------------------------------===//
// Plugin headers
-#include "ABI.h"
+#include "dragonegg/ABI.h"
// System headers
#include <gmp.h>
diff -r -u -N dragonegg-2.9-old/freebsd/dragonegg/OS.h dragonegg-2.9-new/freebsd/dragonegg/OS.h
--- dragonegg-2.9-old/freebsd/dragonegg/OS.h 1970-01-01 01:00:00.000000000 +0100
+++ dragonegg-2.9-new/freebsd/dragonegg/OS.h 2011-04-09 00:38:06.620098051 +0200
@@ -0,0 +1,33 @@
+//===------------ OS.h - FreeBSD specific definitions -----------*- C++ -*-===//
+//
+// Copyright (C) 2009, 2010, 2011 Duncan Sands et al.
+//
+// This file is part of DragonEgg.
+//
+// DragonEgg is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free Software
+// Foundation; either version 2, or (at your option) any later version.
+//
+// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along with
+// DragonEgg; see the file COPYING. If not, write to the Free Software
+// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
+//
+//===----------------------------------------------------------------------===//
+// This file provides FreeBSD specific declarations.
+//===----------------------------------------------------------------------===//
+
+#ifndef DRAGONEGG_OS_H
+#define DRAGONEGG_OS_H
+
+/* Yes, we support PIC codegen for FreeBSD targets! */
+#define LLVM_SET_TARGET_OPTIONS(argvec) \
+ if (flag_pic) \
+ argvec.push_back ("--relocation-model=pic"); \
+ else \
+ argvec.push_back ("--relocation-model=static");
+
+#endif /* DRAGONEGG_OS_H */
diff -r -u -N dragonegg-2.9-old/freebsd/OS.h dragonegg-2.9-new/freebsd/OS.h
--- dragonegg-2.9-old/freebsd/OS.h 2011-03-28 17:04:33.000000000 +0200
+++ dragonegg-2.9-new/freebsd/OS.h 1970-01-01 01:00:00.000000000 +0100
@@ -1,33 +0,0 @@
-//===------------ OS.h - FreeBSD specific definitions -----------*- C++ -*-===//
-//
-// Copyright (C) 2009, 2010, 2011 Duncan Sands et al.
-//
-// This file is part of DragonEgg.
-//
-// DragonEgg is free software; you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free Software
-// Foundation; either version 2, or (at your option) any later version.
-//
-// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along with
-// DragonEgg; see the file COPYING. If not, write to the Free Software
-// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
-//
-//===----------------------------------------------------------------------===//
-// This file provides FreeBSD specific declarations.
-//===----------------------------------------------------------------------===//
-
-#ifndef DRAGONEGG_OS_H
-#define DRAGONEGG_OS_H
-
-/* Yes, we support PIC codegen for FreeBSD targets! */
-#define LLVM_SET_TARGET_OPTIONS(argvec) \
- if (flag_pic) \
- argvec.push_back ("--relocation-model=pic"); \
- else \
- argvec.push_back ("--relocation-model=static");
-
-#endif /* DRAGONEGG_OS_H */
diff -r -u -N dragonegg-2.9-old/gt-cache.h dragonegg-2.9-new/gt-cache.h
--- dragonegg-2.9-old/gt-cache.h 2011-03-10 17:05:54.000000000 +0100
+++ dragonegg-2.9-new/gt-cache.h 1970-01-01 01:00:00.000000000 +0100
@@ -1,802 +0,0 @@
-/* Type information for GCC.
- Copyright (C) 2004, 2007, 2009 Free Software Foundation, Inc.
-
-This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 3, or (at your option) any later
-version.
-
-GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3. If not see
-<http://www.gnu.org/licenses/>. */
-
-/* This file is machine generated. Do not edit. */
-
-/* GC marker procedures. */
-/* macros and declarations */
-#define gt_ggc_m_13tree_llvm_map(X) do { \
- if (X != NULL) gt_ggc_mx_tree_llvm_map (X);\
- } while (0)
-extern void gt_ggc_mx_tree_llvm_map (void *);
-#define gt_ggc_m_15interface_tuple(X) do { \
- if (X != NULL) gt_ggc_mx_interface_tuple (X);\
- } while (0)
-extern void gt_ggc_mx_interface_tuple (void *);
-#define gt_ggc_m_16volatilized_type(X) do { \
- if (X != NULL) gt_ggc_mx_volatilized_type (X);\
- } while (0)
-extern void gt_ggc_mx_volatilized_type (void *);
-#define gt_ggc_m_17string_descriptor(X) do { \
- if (X != NULL) gt_ggc_mx_string_descriptor (X);\
- } while (0)
-extern void gt_ggc_mx_string_descriptor (void *);
-#define gt_ggc_m_15c_inline_static(X) do { \
- if (X != NULL) gt_ggc_mx_c_inline_static (X);\
- } while (0)
-extern void gt_ggc_mx_c_inline_static (void *);
-#define gt_ggc_m_24VEC_c_goto_bindings_p_gc(X) do { \
- if (X != NULL) gt_ggc_mx_VEC_c_goto_bindings_p_gc (X);\
- } while (0)
-extern void gt_ggc_mx_VEC_c_goto_bindings_p_gc (void *);
-#define gt_ggc_m_15c_goto_bindings(X) do { \
- if (X != NULL) gt_ggc_mx_c_goto_bindings (X);\
- } while (0)
-extern void gt_ggc_mx_c_goto_bindings (void *);
-#define gt_ggc_m_7c_scope(X) do { \
- if (X != NULL) gt_ggc_mx_c_scope (X);\
- } while (0)
-extern void gt_ggc_mx_c_scope (void *);
-#define gt_ggc_m_9c_binding(X) do { \
- if (X != NULL) gt_ggc_mx_c_binding (X);\
- } while (0)
-extern void gt_ggc_mx_c_binding (void *);
-#define gt_ggc_m_12c_label_vars(X) do { \
- if (X != NULL) gt_ggc_mx_c_label_vars (X);\
- } while (0)
-extern void gt_ggc_mx_c_label_vars (void *);
-#define gt_ggc_m_8c_parser(X) do { \
- if (X != NULL) gt_ggc_mx_c_parser (X);\
- } while (0)
-extern void gt_ggc_mx_c_parser (void *);
-#define gt_ggc_m_9imp_entry(X) do { \
- if (X != NULL) gt_ggc_mx_imp_entry (X);\
- } while (0)
-extern void gt_ggc_mx_imp_entry (void *);
-#define gt_ggc_m_16hashed_attribute(X) do { \
- if (X != NULL) gt_ggc_mx_hashed_attribute (X);\
- } while (0)
-extern void gt_ggc_mx_hashed_attribute (void *);
-#define gt_ggc_m_12hashed_entry(X) do { \
- if (X != NULL) gt_ggc_mx_hashed_entry (X);\
- } while (0)
-extern void gt_ggc_mx_hashed_entry (void *);
-#define gt_ggc_m_14type_assertion(X) do { \
- if (X != NULL) gt_ggc_mx_type_assertion (X);\
- } while (0)
-extern void gt_ggc_mx_type_assertion (void *);
-#define gt_ggc_m_18treetreehash_entry(X) do { \
- if (X != NULL) gt_ggc_mx_treetreehash_entry (X);\
- } while (0)
-extern void gt_ggc_mx_treetreehash_entry (void *);
-#define gt_ggc_m_5CPool(X) do { \
- if (X != NULL) gt_ggc_mx_CPool (X);\
- } while (0)
-extern void gt_ggc_mx_CPool (void *);
-#define gt_ggc_m_3JCF(X) do { \
- if (X != NULL) gt_ggc_mx_JCF (X);\
- } while (0)
-extern void gt_ggc_mx_JCF (void *);
-#define gt_ggc_m_17module_htab_entry(X) do { \
- if (X != NULL) gt_ggc_mx_module_htab_entry (X);\
- } while (0)
-extern void gt_ggc_mx_module_htab_entry (void *);
-#define gt_ggc_m_13binding_level(X) do { \
- if (X != NULL) gt_ggc_mx_binding_level (X);\
- } while (0)
-extern void gt_ggc_mx_binding_level (void *);
-#define gt_ggc_m_9opt_stack(X) do { \
- if (X != NULL) gt_ggc_mx_opt_stack (X);\
- } while (0)
-extern void gt_ggc_mx_opt_stack (void *);
-#define gt_ggc_m_16def_pragma_macro(X) do { \
- if (X != NULL) gt_ggc_mx_def_pragma_macro (X);\
- } while (0)
-extern void gt_ggc_mx_def_pragma_macro (void *);
-#define gt_ggc_m_22def_pragma_macro_value(X) do { \
- if (X != NULL) gt_ggc_mx_def_pragma_macro_value (X);\
- } while (0)
-extern void gt_ggc_mx_def_pragma_macro_value (void *);
-#define gt_ggc_m_11align_stack(X) do { \
- if (X != NULL) gt_ggc_mx_align_stack (X);\
- } while (0)
-extern void gt_ggc_mx_align_stack (void *);
-#define gt_ggc_m_18VEC_tree_gc_vec_gc(X) do { \
- if (X != NULL) gt_ggc_mx_VEC_tree_gc_vec_gc (X);\
- } while (0)
-extern void gt_ggc_mx_VEC_tree_gc_vec_gc (void *);
-#define gt_ggc_m_19VEC_const_char_p_gc(X) do { \
- if (X != NULL) gt_ggc_mx_VEC_const_char_p_gc (X);\
- } while (0)
-extern void gt_ggc_mx_VEC_const_char_p_gc (void *);
-#define gt_ggc_m_21pending_abstract_type(X) do { \
- if (X != NULL) gt_ggc_mx_pending_abstract_type (X);\
- } while (0)
-extern void gt_ggc_mx_pending_abstract_type (void *);
-#define gt_ggc_m_15VEC_tree_int_gc(X) do { \
- if (X != NULL) gt_ggc_mx_VEC_tree_int_gc (X);\
- } while (0)
-extern void gt_ggc_mx_VEC_tree_int_gc (void *);
-#define gt_ggc_m_9cp_parser(X) do { \
- if (X != NULL) gt_ggc_mx_cp_parser (X);\
- } while (0)
-extern void gt_ggc_mx_cp_parser (void *);
-#define gt_ggc_m_17cp_parser_context(X) do { \
- if (X != NULL) gt_ggc_mx_cp_parser_context (X);\
- } while (0)
-extern void gt_ggc_mx_cp_parser_context (void *);
-#define gt_ggc_m_8cp_lexer(X) do { \
- if (X != NULL) gt_ggc_mx_cp_lexer (X);\
- } while (0)
-extern void gt_ggc_mx_cp_lexer (void *);
-#define gt_ggc_m_10tree_check(X) do { \
- if (X != NULL) gt_ggc_mx_tree_check (X);\
- } while (0)
-extern void gt_ggc_mx_tree_check (void *);
-#define gt_ggc_m_22VEC_deferred_access_gc(X) do { \
- if (X != NULL) gt_ggc_mx_VEC_deferred_access_gc (X);\
- } while (0)
-extern void gt_ggc_mx_VEC_deferred_access_gc (void *);
-#define gt_ggc_m_10spec_entry(X) do { \
- if (X != NULL) gt_ggc_mx_spec_entry (X);\
- } while (0)
-extern void gt_ggc_mx_spec_entry (void *);
-#define gt_ggc_m_16pending_template(X) do { \
- if (X != NULL) gt_ggc_mx_pending_template (X);\
- } while (0)
-extern void gt_ggc_mx_pending_template (void *);
-#define gt_ggc_m_21named_label_use_entry(X) do { \
- if (X != NULL) gt_ggc_mx_named_label_use_entry (X);\
- } while (0)
-extern void gt_ggc_mx_named_label_use_entry (void *);
-#define gt_ggc_m_28VEC_deferred_access_check_gc(X) do { \
- if (X != NULL) gt_ggc_mx_VEC_deferred_access_check_gc (X);\
- } while (0)
-extern void gt_ggc_mx_VEC_deferred_access_check_gc (void *);
-#define gt_ggc_m_11tinst_level(X) do { \
- if (X != NULL) gt_ggc_mx_tinst_level (X);\
- } while (0)
-extern void gt_ggc_mx_tinst_level (void *);
-#define gt_ggc_m_18sorted_fields_type(X) do { \
- if (X != NULL) gt_ggc_mx_sorted_fields_type (X);\
- } while (0)
-extern void gt_ggc_mx_sorted_fields_type (void *);
-#define gt_ggc_m_18VEC_tree_pair_s_gc(X) do { \
- if (X != NULL) gt_ggc_mx_VEC_tree_pair_s_gc (X);\
- } while (0)
-extern void gt_ggc_mx_VEC_tree_pair_s_gc (void *);
-#define gt_ggc_m_17named_label_entry(X) do { \
- if (X != NULL) gt_ggc_mx_named_label_entry (X);\
- } while (0)
-extern void gt_ggc_mx_named_label_entry (void *);
-#define gt_ggc_m_14cp_token_cache(X) do { \
- if (X != NULL) gt_ggc_mx_cp_token_cache (X);\
- } while (0)
-extern void gt_ggc_mx_cp_token_cache (void *);
-#define gt_ggc_m_11saved_scope(X) do { \
- if (X != NULL) gt_ggc_mx_saved_scope (X);\
- } while (0)
-extern void gt_ggc_mx_saved_scope (void *);
-#define gt_ggc_m_16cxx_int_tree_map(X) do { \
- if (X != NULL) gt_ggc_mx_cxx_int_tree_map (X);\
- } while (0)
-extern void gt_ggc_mx_cxx_int_tree_map (void *);
-#define gt_ggc_m_23VEC_cp_class_binding_gc(X) do { \
- if (X != NULL) gt_ggc_mx_VEC_cp_class_binding_gc (X);\
- } while (0)
-extern void gt_ggc_mx_VEC_cp_class_binding_gc (void *);
-#define gt_ggc_m_24VEC_cxx_saved_binding_gc(X) do { \
- if (X != NULL) gt_ggc_mx_VEC_cxx_saved_binding_gc (X);\
- } while (0)
-extern void gt_ggc_mx_VEC_cxx_saved_binding_gc (void *);
-#define gt_ggc_m_16cp_binding_level(X) do { \
- if (X != NULL) gt_ggc_mx_cp_binding_level (X);\
- } while (0)
-extern void gt_ggc_mx_cp_binding_level (void *);
-#define gt_ggc_m_11cxx_binding(X) do { \
- if (X != NULL) gt_ggc_mx_cxx_binding (X);\
- } while (0)
-extern void gt_ggc_mx_cxx_binding (void *);
-#define gt_ggc_m_15binding_entry_s(X) do { \
- if (X != NULL) gt_ggc_mx_binding_entry_s (X);\
- } while (0)
-extern void gt_ggc_mx_binding_entry_s (void *);
-#define gt_ggc_m_15binding_table_s(X) do { \
- if (X != NULL) gt_ggc_mx_binding_table_s (X);\
- } while (0)
-extern void gt_ggc_mx_binding_table_s (void *);
-#define gt_ggc_m_14VEC_tinfo_s_gc(X) do { \
- if (X != NULL) gt_ggc_mx_VEC_tinfo_s_gc (X);\
- } while (0)
-extern void gt_ggc_mx_VEC_tinfo_s_gc (void *);
-#define gt_ggc_m_18gnat_binding_level(X) do { \
- if (X != NULL) gt_ggc_mx_gnat_binding_level (X);\
- } while (0)
-extern void gt_ggc_mx_gnat_binding_level (void *);
-#define gt_ggc_m_9elab_info(X) do { \
- if (X != NULL) gt_ggc_mx_elab_info (X);\
- } while (0)
-extern void gt_ggc_mx_elab_info (void *);
-#define gt_ggc_m_10stmt_group(X) do { \
- if (X != NULL) gt_ggc_mx_stmt_group (X);\
- } while (0)
-extern void gt_ggc_mx_stmt_group (void *);
-#define gt_ggc_m_16VEC_parm_attr_gc(X) do { \
- if (X != NULL) gt_ggc_mx_VEC_parm_attr_gc (X);\
- } while (0)
-extern void gt_ggc_mx_VEC_parm_attr_gc (void *);
-#define gt_ggc_m_11parm_attr_d(X) do { \
- if (X != NULL) gt_ggc_mx_parm_attr_d (X);\
- } while (0)
-extern void gt_ggc_mx_parm_attr_d (void *);
-#define gt_ggc_m_22VEC_ipa_edge_args_t_gc(X) do { \
- if (X != NULL) gt_ggc_mx_VEC_ipa_edge_args_t_gc (X);\
- } while (0)
-extern void gt_ggc_mx_VEC_ipa_edge_args_t_gc (void *);
-#define gt_ggc_m_20lto_symtab_entry_def(X) do { \
- if (X != NULL) gt_ggc_mx_lto_symtab_entry_def (X);\
- } while (0)
-extern void gt_ggc_mx_lto_symtab_entry_def (void *);
-#define gt_ggc_m_20ssa_operand_memory_d(X) do { \
- if (X != NULL) gt_ggc_mx_ssa_operand_memory_d (X);\
- } while (0)
-extern void gt_ggc_mx_ssa_operand_memory_d (void *);
-#define gt_ggc_m_13scev_info_str(X) do { \
- if (X != NULL) gt_ggc_mx_scev_info_str (X);\
- } while (0)
-extern void gt_ggc_mx_scev_info_str (void *);
-#define gt_ggc_m_13VEC_gimple_gc(X) do { \
- if (X != NULL) gt_ggc_mx_VEC_gimple_gc (X);\
- } while (0)
-extern void gt_ggc_mx_VEC_gimple_gc (void *);
-#define gt_ggc_m_9type_hash(X) do { \
- if (X != NULL) gt_ggc_mx_type_hash (X);\
- } while (0)
-extern void gt_ggc_mx_type_hash (void *);
-#define gt_ggc_m_16string_pool_data(X) do { \
- if (X != NULL) gt_ggc_mx_string_pool_data (X);\
- } while (0)
-extern void gt_ggc_mx_string_pool_data (void *);
-#define gt_ggc_m_13libfunc_entry(X) do { \
- if (X != NULL) gt_ggc_mx_libfunc_entry (X);\
- } while (0)
-extern void gt_ggc_mx_libfunc_entry (void *);
-#define gt_ggc_m_23temp_slot_address_entry(X) do { \
- if (X != NULL) gt_ggc_mx_temp_slot_address_entry (X);\
- } while (0)
-extern void gt_ggc_mx_temp_slot_address_entry (void *);
-#define gt_ggc_m_15throw_stmt_node(X) do { \
- if (X != NULL) gt_ggc_mx_throw_stmt_node (X);\
- } while (0)
-extern void gt_ggc_mx_throw_stmt_node (void *);
-#define gt_ggc_m_21VEC_eh_landing_pad_gc(X) do { \
- if (X != NULL) gt_ggc_mx_VEC_eh_landing_pad_gc (X);\
- } while (0)
-extern void gt_ggc_mx_VEC_eh_landing_pad_gc (void *);
-#define gt_ggc_m_16VEC_eh_region_gc(X) do { \
- if (X != NULL) gt_ggc_mx_VEC_eh_region_gc (X);\
- } while (0)
-extern void gt_ggc_mx_VEC_eh_region_gc (void *);
-#define gt_ggc_m_10eh_catch_d(X) do { \
- if (X != NULL) gt_ggc_mx_eh_catch_d (X);\
- } while (0)
-extern void gt_ggc_mx_eh_catch_d (void *);
-#define gt_ggc_m_16eh_landing_pad_d(X) do { \
- if (X != NULL) gt_ggc_mx_eh_landing_pad_d (X);\
- } while (0)
-extern void gt_ggc_mx_eh_landing_pad_d (void *);
-#define gt_ggc_m_11eh_region_d(X) do { \
- if (X != NULL) gt_ggc_mx_eh_region_d (X);\
- } while (0)
-extern void gt_ggc_mx_eh_region_d (void *);
-#define gt_ggc_m_10vcall_insn(X) do { \
- if (X != NULL) gt_ggc_mx_vcall_insn (X);\
- } while (0)
-extern void gt_ggc_mx_vcall_insn (void *);
-#define gt_ggc_m_18VEC_vcall_entry_gc(X) do { \
- if (X != NULL) gt_ggc_mx_VEC_vcall_entry_gc (X);\
- } while (0)
-extern void gt_ggc_mx_VEC_vcall_entry_gc (void *);
-#define gt_ggc_m_18VEC_dcall_entry_gc(X) do { \
- if (X != NULL) gt_ggc_mx_VEC_dcall_entry_gc (X);\
- } while (0)
-extern void gt_ggc_mx_VEC_dcall_entry_gc (void *);
-#define gt_ggc_m_16var_loc_list_def(X) do { \
- if (X != NULL) gt_ggc_mx_var_loc_list_def (X);\
- } while (0)
-extern void gt_ggc_mx_var_loc_list_def (void *);
-#define gt_ggc_m_12var_loc_node(X) do { \
- if (X != NULL) gt_ggc_mx_var_loc_node (X);\
- } while (0)
-extern void gt_ggc_mx_var_loc_node (void *);
-#define gt_ggc_m_20VEC_die_arg_entry_gc(X) do { \
- if (X != NULL) gt_ggc_mx_VEC_die_arg_entry_gc (X);\
- } while (0)
-extern void gt_ggc_mx_VEC_die_arg_entry_gc (void *);
-#define gt_ggc_m_16limbo_die_struct(X) do { \
- if (X != NULL) gt_ggc_mx_limbo_die_struct (X);\
- } while (0)
-extern void gt_ggc_mx_limbo_die_struct (void *);
-#define gt_ggc_m_20VEC_pubname_entry_gc(X) do { \
- if (X != NULL) gt_ggc_mx_VEC_pubname_entry_gc (X);\
- } while (0)
-extern void gt_ggc_mx_VEC_pubname_entry_gc (void *);
-#define gt_ggc_m_19VEC_dw_attr_node_gc(X) do { \
- if (X != NULL) gt_ggc_mx_VEC_dw_attr_node_gc (X);\
- } while (0)
-extern void gt_ggc_mx_VEC_dw_attr_node_gc (void *);
-#define gt_ggc_m_18comdat_type_struct(X) do { \
- if (X != NULL) gt_ggc_mx_comdat_type_struct (X);\
- } while (0)
-extern void gt_ggc_mx_comdat_type_struct (void *);
-#define gt_ggc_m_25dw_ranges_by_label_struct(X) do { \
- if (X != NULL) gt_ggc_mx_dw_ranges_by_label_struct (X);\
- } while (0)
-extern void gt_ggc_mx_dw_ranges_by_label_struct (void *);
-#define gt_ggc_m_16dw_ranges_struct(X) do { \
- if (X != NULL) gt_ggc_mx_dw_ranges_struct (X);\
- } while (0)
-extern void gt_ggc_mx_dw_ranges_struct (void *);
-#define gt_ggc_m_28dw_separate_line_info_struct(X) do { \
- if (X != NULL) gt_ggc_mx_dw_separate_line_info_struct (X);\
- } while (0)
-extern void gt_ggc_mx_dw_separate_line_info_struct (void *);
-#define gt_ggc_m_19dw_line_info_struct(X) do { \
- if (X != NULL) gt_ggc_mx_dw_line_info_struct (X);\
- } while (0)
-extern void gt_ggc_mx_dw_line_info_struct (void *);
-#define gt_ggc_m_25VEC_deferred_locations_gc(X) do { \
- if (X != NULL) gt_ggc_mx_VEC_deferred_locations_gc (X);\
- } while (0)
-extern void gt_ggc_mx_VEC_deferred_locations_gc (void *);
-#define gt_ggc_m_18dw_loc_list_struct(X) do { \
- if (X != NULL) gt_ggc_mx_dw_loc_list_struct (X);\
- } while (0)
-extern void gt_ggc_mx_dw_loc_list_struct (void *);
-#define gt_ggc_m_15dwarf_file_data(X) do { \
- if (X != NULL) gt_ggc_mx_dwarf_file_data (X);\
- } while (0)
-extern void gt_ggc_mx_dwarf_file_data (void *);
-#define gt_ggc_m_15queued_reg_save(X) do { \
- if (X != NULL) gt_ggc_mx_queued_reg_save (X);\
- } while (0)
-extern void gt_ggc_mx_queued_reg_save (void *);
-#define gt_ggc_m_20indirect_string_node(X) do { \
- if (X != NULL) gt_ggc_mx_indirect_string_node (X);\
- } while (0)
-extern void gt_ggc_mx_indirect_string_node (void *);
-#define gt_ggc_m_19dw_loc_descr_struct(X) do { \
- if (X != NULL) gt_ggc_mx_dw_loc_descr_struct (X);\
- } while (0)
-extern void gt_ggc_mx_dw_loc_descr_struct (void *);
-#define gt_ggc_m_13dw_fde_struct(X) do { \
- if (X != NULL) gt_ggc_mx_dw_fde_struct (X);\
- } while (0)
-extern void gt_ggc_mx_dw_fde_struct (void *);
-#define gt_ggc_m_13dw_cfi_struct(X) do { \
- if (X != NULL) gt_ggc_mx_dw_cfi_struct (X);\
- } while (0)
-extern void gt_ggc_mx_dw_cfi_struct (void *);
-#define gt_ggc_m_8typeinfo(X) do { \
- if (X != NULL) gt_ggc_mx_typeinfo (X);\
- } while (0)
-extern void gt_ggc_mx_typeinfo (void *);
-#define gt_ggc_m_22VEC_alias_set_entry_gc(X) do { \
- if (X != NULL) gt_ggc_mx_VEC_alias_set_entry_gc (X);\
- } while (0)
-extern void gt_ggc_mx_VEC_alias_set_entry_gc (void *);
-#define gt_ggc_m_17alias_set_entry_d(X) do { \
- if (X != NULL) gt_ggc_mx_alias_set_entry_d (X);\
- } while (0)
-extern void gt_ggc_mx_alias_set_entry_d (void *);
-#define gt_ggc_m_24constant_descriptor_tree(X) do { \
- if (X != NULL) gt_ggc_mx_constant_descriptor_tree (X);\
- } while (0)
-extern void gt_ggc_mx_constant_descriptor_tree (void *);
-#define gt_ggc_m_15cgraph_asm_node(X) do { \
- if (X != NULL) gt_ggc_mx_cgraph_asm_node (X);\
- } while (0)
-extern void gt_ggc_mx_cgraph_asm_node (void *);
-#define gt_ggc_m_12varpool_node(X) do { \
- if (X != NULL) gt_ggc_mx_varpool_node (X);\
- } while (0)
-extern void gt_ggc_mx_varpool_node (void *);
-#define gt_ggc_m_22VEC_cgraph_node_set_gc(X) do { \
- if (X != NULL) gt_ggc_mx_VEC_cgraph_node_set_gc (X);\
- } while (0)
-extern void gt_ggc_mx_VEC_cgraph_node_set_gc (void *);
-#define gt_ggc_m_19cgraph_node_set_def(X) do { \
- if (X != NULL) gt_ggc_mx_cgraph_node_set_def (X);\
- } while (0)
-extern void gt_ggc_mx_cgraph_node_set_def (void *);
-#define gt_ggc_m_27cgraph_node_set_element_def(X) do { \
- if (X != NULL) gt_ggc_mx_cgraph_node_set_element_def (X);\
- } while (0)
-extern void gt_ggc_mx_cgraph_node_set_element_def (void *);
-#define gt_ggc_m_22VEC_cgraph_node_ptr_gc(X) do { \
- if (X != NULL) gt_ggc_mx_VEC_cgraph_node_ptr_gc (X);\
- } while (0)
-extern void gt_ggc_mx_VEC_cgraph_node_ptr_gc (void *);
-#define gt_ggc_m_11cgraph_edge(X) do { \
- if (X != NULL) gt_ggc_mx_cgraph_edge (X);\
- } while (0)
-extern void gt_ggc_mx_cgraph_edge (void *);
-#define gt_ggc_m_24VEC_ipa_replace_map_p_gc(X) do { \
- if (X != NULL) gt_ggc_mx_VEC_ipa_replace_map_p_gc (X);\
- } while (0)
-extern void gt_ggc_mx_VEC_ipa_replace_map_p_gc (void *);
-#define gt_ggc_m_15ipa_replace_map(X) do { \
- if (X != NULL) gt_ggc_mx_ipa_replace_map (X);\
- } while (0)
-extern void gt_ggc_mx_ipa_replace_map (void *);
-#define gt_ggc_m_11cgraph_node(X) do { \
- if (X != NULL) gt_ggc_mx_cgraph_node (X);\
- } while (0)
-extern void gt_ggc_mx_cgraph_node (void *);
-#define gt_ggc_m_18VEC_basic_block_gc(X) do { \
- if (X != NULL) gt_ggc_mx_VEC_basic_block_gc (X);\
- } while (0)
-extern void gt_ggc_mx_VEC_basic_block_gc (void *);
-#define gt_ggc_m_14gimple_bb_info(X) do { \
- if (X != NULL) gt_ggc_mx_gimple_bb_info (X);\
- } while (0)
-extern void gt_ggc_mx_gimple_bb_info (void *);
-#define gt_ggc_m_11rtl_bb_info(X) do { \
- if (X != NULL) gt_ggc_mx_rtl_bb_info (X);\
- } while (0)
-extern void gt_ggc_mx_rtl_bb_info (void *);
-#define gt_ggc_m_11VEC_edge_gc(X) do { \
- if (X != NULL) gt_ggc_mx_VEC_edge_gc (X);\
- } while (0)
-extern void gt_ggc_mx_VEC_edge_gc (void *);
-#define gt_ggc_m_17cselib_val_struct(X) do { \
- if (X != NULL) gt_ggc_mx_cselib_val_struct (X);\
- } while (0)
-extern void gt_ggc_mx_cselib_val_struct (void *);
-#define gt_ggc_m_12elt_loc_list(X) do { \
- if (X != NULL) gt_ggc_mx_elt_loc_list (X);\
- } while (0)
-extern void gt_ggc_mx_elt_loc_list (void *);
-#define gt_ggc_m_13VEC_loop_p_gc(X) do { \
- if (X != NULL) gt_ggc_mx_VEC_loop_p_gc (X);\
- } while (0)
-extern void gt_ggc_mx_VEC_loop_p_gc (void *);
-#define gt_ggc_m_4loop(X) do { \
- if (X != NULL) gt_ggc_mx_loop (X);\
- } while (0)
-extern void gt_ggc_mx_loop (void *);
-#define gt_ggc_m_9loop_exit(X) do { \
- if (X != NULL) gt_ggc_mx_loop_exit (X);\
- } while (0)
-extern void gt_ggc_mx_loop_exit (void *);
-#define gt_ggc_m_13nb_iter_bound(X) do { \
- if (X != NULL) gt_ggc_mx_nb_iter_bound (X);\
- } while (0)
-extern void gt_ggc_mx_nb_iter_bound (void *);
-#define gt_ggc_m_24types_used_by_vars_entry(X) do { \
- if (X != NULL) gt_ggc_mx_types_used_by_vars_entry (X);\
- } while (0)
-extern void gt_ggc_mx_types_used_by_vars_entry (void *);
-#define gt_ggc_m_17language_function(X) do { \
- if (X != NULL) gt_ggc_mx_language_function (X);\
- } while (0)
-extern void gt_ggc_mx_language_function (void *);
-#define gt_ggc_m_5loops(X) do { \
- if (X != NULL) gt_ggc_mx_loops (X);\
- } while (0)
-extern void gt_ggc_mx_loops (void *);
-#define gt_ggc_m_18control_flow_graph(X) do { \
- if (X != NULL) gt_ggc_mx_control_flow_graph (X);\
- } while (0)
-extern void gt_ggc_mx_control_flow_graph (void *);
-#define gt_ggc_m_9eh_status(X) do { \
- if (X != NULL) gt_ggc_mx_eh_status (X);\
- } while (0)
-extern void gt_ggc_mx_eh_status (void *);
-#define gt_ggc_m_20initial_value_struct(X) do { \
- if (X != NULL) gt_ggc_mx_initial_value_struct (X);\
- } while (0)
-extern void gt_ggc_mx_initial_value_struct (void *);
-#define gt_ggc_m_17rtx_constant_pool(X) do { \
- if (X != NULL) gt_ggc_mx_rtx_constant_pool (X);\
- } while (0)
-extern void gt_ggc_mx_rtx_constant_pool (void *);
-#define gt_ggc_m_18VEC_temp_slot_p_gc(X) do { \
- if (X != NULL) gt_ggc_mx_VEC_temp_slot_p_gc (X);\
- } while (0)
-extern void gt_ggc_mx_VEC_temp_slot_p_gc (void *);
-#define gt_ggc_m_9temp_slot(X) do { \
- if (X != NULL) gt_ggc_mx_temp_slot (X);\
- } while (0)
-extern void gt_ggc_mx_temp_slot (void *);
-#define gt_ggc_m_9gimple_df(X) do { \
- if (X != NULL) gt_ggc_mx_gimple_df (X);\
- } while (0)
-extern void gt_ggc_mx_gimple_df (void *);
-#define gt_ggc_m_23VEC_call_site_record_gc(X) do { \
- if (X != NULL) gt_ggc_mx_VEC_call_site_record_gc (X);\
- } while (0)
-extern void gt_ggc_mx_VEC_call_site_record_gc (void *);
-#define gt_ggc_m_18call_site_record_d(X) do { \
- if (X != NULL) gt_ggc_mx_call_site_record_d (X);\
- } while (0)
-extern void gt_ggc_mx_call_site_record_d (void *);
-#define gt_ggc_m_14sequence_stack(X) do { \
- if (X != NULL) gt_ggc_mx_sequence_stack (X);\
- } while (0)
-extern void gt_ggc_mx_sequence_stack (void *);
-#define gt_ggc_m_8elt_list(X) do { \
- if (X != NULL) gt_ggc_mx_elt_list (X);\
- } while (0)
-extern void gt_ggc_mx_elt_list (void *);
-#define gt_ggc_m_17tree_priority_map(X) do { \
- if (X != NULL) gt_ggc_mx_tree_priority_map (X);\
- } while (0)
-extern void gt_ggc_mx_tree_priority_map (void *);
-#define gt_ggc_m_12tree_int_map(X) do { \
- if (X != NULL) gt_ggc_mx_tree_int_map (X);\
- } while (0)
-extern void gt_ggc_mx_tree_int_map (void *);
-#define gt_ggc_m_8tree_map(X) do { \
- if (X != NULL) gt_ggc_mx_tree_map (X);\
- } while (0)
-extern void gt_ggc_mx_tree_map (void *);
-#define gt_ggc_m_14lang_tree_node(X) do { \
- if (X != NULL) gt_ggc_mx_lang_tree_node (X);\
- } while (0)
-extern void gt_ggc_mx_lang_tree_node (void *);
-#define gt_ggc_m_24tree_statement_list_node(X) do { \
- if (X != NULL) gt_ggc_mx_tree_statement_list_node (X);\
- } while (0)
-extern void gt_ggc_mx_tree_statement_list_node (void *);
-#define gt_ggc_m_9lang_decl(X) do { \
- if (X != NULL) gt_ggc_mx_lang_decl (X);\
- } while (0)
-extern void gt_ggc_mx_lang_decl (void *);
-#define gt_ggc_m_9lang_type(X) do { \
- if (X != NULL) gt_ggc_mx_lang_type (X);\
- } while (0)
-extern void gt_ggc_mx_lang_type (void *);
-#define gt_ggc_m_10die_struct(X) do { \
- if (X != NULL) gt_ggc_mx_die_struct (X);\
- } while (0)
-extern void gt_ggc_mx_die_struct (void *);
-#define gt_ggc_m_15varray_head_tag(X) do { \
- if (X != NULL) gt_ggc_mx_varray_head_tag (X);\
- } while (0)
-extern void gt_ggc_mx_varray_head_tag (void *);
-#define gt_ggc_m_12ptr_info_def(X) do { \
- if (X != NULL) gt_ggc_mx_ptr_info_def (X);\
- } while (0)
-extern void gt_ggc_mx_ptr_info_def (void *);
-#define gt_ggc_m_22VEC_constructor_elt_gc(X) do { \
- if (X != NULL) gt_ggc_mx_VEC_constructor_elt_gc (X);\
- } while (0)
-extern void gt_ggc_mx_VEC_constructor_elt_gc (void *);
-#define gt_ggc_m_10tree_ann_d(X) do { \
- if (X != NULL) gt_ggc_mx_tree_ann_d (X);\
- } while (0)
-extern void gt_ggc_mx_tree_ann_d (void *);
-#define gt_ggc_m_17VEC_alias_pair_gc(X) do { \
- if (X != NULL) gt_ggc_mx_VEC_alias_pair_gc (X);\
- } while (0)
-extern void gt_ggc_mx_VEC_alias_pair_gc (void *);
-#define gt_ggc_m_11VEC_tree_gc(X) do { \
- if (X != NULL) gt_ggc_mx_VEC_tree_gc (X);\
- } while (0)
-extern void gt_ggc_mx_VEC_tree_gc (void *);
-#define gt_ggc_m_12VEC_uchar_gc(X) do { \
- if (X != NULL) gt_ggc_mx_VEC_uchar_gc (X);\
- } while (0)
-extern void gt_ggc_mx_VEC_uchar_gc (void *);
-#define gt_ggc_m_8function(X) do { \
- if (X != NULL) gt_ggc_mx_function (X);\
- } while (0)
-extern void gt_ggc_mx_function (void *);
-#define gt_ggc_m_23constant_descriptor_rtx(X) do { \
- if (X != NULL) gt_ggc_mx_constant_descriptor_rtx (X);\
- } while (0)
-extern void gt_ggc_mx_constant_descriptor_rtx (void *);
-#define gt_ggc_m_11fixed_value(X) do { \
- if (X != NULL) gt_ggc_mx_fixed_value (X);\
- } while (0)
-extern void gt_ggc_mx_fixed_value (void *);
-#define gt_ggc_m_10real_value(X) do { \
- if (X != NULL) gt_ggc_mx_real_value (X);\
- } while (0)
-extern void gt_ggc_mx_real_value (void *);
-#define gt_ggc_m_10VEC_rtx_gc(X) do { \
- if (X != NULL) gt_ggc_mx_VEC_rtx_gc (X);\
- } while (0)
-extern void gt_ggc_mx_VEC_rtx_gc (void *);
-#define gt_ggc_m_12object_block(X) do { \
- if (X != NULL) gt_ggc_mx_object_block (X);\
- } while (0)
-extern void gt_ggc_mx_object_block (void *);
-#define gt_ggc_m_9reg_attrs(X) do { \
- if (X != NULL) gt_ggc_mx_reg_attrs (X);\
- } while (0)
-extern void gt_ggc_mx_reg_attrs (void *);
-#define gt_ggc_m_9mem_attrs(X) do { \
- if (X != NULL) gt_ggc_mx_mem_attrs (X);\
- } while (0)
-extern void gt_ggc_mx_mem_attrs (void *);
-#define gt_ggc_m_14bitmap_obstack(X) do { \
- if (X != NULL) gt_ggc_mx_bitmap_obstack (X);\
- } while (0)
-extern void gt_ggc_mx_bitmap_obstack (void *);
-#define gt_ggc_m_18bitmap_element_def(X) do { \
- if (X != NULL) gt_ggc_mx_bitmap_element_def (X);\
- } while (0)
-extern void gt_ggc_mx_bitmap_element_def (void *);
-#define gt_ggc_m_16machine_function(X) do { \
- if (X != NULL) gt_ggc_mx_machine_function (X);\
- } while (0)
-extern void gt_ggc_mx_machine_function (void *);
-#define gt_ggc_m_17stack_local_entry(X) do { \
- if (X != NULL) gt_ggc_mx_stack_local_entry (X);\
- } while (0)
-extern void gt_ggc_mx_stack_local_entry (void *);
-#define gt_ggc_m_15basic_block_def(X) do { \
- if (X != NULL) gt_ggc_mx_basic_block_def (X);\
- } while (0)
-extern void gt_ggc_mx_basic_block_def (void *);
-#define gt_ggc_m_8edge_def(X) do { \
- if (X != NULL) gt_ggc_mx_edge_def (X);\
- } while (0)
-extern void gt_ggc_mx_edge_def (void *);
-#define gt_ggc_m_17gimple_seq_node_d(X) do { \
- if (X != NULL) gt_ggc_mx_gimple_seq_node_d (X);\
- } while (0)
-extern void gt_ggc_mx_gimple_seq_node_d (void *);
-#define gt_ggc_m_12gimple_seq_d(X) do { \
- if (X != NULL) gt_ggc_mx_gimple_seq_d (X);\
- } while (0)
-extern void gt_ggc_mx_gimple_seq_d (void *);
-#define gt_ggc_m_7section(X) do { \
- if (X != NULL) gt_ggc_mx_section (X);\
- } while (0)
-extern void gt_ggc_mx_section (void *);
-#define gt_ggc_m_18gimple_statement_d(X) do { \
- if (X != NULL) gt_ggc_mx_gimple_statement_d (X);\
- } while (0)
-extern void gt_ggc_mx_gimple_statement_d (void *);
-#define gt_ggc_m_9rtvec_def(X) do { \
- if (X != NULL) gt_ggc_mx_rtvec_def (X);\
- } while (0)
-extern void gt_ggc_mx_rtvec_def (void *);
-#define gt_ggc_m_7rtx_def(X) do { \
- if (X != NULL) gt_ggc_mx_rtx_def (X);\
- } while (0)
-extern void gt_ggc_mx_rtx_def (void *);
-#define gt_ggc_m_15bitmap_head_def(X) do { \
- if (X != NULL) gt_ggc_mx_bitmap_head_def (X);\
- } while (0)
-extern void gt_ggc_mx_bitmap_head_def (void *);
-#define gt_ggc_m_9tree_node(X) do { \
- if (X != NULL) gt_ggc_mx_tree_node (X);\
- } while (0)
-#define gt_ggc_mx_tree_node gt_ggc_mx_lang_tree_node
-#define gt_ggc_m_6answer(X) do { \
- if (X != NULL) gt_ggc_mx_answer (X);\
- } while (0)
-extern void gt_ggc_mx_answer (void *);
-#define gt_ggc_m_9cpp_macro(X) do { \
- if (X != NULL) gt_ggc_mx_cpp_macro (X);\
- } while (0)
-extern void gt_ggc_mx_cpp_macro (void *);
-#define gt_ggc_m_9cpp_token(X) do { \
- if (X != NULL) gt_ggc_mx_cpp_token (X);\
- } while (0)
-extern void gt_ggc_mx_cpp_token (void *);
-#define gt_ggc_m_9line_maps(X) do { \
- if (X != NULL) gt_ggc_mx_line_maps (X);\
- } while (0)
-extern void gt_ggc_mx_line_maps (void *);
-extern void gt_ggc_m_II17splay_tree_node_s (void *);
-extern void gt_ggc_m_SP9tree_node17splay_tree_node_s (void *);
-extern void gt_ggc_m_P9tree_nodeP9tree_node17splay_tree_node_s (void *);
-extern void gt_ggc_m_IP9tree_node17splay_tree_node_s (void *);
-extern void gt_ggc_m_P13tree_llvm_map4htab (void *);
-extern void gt_ggc_m_P15interface_tuple4htab (void *);
-extern void gt_ggc_m_P16volatilized_type4htab (void *);
-extern void gt_ggc_m_P17string_descriptor4htab (void *);
-extern void gt_ggc_m_P14type_assertion4htab (void *);
-extern void gt_ggc_m_P18treetreehash_entry4htab (void *);
-extern void gt_ggc_m_P17module_htab_entry4htab (void *);
-extern void gt_ggc_m_P16def_pragma_macro4htab (void *);
-extern void gt_ggc_m_P21pending_abstract_type4htab (void *);
-extern void gt_ggc_m_P10spec_entry4htab (void *);
-extern void gt_ggc_m_P16cxx_int_tree_map4htab (void *);
-extern void gt_ggc_m_P17named_label_entry4htab (void *);
-extern void gt_ggc_m_P12tree_int_map4htab (void *);
-extern void gt_ggc_m_P20lto_symtab_entry_def4htab (void *);
-extern void gt_ggc_m_IP9tree_node12splay_tree_s (void *);
-extern void gt_ggc_m_P9tree_nodeP9tree_node12splay_tree_s (void *);
-extern void gt_ggc_m_P12varpool_node4htab (void *);
-extern void gt_ggc_m_P13scev_info_str4htab (void *);
-extern void gt_ggc_m_P23constant_descriptor_rtx4htab (void *);
-extern void gt_ggc_m_P24constant_descriptor_tree4htab (void *);
-extern void gt_ggc_m_P12object_block4htab (void *);
-extern void gt_ggc_m_P7section4htab (void *);
-extern void gt_ggc_m_P17tree_priority_map4htab (void *);
-extern void gt_ggc_m_P8tree_map4htab (void *);
-extern void gt_ggc_m_P9type_hash4htab (void *);
-extern void gt_ggc_m_P13libfunc_entry4htab (void *);
-extern void gt_ggc_m_P23temp_slot_address_entry4htab (void *);
-extern void gt_ggc_m_P15throw_stmt_node4htab (void *);
-extern void gt_ggc_m_P9reg_attrs4htab (void *);
-extern void gt_ggc_m_P9mem_attrs4htab (void *);
-extern void gt_ggc_m_P7rtx_def4htab (void *);
-extern void gt_ggc_m_SP9tree_node12splay_tree_s (void *);
-extern void gt_ggc_m_P10vcall_insn4htab (void *);
-extern void gt_ggc_m_P16var_loc_list_def4htab (void *);
-extern void gt_ggc_m_P10die_struct4htab (void *);
-extern void gt_ggc_m_P15dwarf_file_data4htab (void *);
-extern void gt_ggc_m_P20indirect_string_node4htab (void *);
-extern void gt_ggc_m_P11cgraph_node4htab (void *);
-extern void gt_ggc_m_II12splay_tree_s (void *);
-extern void gt_ggc_m_P27cgraph_node_set_element_def4htab (void *);
-extern void gt_ggc_m_P11cgraph_edge4htab (void *);
-extern void gt_ggc_m_P9loop_exit4htab (void *);
-extern void gt_ggc_m_P24types_used_by_vars_entry4htab (void *);
-extern void gt_ggc_m_P9tree_node4htab (void *);
-
-/* functions code */
-
-void
-gt_ggc_mx_tree_llvm_map (void *x_p)
-{
- struct tree_llvm_map * const x = (struct tree_llvm_map *)x_p;
- if (ggc_test_and_set_mark (x))
- {
- gt_ggc_m_9tree_node ((*x).base.from);
- }
-}
-
-void
-gt_ggc_m_P13tree_llvm_map4htab (void *x_p)
-{
- struct htab * const x = (struct htab *)x_p;
- if (ggc_test_and_set_mark (x))
- {
- if ((*x).entries != NULL) {
- size_t i0;
- for (i0 = 0; i0 != (size_t)(((*x)).size); i0++) {
- gt_ggc_m_13tree_llvm_map ((*x).entries[i0]);
- }
- ggc_mark ((*x).entries);
- }
- }
-}
-
-/* GC roots. */
-
-EXPORTED_CONST struct ggc_cache_tab gt_ggc_rc__gt_llvm_cache_h[] = {
- {
- &llvm_cache,
- 1,
- sizeof (llvm_cache),
- &gt_ggc_mx_tree_llvm_map,
- NULL,
- &tree_llvm_map_marked_p
- },
- LAST_GGC_CACHE_TAB
-};
-
diff -r -u -N dragonegg-2.9-old/include/dragonegg/ABI.h dragonegg-2.9-new/include/dragonegg/ABI.h
--- dragonegg-2.9-old/include/dragonegg/ABI.h 1970-01-01 01:00:00.000000000 +0100
+++ dragonegg-2.9-new/include/dragonegg/ABI.h 2011-04-09 00:38:06.630097839 +0200
@@ -0,0 +1,351 @@
+//===--------- ABI.h - Processor ABI customization hooks --------*- C++ -*-===//
+//
+// Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Chris Lattner,
+// Duncan Sands et al.
+//
+// This file is part of DragonEgg.
+//
+// DragonEgg is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free Software
+// Foundation; either version 2, or (at your option) any later version.
+//
+// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along with
+// DragonEgg; see the file COPYING. If not, write to the Free Software
+// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
+//
+//===----------------------------------------------------------------------===//
+// This file specifies how argument values are passed and returned from function
+// calls. This allows the target to specialize handling of things like how
+// structures are passed by-value.
+//===----------------------------------------------------------------------===//
+
+#ifndef DRAGONEGG_ABI_H
+#define DRAGONEGG_ABI_H
+
+// Plugin headers
+#include "dragonegg/Internals.h"
+#include "dragonegg/Target.h"
+
+// LLVM headers
+#include "llvm/LLVMContext.h"
+#include "llvm/Target/TargetData.h"
+
+namespace llvm {
+ class BasicBlock;
+}
+
+/// DefaultABIClient - This is a simple implementation of the ABI client
+/// interface that can be subclassed.
+struct DefaultABIClient {
+ virtual ~DefaultABIClient() {}
+ virtual CallingConv::ID& getCallingConv(void) = 0;
+ virtual bool isShadowReturn() const { return false; }
+
+ /// HandleScalarResult - This callback is invoked if the function returns a
+ /// simple scalar result value, which is of type RetTy.
+ virtual void HandleScalarResult(const Type * /*RetTy*/) {}
+
+ /// HandleAggregateResultAsScalar - This callback is invoked if the function
+ /// returns an aggregate value by bit converting it to the specified scalar
+ /// type and returning that. The bit conversion should start at byte Offset
+ /// within the struct, and ScalarTy is not necessarily big enough to cover
+ /// the entire struct.
+ virtual void HandleAggregateResultAsScalar(const Type * /*ScalarTy*/,
+ unsigned /*Offset*/ = 0) {}
+
+ /// HandleAggregateResultAsAggregate - This callback is invoked if the function
+ /// returns an aggregate value using multiple return values.
+ virtual void HandleAggregateResultAsAggregate(const Type * /*AggrTy*/) {}
+
+ /// HandleAggregateShadowResult - This callback is invoked if the function
+ /// returns an aggregate value by using a "shadow" first parameter, which is
+ /// a pointer to the aggregate, of type PtrArgTy. If RetPtr is set to true,
+ /// the pointer argument itself is returned from the function.
+ virtual void HandleAggregateShadowResult(const PointerType * /*PtrArgTy*/,
+ bool /*RetPtr*/) {}
+
+ /// HandleScalarShadowResult - This callback is invoked if the function
+ /// returns a scalar value by using a "shadow" first parameter, which is a
+ /// pointer to the scalar, of type PtrArgTy. If RetPtr is set to true,
+ /// the pointer argument itself is returned from the function.
+ virtual void HandleScalarShadowResult(const PointerType * /*PtrArgTy*/,
+ bool /*RetPtr*/) {}
+
+
+ /// HandleScalarArgument - This is the primary callback that specifies an
+ /// LLVM argument to pass. It is only used for first class types.
+ /// If RealSize is non Zero then it specifies number of bytes to access
+ /// from LLVMTy.
+ virtual void HandleScalarArgument(const llvm::Type * /*LLVMTy*/,
+ tree_node * /*type*/,
+ unsigned /*RealSize*/ = 0) {}
+
+ /// HandleByInvisibleReferenceArgument - This callback is invoked if a pointer
+ /// (of type PtrTy) to the argument is passed rather than the argument itself.
+ virtual void HandleByInvisibleReferenceArgument(const llvm::Type * /*PtrTy*/,
+ tree_node * /*type*/) {}
+
+ /// HandleByValArgument - This callback is invoked if the aggregate function
+ /// argument is passed by value.
+ virtual void HandleByValArgument(const llvm::Type * /*LLVMTy*/,
+ tree_node * /*type*/) {}
+
+ /// HandleFCAArgument - This callback is invoked if the aggregate function
+ /// argument is passed by value as a first class aggregate.
+ virtual void HandleFCAArgument(const llvm::Type * /*LLVMTy*/,
+ tree_node * /*type*/) {}
+
+ /// EnterField - Called when we're about the enter the field of a struct
+ /// or union. FieldNo is the number of the element we are entering in the
+ /// LLVM Struct, StructTy is the LLVM type of the struct we are entering.
+ virtual void EnterField(unsigned /*FieldNo*/,
+ const llvm::Type * /*StructTy*/) {}
+ virtual void ExitField() {}
+ virtual void HandlePad(const llvm::Type * /*LLVMTy*/) {}
+};
+
+// LLVM_SHOULD_NOT_RETURN_COMPLEX_IN_MEMORY - A hook to allow
+// special _Complex handling. Return true if X should be returned using
+// multiple value return instruction.
+#ifndef LLVM_SHOULD_NOT_RETURN_COMPLEX_IN_MEMORY
+#define LLVM_SHOULD_NOT_RETURN_COMPLEX_IN_MEMORY(X) \
+ false
+#endif
+
+// LLVM_SHOULD_NOT_USE_SHADOW_RETURN - A hook to allow aggregates to be
+// returned in registers.
+#ifndef LLVM_SHOULD_NOT_USE_SHADOW_RETURN
+#define LLVM_SHOULD_NOT_USE_SHADOW_RETURN(X, CC) \
+ false
+#endif
+
+// doNotUseShadowReturn - Return true if the specified GCC type
+// should not be returned using a pointer to struct parameter.
+extern bool doNotUseShadowReturn(tree_node *type, tree_node *fndecl,
+ CallingConv::ID CC);
+
+/// isSingleElementStructOrArray - If this is (recursively) a structure with one
+/// field or an array with one element, return the field type, otherwise return
+/// null. Returns null for complex number types. If ignoreZeroLength, the
+/// struct (recursively) may include zero-length fields in addition to the
+/// single element that has data. If rejectFatBitField, and the single element
+/// is a bitfield of a type that's bigger than the struct, return null anyway.
+extern tree_node *isSingleElementStructOrArray(tree_node *type,
+ bool ignoreZeroLength,
+ bool rejectFatBitfield);
+
+/// isZeroSizedStructOrUnion - Returns true if this is a struct or union
+/// which is zero bits wide.
+extern bool isZeroSizedStructOrUnion(tree_node *type);
+
+// getLLVMScalarTypeForStructReturn - Return LLVM Type if TY can be
+// returned as a scalar, otherwise return NULL. This is the default
+// target independent implementation.
+static inline
+const Type* getLLVMScalarTypeForStructReturn(tree_node *type, unsigned *Offset) {
+ const Type *Ty = ConvertType(type);
+ unsigned Size = getTargetData().getTypeAllocSize(Ty);
+ *Offset = 0;
+ if (Size == 0)
+ return Type::getVoidTy(getGlobalContext());
+ else if (Size == 1)
+ return Type::getInt8Ty(getGlobalContext());
+ else if (Size == 2)
+ return Type::getInt16Ty(getGlobalContext());
+ else if (Size <= 4)
+ return Type::getInt32Ty(getGlobalContext());
+ else if (Size <= 8)
+ return Type::getInt64Ty(getGlobalContext());
+ else if (Size <= 16)
+ return IntegerType::get(getGlobalContext(), 128);
+ else if (Size <= 32)
+ return IntegerType::get(getGlobalContext(), 256);
+
+ return NULL;
+}
+
+// getLLVMAggregateTypeForStructReturn - Return LLVM type if TY can be
+// returns as multiple values, otherwise return NULL. This is the default
+// target independent implementation.
+static inline
+const Type* getLLVMAggregateTypeForStructReturn(tree_node * /*type*/) {
+ return NULL;
+}
+
+#ifndef LLVM_TRY_PASS_AGGREGATE_CUSTOM
+#define LLVM_TRY_PASS_AGGREGATE_CUSTOM(T, E, CC, C) \
+ false
+#endif
+
+// LLVM_SHOULD_PASS_VECTOR_IN_INTEGER_REGS - Return true if this vector
+// type should be passed as integer registers. Generally vectors which are
+// not part of the target architecture should do this.
+#ifndef LLVM_SHOULD_PASS_VECTOR_IN_INTEGER_REGS
+#define LLVM_SHOULD_PASS_VECTOR_IN_INTEGER_REGS(TY) \
+ false
+#endif
+
+// LLVM_SHOULD_PASS_VECTOR_USING_BYVAL_ATTR - Return true if this vector
+// type should be passed byval. Used for generic vectors on x86-64.
+#ifndef LLVM_SHOULD_PASS_VECTOR_USING_BYVAL_ATTR
+#define LLVM_SHOULD_PASS_VECTOR_USING_BYVAL_ATTR(X) \
+ false
+#endif
+
+// LLVM_SHOULD_PASS_AGGREGATE_USING_BYVAL_ATTR - Return true if this aggregate
+// value should be passed by value, i.e. passing its address with the byval
+// attribute bit set. The default is false.
+#ifndef LLVM_SHOULD_PASS_AGGREGATE_USING_BYVAL_ATTR
+#define LLVM_SHOULD_PASS_AGGREGATE_USING_BYVAL_ATTR(X, TY) \
+ false
+#endif
+
+// LLVM_SHOULD_PASS_AGGREGATE_AS_FCA - Return true if this aggregate value
+// should be passed by value as a first class aggregate. The default is false.
+#ifndef LLVM_SHOULD_PASS_AGGREGATE_AS_FCA
+#define LLVM_SHOULD_PASS_AGGREGATE_AS_FCA(X, TY) \
+ false
+#endif
+
+// LLVM_SHOULD_PASS_AGGREGATE_IN_MIXED_REGS - Return true if this aggregate
+// value should be passed in a mixture of integer, floating point, and vector
+// registers. The routine should also return by reference a vector of the
+// types of the registers being used. The default is false.
+#ifndef LLVM_SHOULD_PASS_AGGREGATE_IN_MIXED_REGS
+#define LLVM_SHOULD_PASS_AGGREGATE_IN_MIXED_REGS(T, TY, CC, E) \
+ false
+#endif
+
+// LLVM_AGGREGATE_PARTIALLY_PASSED_IN_REGS - Only called if
+// LLVM_SHOULD_PASS_AGGREGATE_IN_MIXED_REGS returns true. This returns true if
+// there are only enough unused argument passing registers to pass a part of
+// the aggregate. Note, this routine should return false if none of the needed
+// registers are available.
+#ifndef LLVM_AGGREGATE_PARTIALLY_PASSED_IN_REGS
+#define LLVM_AGGREGATE_PARTIALLY_PASSED_IN_REGS(E, SE, ISR, CC) \
+ false
+#endif
+
+// LLVM_BYVAL_ALIGNMENT - Returns the alignment of the type in bytes, if known,
+// in the getGlobalContext() of its use as a function parameter.
+// Note that the alignment in the TYPE node is usually the alignment appropriate
+// when the type is used within a struct, which may or may not be appropriate
+// here.
+#ifndef LLVM_BYVAL_ALIGNMENT
+#define LLVM_BYVAL_ALIGNMENT(T) 0
+#endif
+
+// LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS - Return true if this aggregate
+// value should be passed in integer registers. By default, we do this for all
+// values that are not single-element structs. This ensures that things like
+// {short,short} are passed in one 32-bit chunk, not as two arguments (which
+// would often be 64-bits). We also do it for single-element structs when the
+// single element is a bitfield of a type bigger than the struct; the code
+// for field-by-field struct passing does not handle this one right.
+#ifndef LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS
+#define LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS(X, Y, Z) \
+ !isSingleElementStructOrArray((X), false, true)
+#endif
+
+// LLVM_SHOULD_RETURN_SELT_STRUCT_AS_SCALAR - Return a TYPE tree if this single
+// element struct should be returned using the convention for that scalar TYPE,
+// 0 otherwise.
+// The returned TYPE must be the same size as X for this to work; that is
+// checked elsewhere. (Structs where this is not the case can be constructed
+// by abusing the __aligned__ attribute.)
+#ifndef LLVM_SHOULD_RETURN_SELT_STRUCT_AS_SCALAR
+#define LLVM_SHOULD_RETURN_SELT_STRUCT_AS_SCALAR(X) \
+ isSingleElementStructOrArray(X, false, false)
+#endif
+
+// LLVM_SHOULD_RETURN_VECTOR_AS_SCALAR - Return a TYPE tree if this vector type
+// should be returned using the convention for that scalar TYPE, 0 otherwise.
+// X may be evaluated more than once.
+#ifndef LLVM_SHOULD_RETURN_VECTOR_AS_SCALAR
+#define LLVM_SHOULD_RETURN_VECTOR_AS_SCALAR(X,Y) 0
+#endif
+
+// LLVM_SHOULD_RETURN_VECTOR_AS_SHADOW - Return true if this vector type
+// should be returned using the aggregate shadow (sret) convention, 0 otherwise.
+// X may be evaluated more than once.
+#ifndef LLVM_SHOULD_RETURN_VECTOR_AS_SHADOW
+#define LLVM_SHOULD_RETURN_VECTOR_AS_SHADOW(X,Y) 0
+#endif
+
+// LLVM_SCALAR_TYPE_FOR_STRUCT_RETURN - Return LLVM Type if X can be
+// returned as a scalar, otherwise return NULL.
+#ifndef LLVM_SCALAR_TYPE_FOR_STRUCT_RETURN
+#define LLVM_SCALAR_TYPE_FOR_STRUCT_RETURN(X, Y) \
+ getLLVMScalarTypeForStructReturn((X), (Y))
+#endif
+
+// LLVM_AGGR_TYPE_FOR_STRUCT_RETURN - Return LLVM Type if X can be
+// returned as an aggregate, otherwise return NULL.
+#ifndef LLVM_AGGR_TYPE_FOR_STRUCT_RETURN
+#define LLVM_AGGR_TYPE_FOR_STRUCT_RETURN(X, CC) \
+ getLLVMAggregateTypeForStructReturn(X)
+#endif
+
+// LLVM_EXTRACT_MULTIPLE_RETURN_VALUE - Extract multiple return value from
+// SRC and assign it to DEST. Each target that supports multiple return
+// value must implement this hook.
+#ifndef LLVM_EXTRACT_MULTIPLE_RETURN_VALUE
+#define LLVM_EXTRACT_MULTIPLE_RETURN_VALUE(Src,Dest,V,B) \
+ llvm_default_extract_multiple_return_value((Src),(Dest),(V),(B))
+#endif
+static inline
+void llvm_default_extract_multiple_return_value(Value * /*Src*/, Value * /*Dest*/,
+ bool /*isVolatile*/,
+ LLVMBuilder &/*Builder*/) {
+ assert (0 && "LLVM_EXTRACT_MULTIPLE_RETURN_VALUE is not implemented!");
+}
+
+/// DefaultABI - This class implements the default LLVM ABI where structures are
+/// passed by decimating them into individual components and unions are passed
+/// by passing the largest member of the union.
+///
+class DefaultABI {
+protected:
+ DefaultABIClient &C;
+public:
+ DefaultABI(DefaultABIClient &c);
+
+ bool isShadowReturn() const;
+
+ /// HandleReturnType - This is invoked by the target-independent code for the
+ /// return type. It potentially breaks down the argument and invokes methods
+ /// on the client that indicate how its pieces should be handled. This
+ /// handles things like returning structures via hidden parameters.
+ void HandleReturnType(tree_node *type, tree_node *fn, bool isBuiltin);
+
+ /// HandleArgument - This is invoked by the target-independent code for each
+ /// argument type passed into the function. It potentially breaks down the
+ /// argument and invokes methods on the client that indicate how its pieces
+ /// should be handled. This handles things like decimating structures into
+ /// their fields.
+ void HandleArgument(tree_node *type, std::vector<const Type*> &ScalarElts,
+ Attributes *Attributes = NULL);
+
+ /// HandleUnion - Handle a UNION_TYPE or QUAL_UNION_TYPE tree.
+ ///
+ void HandleUnion(tree_node *type, std::vector<const Type*> &ScalarElts);
+
+ /// PassInIntegerRegisters - Given an aggregate value that should be passed in
+ /// integer registers, convert it to a structure containing ints and pass all
+ /// of the struct elements in. If Size is set we pass only that many bytes.
+ void PassInIntegerRegisters(tree_node *type,
+ std::vector<const Type*> &ScalarElts,
+ unsigned origSize, bool DontCheckAlignment);
+
+ /// PassInMixedRegisters - Given an aggregate value that should be passed in
+ /// mixed integer, floating point, and vector registers, convert it to a
+ /// structure containing the specified struct elements in.
+ void PassInMixedRegisters(const Type *Ty, std::vector<const Type*> &OrigElts,
+ std::vector<const Type*> &ScalarElts);
+};
+
+#endif /* DRAGONEGG_ABI_H */
diff -r -u -N dragonegg-2.9-old/include/dragonegg/ADT/IntervalList.h dragonegg-2.9-new/include/dragonegg/ADT/IntervalList.h
--- dragonegg-2.9-old/include/dragonegg/ADT/IntervalList.h 1970-01-01 01:00:00.000000000 +0100
+++ dragonegg-2.9-new/include/dragonegg/ADT/IntervalList.h 2011-04-09 00:38:06.630097839 +0200
@@ -0,0 +1,218 @@
+//=--------- IntervalList.h - List of disjoint intervals ----------*- C++ -*-=//
+//
+// Copyright (C) 2011 Duncan Sands.
+//
+// This file is part of DragonEgg.
+//
+// DragonEgg is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free Software
+// Foundation; either version 2, or (at your option) any later version.
+//
+// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along with
+// DragonEgg; see the file COPYING. If not, write to the Free Software
+// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
+//
+//===----------------------------------------------------------------------===//
+// This file declares a utility class for maintaining a collection of pairwise
+// disjoint intervals.
+//===----------------------------------------------------------------------===//
+
+#ifndef DRAGONEGG_INTERVALLIST_H
+#define DRAGONEGG_INTERVALLIST_H
+
+// Plugin headers
+#include "dragonegg/ADT/Range.h"
+
+// LLVM headers
+#include "llvm/ADT/SmallVector.h"
+
+/// IntervalList - Maintains a list of disjoint intervals. Type 'T' represents
+/// an interval, and should have a getRange method which returns a range of 'U'
+/// values. In addition it should provide ChangeRangeTo for growing, shrinking
+/// and otherwise changing the shape of the interval; and JoinWith for replacing
+/// the interval with the convex hull of its union with another interval (which
+/// is guaranteed to be disjoint from the original).
+template <class T, typename U, unsigned N>
+class IntervalList {
+ typedef typename llvm::SmallVector<T, N> List;
+ typedef typename List::iterator iterator;
+
+ List Intervals;
+ // The actual intervals. Always disjoint, sorted and non-empty.
+
+ /// CmpFirst - Compare intervals based on where they start.
+ static bool CmpFirst(const T &L, const T &R) {
+ return L.getRange().getFirst() < R.getRange().getFirst();
+ }
+
+ /// CmpLast - Compare intervals based on where they stop.
+ static bool CmpLast(const T &L, const T &R) {
+ return L.getRange().getLast() < R.getRange().getLast();
+ }
+
+ /// isSane - Return true if the intervals are non-empty, disjoint and
+ /// sorted.
+ bool isSane() const {
+ for (unsigned i = 0, e = Intervals.size(); i < e; ++i) {
+ if (Intervals[i].getRange().empty())
+ return false;
+ if (i && Intervals[i].getRange().getFirst() <
+ Intervals[i-1].getRange().getLast())
+ return false;
+ }
+ return true;
+ }
+
+public:
+
+ /// AddInterval - Add the given interval to the list. If it overlaps any
+ /// existing intervals then the existing intervals are pruned by removing
+ /// exactly the parts of them that overlap the new interval. If the added
+ /// interval is empty then it will be discarded.
+ void AddInterval(const T &S);
+
+ /// getNumIntervals - Return the number of intervals in the list.
+ unsigned getNumIntervals() const {
+ return Intervals.size();
+ }
+
+ /// getInterval - Return the interval with the given index.
+ T getInterval(unsigned Idx) {
+ return Intervals[Idx];
+ }
+
+ /// AlignBoundaries - Ensure that all intervals begin and end on a multiple of
+ /// the given value.
+ void AlignBoundaries(unsigned Alignment);
+};
+
+/// AddInterval - Add the given interval to the list. If it overlaps any
+/// existing intervals then the existing intervals are pruned by removing
+/// exactly the parts of them that overlap the new interval. If the added
+/// interval is empty then it will be discarded.
+template <class T, typename U, unsigned N>
+void IntervalList<T, U, N>::AddInterval(const T &Interval) {
+ const Range<U> NewRange = Interval.getRange();
+
+ // If the new interval is empty then there is no point in adding it.
+ if (NewRange.empty())
+ return;
+
+ // If this is the first interval then it cannot overlap any others.
+ if (Intervals.empty()) {
+ Intervals.push_back(Interval);
+ return;
+ }
+
+ // Check for overlap with existing intervals.
+ iterator Lo = std::lower_bound(Intervals.begin(), Intervals.end(), Interval,
+ CmpFirst);
+ iterator Hi = std::upper_bound(Intervals.begin(), Intervals.end(), Interval,
+ CmpLast);
+ if (Lo < Hi) {
+ // Intervals with index in [Lo, Hi) are those completely covered by the new
+ // interval. Throw them away.
+ for (iterator I = Lo; I != Hi; ++I)
+ assert(NewRange.contains(I->getRange()) && "Old interval not covered!");
+ Intervals.erase(Lo, Hi);
+ Hi = Lo;
+ } else if (Hi < Lo) {
+ // The new interval is contained in Hi with an excedent at each end. Chop
+ // the old interval into two pieces (the lower and upper parts) and insert
+ // the new interval between them.
+ const Range<U> OldRange = Hi->getRange();
+ assert(OldRange.contains(NewRange) && "New interval not contained in old!");
+ const Range<U> LowerRange(OldRange.getFirst(), NewRange.getFirst());
+ const Range<U> UpperRange(NewRange.getLast(), OldRange.getLast());
+ assert(!LowerRange.empty() && !UpperRange.empty() && "Degenerate end!");
+ T UpperPart = *Hi;
+ Hi->ChangeRangeTo(LowerRange);
+ UpperPart.ChangeRangeTo(UpperRange);
+ Lo = Intervals.insert(Lo, UpperPart);
+ Intervals.insert(Lo, Interval);
+ assert(isSane() && "Interval added wrong!");
+ return;
+ }
+ assert(Lo == Hi);
+ // Check for overlap with the preceding interval.
+ if (Lo != Intervals.begin()) {
+ const iterator Prev = Lo - 1;
+ const Range<U> PrevRange = Prev->getRange();
+ if (NewRange.getFirst() < PrevRange.getLast())
+ // Shrink the previous interval to remove the overlap.
+ Prev->ChangeRangeTo(Range<U>(PrevRange.getFirst(), NewRange.getFirst()));
+ }
+ // Check for overlap with the following interval.
+ if (Lo != Intervals.end()) {
+ const iterator Next = Lo;
+ const Range<U> NextRange = Next->getRange();
+ if (NextRange.getFirst() < NewRange.getLast())
+ // Shrink the next interval to remove the overlap.
+ Next->ChangeRangeTo(Range<U>(NewRange.getLast(), NextRange.getLast()));
+ }
+ // The new interval is now disjoint from any existing intervals. Insert it.
+ Intervals.insert(Lo, Interval);
+ assert(isSane() && "Interval added wrong!");
+}
+
+/// AlignBoundaries - Ensure that all intervals begin and end on a multiple of
+/// the given value.
+template <class T, typename U, unsigned N>
+void IntervalList<T, U, N>::AlignBoundaries(unsigned Alignment) {
+ assert(Alignment > 0 && "Alignment should be positive!");
+ for (iterator SI = Intervals.begin(); SI != Intervals.end(); ++SI) {
+ T &Interval = *SI;
+ Range<U> OrigRange = Interval.getRange();
+
+ // Round the start of the interval down and the end of the interval up to
+ // the nearest multiple of the alignment.
+ U RoundedFirst = OrigRange.getFirst() - (OrigRange.getFirst() % Alignment);
+ U RoundedLast = OrigRange.getLast() + Alignment - 1;
+ RoundedLast -= RoundedLast % Alignment;
+ Range<U> AlignedRange(RoundedFirst, RoundedLast);
+
+ // There is nothing to do if the interval is already aligned.
+ if (OrigRange == AlignedRange)
+ continue;
+
+ // Merge in all following intervals that start before RoundedLast.
+ iterator Next = SI + 1;
+ for (; Next != Intervals.end() && Next->getRange().getFirst() < RoundedLast;
+ ++Next)
+ Interval.JoinWith(*Next);
+ assert(Interval.getRange().getFirst() == OrigRange.getFirst() &&
+ "Merging at end changed start!");
+
+ // If merging caused the interval to extend beyond RoundedLast then chop the
+ // interval in two at RoundedLast. This stops intervals getting huge due to
+ // repeated merging.
+ if (Interval.getRange().getLast() > RoundedLast) {
+ Range<U> LowerR(OrigRange.getFirst(), RoundedLast);
+ Range<U> UpperR(RoundedLast, Interval.getRange().getLast());
+ // We must have merged in at least the next interval. Reuse it to hold
+ // the part we chop off the end.
+ T &J = *(SI + 1) = Interval;
+ // Chop the end off the original interval so that it stops at RoundedLast
+ // and at the same time extend the start of the original interval down to
+ // the alignment boundary.
+ Interval.ChangeRangeTo(AlignedRange);
+ // Chop the start off the new (following) interval so that it begins at
+ // RoundedLast.
+ J.ChangeRangeTo(UpperR);
+ // Delete any other merged intervals.
+ Intervals.erase(SI + 2, Next);
+ } else {
+ // The interval didn't grow beyond the original alignment boundary. Round
+ // it to those boundaries.
+ Interval.ChangeRangeTo(AlignedRange);
+ // Delete any merged intervals.
+ Intervals.erase(SI + 1, Next);
+ }
+ }
+}
+
+#endif /* DRAGONEGG_INTERVALLIST_H */
diff -r -u -N dragonegg-2.9-old/include/dragonegg/ADT/Range.h dragonegg-2.9-new/include/dragonegg/ADT/Range.h
--- dragonegg-2.9-old/include/dragonegg/ADT/Range.h 1970-01-01 01:00:00.000000000 +0100
+++ dragonegg-2.9-new/include/dragonegg/ADT/Range.h 2011-04-09 00:38:06.630097839 +0200
@@ -0,0 +1,106 @@
+//=------------------ Range.h - Interval of values ----------------*- C++ -*-=//
+//
+// Copyright (C) 2011 Duncan Sands.
+//
+// This file is part of DragonEgg.
+//
+// DragonEgg is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free Software
+// Foundation; either version 2, or (at your option) any later version.
+//
+// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along with
+// DragonEgg; see the file COPYING. If not, write to the Free Software
+// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
+//
+//===----------------------------------------------------------------------===//
+// This file declares a utility class for representing an interval of values.
+//===----------------------------------------------------------------------===//
+
+#ifndef DRAGONEGG_RANGE_H
+#define DRAGONEGG_RANGE_H
+
+/// Range - Represents the interval [First, Last).
+template<typename T>
+class Range {
+ T First, Last;
+public:
+ Range() : First(0), Last(0) {}
+ Range(T first, T last) : First(first), Last(last) {}
+
+ bool operator==(const Range &other) const {
+ return (empty() && other.empty()) ||
+ (First == other.First && Last == other.Last);
+ }
+
+ /// empty - Return whether the range is empty.
+ bool empty() const {
+ return Last <= First;
+ }
+
+ /// getFirst - Return the value defining the start of the range.
+ T getFirst() const {
+ assert(!empty() && "An empty range has no starting value!");
+ return First;
+ }
+
+ /// getLast - Return the value defining the end of the range.
+ T getLast() const {
+ assert(!empty() && "An empty range has no ending value!");
+ return Last;
+ }
+
+ /// getWidth - Return the number of values in the range.
+ T getWidth() const {
+ return empty() ? 0 : Last - First;
+ }
+
+ /// contains - Return true if the given range is contained in this one.
+ bool contains(Range r) const {
+ if (r.empty())
+ return true;
+ if (empty())
+ return false;
+ return First <= r.First && Last >= r.Last;
+ }
+
+ /// intersects - Return true if the given range intersects this one.
+ bool intersects(Range r) const {
+ if (empty() || r.empty())
+ return false;
+ return r.First < Last && r.Last > First;
+ }
+
+ /// Displace - Return the range obtained by adding the given offset.
+ Range Displace(T Offset) const {
+ if (empty())
+ return Range();
+ assert(((Offset >= 0 && First + Offset >= First && Last + Offset >= Last) ||
+ (Offset < 0 && First + Offset < First && Last + Offset < Last)) &&
+ "Displacement wrapped range!");
+ return Range(First + Offset, Last + Offset);
+ }
+
+ /// Join - Return the smallest range containing this range and the given one.
+ Range Join(Range other) const {
+ if (empty())
+ return other;
+ if (other.empty())
+ return *this;
+ return Range(First < other.First ? First : other.First,
+ Last > other.Last ? Last : other.Last);
+ }
+
+ /// Meet - Return the intersection of this range and the given one.
+ Range Meet(Range other) const {
+ if (empty() || other.empty())
+ return Range();
+ return Range(First > other.First ? First : other.First,
+ Last < other.Last ? Last : other.Last);
+ }
+};
+
+#endif /* DRAGONEGG_RANGE_H */
diff -r -u -N dragonegg-2.9-old/include/dragonegg/cache.h dragonegg-2.9-new/include/dragonegg/cache.h
--- dragonegg-2.9-old/include/dragonegg/cache.h 1970-01-01 01:00:00.000000000 +0100
+++ dragonegg-2.9-new/include/dragonegg/cache.h 2011-04-09 00:38:06.630097839 +0200
@@ -0,0 +1,45 @@
+/*===----------- cache.h - Caching values "in" GCC trees ----------*- C -*-===*\
+|* *|
+|* Copyright (C) 2009, 2010, 2011 Duncan Sands. *|
+|* *|
+|* This file is part of DragonEgg. *|
+|* *|
+|* DragonEgg is free software; you can redistribute it and/or modify it under *|
+|* the terms of the GNU General Public License as published by the Free *|
+|* Software Foundation; either version 2, or (at your option) any later *|
+|* version. *|
+|* *|
+|* DragonEgg is distributed in the hope that it will be useful, but WITHOUT *|
+|* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *|
+|* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *|
+|* more details. *|
+|* You should have received a copy of the GNU General Public License along *|
+|* with DragonEgg; see the file COPYING. If not, write to the Free Software *|
+|* Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. *|
+|* *|
+|*===----------------------------------------------------------------------===*|
+|* This code lets you to associate a void* with a tree, as if it were cached *|
+|* inside the tree: if the tree is garbage collected and reallocated, then *|
+|* the cached value will have been cleared. *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef DRAGONEGG_CACHE_H
+#define DRAGONEGG_CACHE_H
+
+union tree_node;
+
+/* llvm_has_cached - Returns whether a value has been associated with the
+ tree. */
+extern int llvm_has_cached(union tree_node *tree);
+
+/* llvm_get_cached - Returns the value associated with the tree, or NULL. */
+extern const void *llvm_get_cached(union tree_node *tree);
+
+/* llvm_set_cached - Associates the given value with the tree (and returns it).
+ To delete an association, pass NULL for the value. */
+extern const void *llvm_set_cached(union tree_node *tree, const void *val);
+
+/* llvm_replace_cached - Replaces all occurrences of old_val with new_val. */
+extern void llvm_replace_cached(const void *old_val, const void *new_val);
+
+#endif /* DRAGONEGG_CACHE_H */
diff -r -u -N dragonegg-2.9-old/include/dragonegg/Constants.h dragonegg-2.9-new/include/dragonegg/Constants.h
--- dragonegg-2.9-old/include/dragonegg/Constants.h 1970-01-01 01:00:00.000000000 +0100
+++ dragonegg-2.9-new/include/dragonegg/Constants.h 2011-04-09 00:38:06.630097839 +0200
@@ -0,0 +1,60 @@
+//=----- Constants.h - Converting and working with constants ------*- C++ -*-=//
+//
+// Copyright (C) 2011 Duncan Sands.
+//
+// This file is part of DragonEgg.
+//
+// DragonEgg is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free Software
+// Foundation; either version 2, or (at your option) any later version.
+//
+// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along with
+// DragonEgg; see the file COPYING. If not, write to the Free Software
+// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
+//
+//===----------------------------------------------------------------------===//
+// This file declares functions for converting GCC constants to LLVM and working
+// with them.
+//===----------------------------------------------------------------------===//
+
+#ifndef DRAGONEGG_CONSTANTS_H
+#define DRAGONEGG_CONSTANTS_H
+
+// Forward declarations.
+namespace llvm {
+ class Constant;
+ class Type;
+}
+union tree_node;
+
+/// AddressOf - Given an expression with a constant address such as a constant,
+/// a global variable or a label, returns the address. The type of the returned
+/// is always a pointer type and, as long as 'exp' does not have void type, the
+/// type of the pointee is the memory type that corresponds to the type of exp
+/// (see ConvertType).
+extern llvm::Constant *AddressOf(tree_node *exp);
+
+/// ConvertInitializer - Convert the initial value for a global variable to an
+/// 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.
+extern llvm::Constant *ConvertInitializer(tree_node *exp);
+
+/// InterpretAsType - Interpret the bits of the given constant (starting from
+/// StartingBit) as representing a constant of type 'Ty'. This results in the
+/// same constant as you would get by storing the bits of 'C' to memory (with
+/// the first bit stored being 'StartingBit') and then loading out a (constant)
+/// value of type 'Ty' from the stored to memory location.
+extern llvm::Constant *InterpretAsType(llvm::Constant *C, const llvm::Type* Ty,
+ int StartingBit);
+
+#endif /* DRAGONEGG_CONSTANTS_H */
diff -r -u -N dragonegg-2.9-old/include/dragonegg/Debug.h dragonegg-2.9-new/include/dragonegg/Debug.h
--- dragonegg-2.9-old/include/dragonegg/Debug.h 1970-01-01 01:00:00.000000000 +0100
+++ dragonegg-2.9-new/include/dragonegg/Debug.h 2011-04-09 00:38:06.630097839 +0200
@@ -0,0 +1,367 @@
+//===------ Debug.h - Interface for generating debug info -------*- C++ -*-===//
+//
+// Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Jim Laskey, Duncan Sands
+// et al.
+//
+// This file is part of DragonEgg.
+//
+// DragonEgg is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free Software
+// Foundation; either version 2, or (at your option) any later version.
+//
+// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along with
+// DragonEgg; see the file COPYING. If not, write to the Free Software
+// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
+//
+//===----------------------------------------------------------------------===//
+// This file declares the debug interfaces shared among the dragonegg files.
+//===----------------------------------------------------------------------===//
+
+#ifndef DRAGONEGG_DEBUG_H
+#define DRAGONEGG_DEBUG_H
+
+// Plugin headers
+#include "dragonegg/Internals.h"
+
+// LLVM headers
+#include "llvm/Analysis/DebugInfo.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/ValueHandle.h"
+
+// System headers
+#include <map>
+
+namespace llvm {
+
+// Forward declarations
+class AllocaInst;
+class BasicBlock;
+class CallInst;
+class Function;
+class Module;
+
+/// DIFactory - This object assists with the construction of the various
+/// descriptors.
+class DIFactory {
+ Module &M;
+ LLVMContext& VMContext;
+
+ Function *DeclareFn; // llvm.dbg.declare
+ Function *ValueFn; // llvm.dbg.value
+
+ DIFactory(const DIFactory &); // DO NOT IMPLEMENT
+ void operator=(const DIFactory&); // DO NOT IMPLEMENT
+ public:
+ enum ComplexAddrKind { OpPlus=1, OpDeref };
+
+ explicit DIFactory(Module &m);
+
+ /// GetOrCreateArray - Create an descriptor for an array of descriptors.
+ /// This implicitly uniques the arrays created.
+ DIArray GetOrCreateArray(DIDescriptor *Tys, unsigned NumTys);
+
+ /// GetOrCreateSubrange - Create a descriptor for a value range. This
+ /// implicitly uniques the values returned.
+ DISubrange GetOrCreateSubrange(int64_t Lo, int64_t Hi);
+
+ /// CreateUnspecifiedParameter - Create unspeicified type descriptor
+ /// for a subroutine type.
+ DIDescriptor CreateUnspecifiedParameter();
+
+ /// CreateCompileUnit - Create a new descriptor for the specified compile
+ /// unit.
+ DICompileUnit CreateCompileUnit(unsigned LangID,
+ StringRef Filename,
+ StringRef Directory,
+ StringRef Producer,
+ bool isMain = false,
+ bool isOptimized = false,
+ StringRef Flags = "",
+ unsigned RunTimeVer = 0);
+
+ /// CreateFile - Create a new descriptor for the specified file.
+ DIFile CreateFile(StringRef Filename, StringRef Directory,
+ DICompileUnit CU);
+
+ /// CreateEnumerator - Create a single enumerator value.
+ DIEnumerator CreateEnumerator(StringRef Name, uint64_t Val);
+
+ /// CreateBasicType - Create a basic type like int, float, etc.
+ DIBasicType CreateBasicType(DIDescriptor Context, StringRef Name,
+ DIFile F, unsigned LineNumber,
+ uint64_t SizeInBits, uint64_t AlignInBits,
+ uint64_t OffsetInBits, unsigned Flags,
+ unsigned Encoding);
+
+ /// CreateBasicType - Create a basic type like int, float, etc.
+ DIBasicType CreateBasicTypeEx(DIDescriptor Context, StringRef Name,
+ DIFile F, unsigned LineNumber,
+ Constant *SizeInBits, Constant *AlignInBits,
+ Constant *OffsetInBits, unsigned Flags,
+ unsigned Encoding);
+
+ /// CreateDerivedType - Create a derived type like const qualified type,
+ /// pointer, typedef, etc.
+ DIDerivedType CreateDerivedType(unsigned Tag, DIDescriptor Context,
+ StringRef Name,
+ DIFile F,
+ unsigned LineNumber,
+ uint64_t SizeInBits, uint64_t AlignInBits,
+ uint64_t OffsetInBits, unsigned Flags,
+ DIType DerivedFrom);
+
+ /// CreateDerivedType - Create a derived type like const qualified type,
+ /// pointer, typedef, etc.
+ DIDerivedType CreateDerivedTypeEx(unsigned Tag, DIDescriptor Context,
+ StringRef Name,
+ DIFile F,
+ unsigned LineNumber,
+ Constant *SizeInBits,
+ Constant *AlignInBits,
+ Constant *OffsetInBits, unsigned Flags,
+ DIType DerivedFrom);
+
+ /// CreateCompositeType - Create a composite type like array, struct, etc.
+ DICompositeType CreateCompositeType(unsigned Tag, DIDescriptor Context,
+ StringRef Name,
+ DIFile F,
+ unsigned LineNumber,
+ uint64_t SizeInBits,
+ uint64_t AlignInBits,
+ uint64_t OffsetInBits, unsigned Flags,
+ DIType DerivedFrom,
+ DIArray Elements,
+ unsigned RunTimeLang = 0,
+ MDNode *ContainingType = 0);
+
+ /// CreateTemporaryType - Create a temporary forward-declared type.
+ DIType CreateTemporaryType();
+ DIType CreateTemporaryType(DIFile F);
+
+ /// CreateArtificialType - Create a new DIType with "artificial" flag set.
+ DIType CreateArtificialType(DIType Ty);
+
+ /// CreateCompositeType - Create a composite type like array, struct, etc.
+ DICompositeType CreateCompositeTypeEx(unsigned Tag, DIDescriptor Context,
+ StringRef Name,
+ DIFile F,
+ unsigned LineNumber,
+ Constant *SizeInBits,
+ Constant *AlignInBits,
+ Constant *OffsetInBits,
+ unsigned Flags,
+ DIType DerivedFrom,
+ DIArray Elements,
+ unsigned RunTimeLang = 0,
+ MDNode *ContainingType = 0);
+
+ /// CreateSubprogram - Create a new descriptor for the specified subprogram.
+ /// See comments in DISubprogram for descriptions of these fields.
+ DISubprogram CreateSubprogram(DIDescriptor Context, StringRef Name,
+ StringRef DisplayName,
+ StringRef LinkageName,
+ DIFile F, unsigned LineNo,
+ DIType Ty, bool isLocalToUnit,
+ bool isDefinition,
+ unsigned VK = 0,
+ unsigned VIndex = 0,
+ DIType ContainingType = DIType(),
+ unsigned Flags = 0,
+ bool isOptimized = false,
+ Function *Fn = 0);
+
+ /// CreateSubprogramDefinition - Create new subprogram descriptor for the
+ /// given declaration.
+ DISubprogram CreateSubprogramDefinition(DISubprogram &SPDeclaration);
+
+ /// CreateGlobalVariable - Create a new descriptor for the specified global.
+ DIGlobalVariable
+ CreateGlobalVariable(DIDescriptor Context, StringRef Name,
+ StringRef DisplayName,
+ StringRef LinkageName,
+ DIFile F,
+ unsigned LineNo, DIType Ty, bool isLocalToUnit,
+ bool isDefinition, llvm::GlobalVariable *GV);
+
+ /// CreateGlobalVariable - Create a new descriptor for the specified constant.
+ DIGlobalVariable
+ CreateGlobalVariable(DIDescriptor Context, StringRef Name,
+ StringRef DisplayName,
+ StringRef LinkageName,
+ DIFile F,
+ unsigned LineNo, DIType Ty, bool isLocalToUnit,
+ bool isDefinition, llvm::Constant *C);
+
+ /// CreateVariable - Create a new descriptor for the specified variable.
+ DIVariable CreateVariable(unsigned Tag, DIDescriptor Context,
+ StringRef Name,
+ DIFile F, unsigned LineNo,
+ DIType Ty, bool AlwaysPreserve = false,
+ unsigned Flags = 0);
+
+ /// CreateComplexVariable - Create a new descriptor for the specified
+ /// variable which has a complex address expression for its address.
+ DIVariable CreateComplexVariable(unsigned Tag, DIDescriptor Context,
+ StringRef Name, DIFile F, unsigned LineNo,
+ DIType Ty, Value *const *Addr,
+ unsigned NumAddr);
+
+ /// CreateLexicalBlock - This creates a descriptor for a lexical block
+ /// with the specified parent context.
+ DILexicalBlock CreateLexicalBlock(DIDescriptor Context, DIFile F,
+ unsigned Line = 0, unsigned Col = 0);
+
+ /// CreateNameSpace - This creates new descriptor for a namespace
+ /// with the specified parent context.
+ DINameSpace CreateNameSpace(DIDescriptor Context, StringRef Name,
+ DIFile F, unsigned LineNo);
+
+ /// CreateLocation - Creates a debug info location.
+ DILocation CreateLocation(unsigned LineNo, unsigned ColumnNo,
+ DIScope S, DILocation OrigLoc);
+
+ /// CreateLocation - Creates a debug info location.
+ DILocation CreateLocation(unsigned LineNo, unsigned ColumnNo,
+ DIScope S, MDNode *OrigLoc = 0);
+
+ /// InsertDeclare - Insert a new llvm.dbg.declare intrinsic call.
+ Instruction *InsertDeclare(llvm::Value *Storage, DIVariable D,
+ BasicBlock *InsertAtEnd);
+
+ /// InsertDeclare - Insert a new llvm.dbg.declare intrinsic call.
+ Instruction *InsertDeclare(llvm::Value *Storage, DIVariable D,
+ Instruction *InsertBefore);
+
+ /// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
+ Instruction *InsertDbgValueIntrinsic(llvm::Value *V, uint64_t Offset,
+ DIVariable D, BasicBlock *InsertAtEnd);
+
+ /// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
+ Instruction *InsertDbgValueIntrinsic(llvm::Value *V, uint64_t Offset,
+ DIVariable D, Instruction *InsertBefore);
+
+ // RecordType - Record DIType in a module such that it is not lost even if
+ // it is not referenced through debug info anchors.
+ void RecordType(DIType T);
+
+ private:
+ Constant *GetTagConstant(unsigned TAG);
+};
+
+/// DebugInfo - This class gathers all debug information during compilation and
+/// is responsible for emitting to llvm globals or pass directly to the backend.
+class DebugInfo {
+private:
+ Module *M; // The current module.
+ DIFactory DebugFactory;
+ const char *CurFullPath; // Previous location file encountered.
+ int CurLineNo; // Previous location line# encountered.
+ const char *PrevFullPath; // Previous location file encountered.
+ int PrevLineNo; // Previous location line# encountered.
+ BasicBlock *PrevBB; // Last basic block encountered.
+
+ DICompileUnit TheCU; // The compile unit.
+
+ std::map<tree_node *, WeakVH > TypeCache;
+ // Cache of previously constructed
+ // Types.
+ std::map<tree_node *, WeakVH > SPCache;
+ // Cache of previously constructed
+ // Subprograms.
+ std::map<tree_node *, WeakVH> NameSpaceCache;
+ // Cache of previously constructed name
+ // spaces.
+
+ SmallVector<WeakVH, 4> RegionStack;
+ // Stack to track declarative scopes.
+
+ std::map<tree_node *, WeakVH> RegionMap;
+
+ /// FunctionNames - This is a storage for function names that are
+ /// constructed on demand. For example, C++ destructors, C++ operators etc..
+ llvm::BumpPtrAllocator FunctionNames;
+
+public:
+ DebugInfo(Module *m);
+
+ /// Initialize - Initialize debug info by creating compile unit for
+ /// main_input_filename. This must be invoked after language dependent
+ /// initialization is done.
+ void Initialize();
+
+ // Accessors.
+ void setLocationFile(const char *FullPath) { CurFullPath = FullPath; }
+ void setLocationLine(int LineNo) { CurLineNo = LineNo; }
+
+ /// EmitFunctionStart - Constructs the debug code for entering a function -
+ /// "llvm.dbg.func.start."
+ void EmitFunctionStart(tree_node *FnDecl, Function *Fn);
+
+ /// EmitFunctionEnd - Constructs the debug code for exiting a declarative
+ /// region - "llvm.dbg.region.end."
+ void EmitFunctionEnd(bool EndFunction);
+
+ /// EmitDeclare - Constructs the debug code for allocation of a new variable.
+ /// region - "llvm.dbg.declare."
+ void EmitDeclare(tree_node *decl, unsigned Tag, const char *Name,
+ tree_node *type, Value *AI, LLVMBuilder &Builder);
+
+ /// EmitStopPoint - Emit a call to llvm.dbg.stoppoint to indicate a change of
+ /// source line.
+ void EmitStopPoint(BasicBlock *CurBB, LLVMBuilder &Builder);
+
+ /// EmitGlobalVariable - Emit information about a global variable.
+ ///
+ void EmitGlobalVariable(GlobalVariable *GV, tree_node *decl);
+
+ /// getOrCreateType - Get the type from the cache or create a new type if
+ /// necessary.
+ DIType getOrCreateType(tree_node *type);
+
+ /// createBasicType - Create BasicType.
+ DIType createBasicType(tree_node *type);
+
+ /// createMethodType - Create MethodType.
+ DIType createMethodType(tree_node *type);
+
+ /// createPointerType - Create PointerType.
+ DIType createPointerType(tree_node *type);
+
+ /// createArrayType - Create ArrayType.
+ DIType createArrayType(tree_node *type);
+
+ /// createEnumType - Create EnumType.
+ DIType createEnumType(tree_node *type);
+
+ /// createStructType - Create StructType for struct or union or class.
+ DIType createStructType(tree_node *type);
+
+ /// createVarinatType - Create variant type or return MainTy.
+ DIType createVariantType(tree_node *type, DIType MainTy);
+
+ /// getOrCreateCompileUnit - Create a new compile unit.
+ DICompileUnit getOrCreateCompileUnit(const char *FullPath,
+ bool isMain = false);
+
+ /// getOrCreateFile - Get DIFile descriptor.
+ DIFile getOrCreateFile(const char *FullPath);
+
+ /// findRegion - Find tree_node N's region.
+ DIDescriptor findRegion(tree_node *n);
+
+ /// getOrCreateNameSpace - Get name space descriptor for the tree node.
+ DINameSpace getOrCreateNameSpace(tree_node *Node, DIDescriptor Context);
+
+ /// getFunctionName - Get function name for the given FnDecl. If the
+ /// name is constructred on demand (e.g. C++ destructor) then the name
+ /// is stored on the side.
+ StringRef getFunctionName(tree_node *FnDecl);
+};
+
+} // end namespace llvm
+
+#endif /* DRAGONEGG_DEBUG_H */
diff -r -u -N dragonegg-2.9-old/include/dragonegg/gt-cache.h dragonegg-2.9-new/include/dragonegg/gt-cache.h
--- dragonegg-2.9-old/include/dragonegg/gt-cache.h 1970-01-01 01:00:00.000000000 +0100
+++ dragonegg-2.9-new/include/dragonegg/gt-cache.h 2011-04-09 00:38:06.630097839 +0200
@@ -0,0 +1,802 @@
+/* Type information for GCC.
+ Copyright (C) 2004, 2007, 2009 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+/* This file is machine generated. Do not edit. */
+
+/* GC marker procedures. */
+/* macros and declarations */
+#define gt_ggc_m_13tree_llvm_map(X) do { \
+ if (X != NULL) gt_ggc_mx_tree_llvm_map (X);\
+ } while (0)
+extern void gt_ggc_mx_tree_llvm_map (void *);
+#define gt_ggc_m_15interface_tuple(X) do { \
+ if (X != NULL) gt_ggc_mx_interface_tuple (X);\
+ } while (0)
+extern void gt_ggc_mx_interface_tuple (void *);
+#define gt_ggc_m_16volatilized_type(X) do { \
+ if (X != NULL) gt_ggc_mx_volatilized_type (X);\
+ } while (0)
+extern void gt_ggc_mx_volatilized_type (void *);
+#define gt_ggc_m_17string_descriptor(X) do { \
+ if (X != NULL) gt_ggc_mx_string_descriptor (X);\
+ } while (0)
+extern void gt_ggc_mx_string_descriptor (void *);
+#define gt_ggc_m_15c_inline_static(X) do { \
+ if (X != NULL) gt_ggc_mx_c_inline_static (X);\
+ } while (0)
+extern void gt_ggc_mx_c_inline_static (void *);
+#define gt_ggc_m_24VEC_c_goto_bindings_p_gc(X) do { \
+ if (X != NULL) gt_ggc_mx_VEC_c_goto_bindings_p_gc (X);\
+ } while (0)
+extern void gt_ggc_mx_VEC_c_goto_bindings_p_gc (void *);
+#define gt_ggc_m_15c_goto_bindings(X) do { \
+ if (X != NULL) gt_ggc_mx_c_goto_bindings (X);\
+ } while (0)
+extern void gt_ggc_mx_c_goto_bindings (void *);
+#define gt_ggc_m_7c_scope(X) do { \
+ if (X != NULL) gt_ggc_mx_c_scope (X);\
+ } while (0)
+extern void gt_ggc_mx_c_scope (void *);
+#define gt_ggc_m_9c_binding(X) do { \
+ if (X != NULL) gt_ggc_mx_c_binding (X);\
+ } while (0)
+extern void gt_ggc_mx_c_binding (void *);
+#define gt_ggc_m_12c_label_vars(X) do { \
+ if (X != NULL) gt_ggc_mx_c_label_vars (X);\
+ } while (0)
+extern void gt_ggc_mx_c_label_vars (void *);
+#define gt_ggc_m_8c_parser(X) do { \
+ if (X != NULL) gt_ggc_mx_c_parser (X);\
+ } while (0)
+extern void gt_ggc_mx_c_parser (void *);
+#define gt_ggc_m_9imp_entry(X) do { \
+ if (X != NULL) gt_ggc_mx_imp_entry (X);\
+ } while (0)
+extern void gt_ggc_mx_imp_entry (void *);
+#define gt_ggc_m_16hashed_attribute(X) do { \
+ if (X != NULL) gt_ggc_mx_hashed_attribute (X);\
+ } while (0)
+extern void gt_ggc_mx_hashed_attribute (void *);
+#define gt_ggc_m_12hashed_entry(X) do { \
+ if (X != NULL) gt_ggc_mx_hashed_entry (X);\
+ } while (0)
+extern void gt_ggc_mx_hashed_entry (void *);
+#define gt_ggc_m_14type_assertion(X) do { \
+ if (X != NULL) gt_ggc_mx_type_assertion (X);\
+ } while (0)
+extern void gt_ggc_mx_type_assertion (void *);
+#define gt_ggc_m_18treetreehash_entry(X) do { \
+ if (X != NULL) gt_ggc_mx_treetreehash_entry (X);\
+ } while (0)
+extern void gt_ggc_mx_treetreehash_entry (void *);
+#define gt_ggc_m_5CPool(X) do { \
+ if (X != NULL) gt_ggc_mx_CPool (X);\
+ } while (0)
+extern void gt_ggc_mx_CPool (void *);
+#define gt_ggc_m_3JCF(X) do { \
+ if (X != NULL) gt_ggc_mx_JCF (X);\
+ } while (0)
+extern void gt_ggc_mx_JCF (void *);
+#define gt_ggc_m_17module_htab_entry(X) do { \
+ if (X != NULL) gt_ggc_mx_module_htab_entry (X);\
+ } while (0)
+extern void gt_ggc_mx_module_htab_entry (void *);
+#define gt_ggc_m_13binding_level(X) do { \
+ if (X != NULL) gt_ggc_mx_binding_level (X);\
+ } while (0)
+extern void gt_ggc_mx_binding_level (void *);
+#define gt_ggc_m_9opt_stack(X) do { \
+ if (X != NULL) gt_ggc_mx_opt_stack (X);\
+ } while (0)
+extern void gt_ggc_mx_opt_stack (void *);
+#define gt_ggc_m_16def_pragma_macro(X) do { \
+ if (X != NULL) gt_ggc_mx_def_pragma_macro (X);\
+ } while (0)
+extern void gt_ggc_mx_def_pragma_macro (void *);
+#define gt_ggc_m_22def_pragma_macro_value(X) do { \
+ if (X != NULL) gt_ggc_mx_def_pragma_macro_value (X);\
+ } while (0)
+extern void gt_ggc_mx_def_pragma_macro_value (void *);
+#define gt_ggc_m_11align_stack(X) do { \
+ if (X != NULL) gt_ggc_mx_align_stack (X);\
+ } while (0)
+extern void gt_ggc_mx_align_stack (void *);
+#define gt_ggc_m_18VEC_tree_gc_vec_gc(X) do { \
+ if (X != NULL) gt_ggc_mx_VEC_tree_gc_vec_gc (X);\
+ } while (0)
+extern void gt_ggc_mx_VEC_tree_gc_vec_gc (void *);
+#define gt_ggc_m_19VEC_const_char_p_gc(X) do { \
+ if (X != NULL) gt_ggc_mx_VEC_const_char_p_gc (X);\
+ } while (0)
+extern void gt_ggc_mx_VEC_const_char_p_gc (void *);
+#define gt_ggc_m_21pending_abstract_type(X) do { \
+ if (X != NULL) gt_ggc_mx_pending_abstract_type (X);\
+ } while (0)
+extern void gt_ggc_mx_pending_abstract_type (void *);
+#define gt_ggc_m_15VEC_tree_int_gc(X) do { \
+ if (X != NULL) gt_ggc_mx_VEC_tree_int_gc (X);\
+ } while (0)
+extern void gt_ggc_mx_VEC_tree_int_gc (void *);
+#define gt_ggc_m_9cp_parser(X) do { \
+ if (X != NULL) gt_ggc_mx_cp_parser (X);\
+ } while (0)
+extern void gt_ggc_mx_cp_parser (void *);
+#define gt_ggc_m_17cp_parser_context(X) do { \
+ if (X != NULL) gt_ggc_mx_cp_parser_context (X);\
+ } while (0)
+extern void gt_ggc_mx_cp_parser_context (void *);
+#define gt_ggc_m_8cp_lexer(X) do { \
+ if (X != NULL) gt_ggc_mx_cp_lexer (X);\
+ } while (0)
+extern void gt_ggc_mx_cp_lexer (void *);
+#define gt_ggc_m_10tree_check(X) do { \
+ if (X != NULL) gt_ggc_mx_tree_check (X);\
+ } while (0)
+extern void gt_ggc_mx_tree_check (void *);
+#define gt_ggc_m_22VEC_deferred_access_gc(X) do { \
+ if (X != NULL) gt_ggc_mx_VEC_deferred_access_gc (X);\
+ } while (0)
+extern void gt_ggc_mx_VEC_deferred_access_gc (void *);
+#define gt_ggc_m_10spec_entry(X) do { \
+ if (X != NULL) gt_ggc_mx_spec_entry (X);\
+ } while (0)
+extern void gt_ggc_mx_spec_entry (void *);
+#define gt_ggc_m_16pending_template(X) do { \
+ if (X != NULL) gt_ggc_mx_pending_template (X);\
+ } while (0)
+extern void gt_ggc_mx_pending_template (void *);
+#define gt_ggc_m_21named_label_use_entry(X) do { \
+ if (X != NULL) gt_ggc_mx_named_label_use_entry (X);\
+ } while (0)
+extern void gt_ggc_mx_named_label_use_entry (void *);
+#define gt_ggc_m_28VEC_deferred_access_check_gc(X) do { \
+ if (X != NULL) gt_ggc_mx_VEC_deferred_access_check_gc (X);\
+ } while (0)
+extern void gt_ggc_mx_VEC_deferred_access_check_gc (void *);
+#define gt_ggc_m_11tinst_level(X) do { \
+ if (X != NULL) gt_ggc_mx_tinst_level (X);\
+ } while (0)
+extern void gt_ggc_mx_tinst_level (void *);
+#define gt_ggc_m_18sorted_fields_type(X) do { \
+ if (X != NULL) gt_ggc_mx_sorted_fields_type (X);\
+ } while (0)
+extern void gt_ggc_mx_sorted_fields_type (void *);
+#define gt_ggc_m_18VEC_tree_pair_s_gc(X) do { \
+ if (X != NULL) gt_ggc_mx_VEC_tree_pair_s_gc (X);\
+ } while (0)
+extern void gt_ggc_mx_VEC_tree_pair_s_gc (void *);
+#define gt_ggc_m_17named_label_entry(X) do { \
+ if (X != NULL) gt_ggc_mx_named_label_entry (X);\
+ } while (0)
+extern void gt_ggc_mx_named_label_entry (void *);
+#define gt_ggc_m_14cp_token_cache(X) do { \
+ if (X != NULL) gt_ggc_mx_cp_token_cache (X);\
+ } while (0)
+extern void gt_ggc_mx_cp_token_cache (void *);
+#define gt_ggc_m_11saved_scope(X) do { \
+ if (X != NULL) gt_ggc_mx_saved_scope (X);\
+ } while (0)
+extern void gt_ggc_mx_saved_scope (void *);
+#define gt_ggc_m_16cxx_int_tree_map(X) do { \
+ if (X != NULL) gt_ggc_mx_cxx_int_tree_map (X);\
+ } while (0)
+extern void gt_ggc_mx_cxx_int_tree_map (void *);
+#define gt_ggc_m_23VEC_cp_class_binding_gc(X) do { \
+ if (X != NULL) gt_ggc_mx_VEC_cp_class_binding_gc (X);\
+ } while (0)
+extern void gt_ggc_mx_VEC_cp_class_binding_gc (void *);
+#define gt_ggc_m_24VEC_cxx_saved_binding_gc(X) do { \
+ if (X != NULL) gt_ggc_mx_VEC_cxx_saved_binding_gc (X);\
+ } while (0)
+extern void gt_ggc_mx_VEC_cxx_saved_binding_gc (void *);
+#define gt_ggc_m_16cp_binding_level(X) do { \
+ if (X != NULL) gt_ggc_mx_cp_binding_level (X);\
+ } while (0)
+extern void gt_ggc_mx_cp_binding_level (void *);
+#define gt_ggc_m_11cxx_binding(X) do { \
+ if (X != NULL) gt_ggc_mx_cxx_binding (X);\
+ } while (0)
+extern void gt_ggc_mx_cxx_binding (void *);
+#define gt_ggc_m_15binding_entry_s(X) do { \
+ if (X != NULL) gt_ggc_mx_binding_entry_s (X);\
+ } while (0)
+extern void gt_ggc_mx_binding_entry_s (void *);
+#define gt_ggc_m_15binding_table_s(X) do { \
+ if (X != NULL) gt_ggc_mx_binding_table_s (X);\
+ } while (0)
+extern void gt_ggc_mx_binding_table_s (void *);
+#define gt_ggc_m_14VEC_tinfo_s_gc(X) do { \
+ if (X != NULL) gt_ggc_mx_VEC_tinfo_s_gc (X);\
+ } while (0)
+extern void gt_ggc_mx_VEC_tinfo_s_gc (void *);
+#define gt_ggc_m_18gnat_binding_level(X) do { \
+ if (X != NULL) gt_ggc_mx_gnat_binding_level (X);\
+ } while (0)
+extern void gt_ggc_mx_gnat_binding_level (void *);
+#define gt_ggc_m_9elab_info(X) do { \
+ if (X != NULL) gt_ggc_mx_elab_info (X);\
+ } while (0)
+extern void gt_ggc_mx_elab_info (void *);
+#define gt_ggc_m_10stmt_group(X) do { \
+ if (X != NULL) gt_ggc_mx_stmt_group (X);\
+ } while (0)
+extern void gt_ggc_mx_stmt_group (void *);
+#define gt_ggc_m_16VEC_parm_attr_gc(X) do { \
+ if (X != NULL) gt_ggc_mx_VEC_parm_attr_gc (X);\
+ } while (0)
+extern void gt_ggc_mx_VEC_parm_attr_gc (void *);
+#define gt_ggc_m_11parm_attr_d(X) do { \
+ if (X != NULL) gt_ggc_mx_parm_attr_d (X);\
+ } while (0)
+extern void gt_ggc_mx_parm_attr_d (void *);
+#define gt_ggc_m_22VEC_ipa_edge_args_t_gc(X) do { \
+ if (X != NULL) gt_ggc_mx_VEC_ipa_edge_args_t_gc (X);\
+ } while (0)
+extern void gt_ggc_mx_VEC_ipa_edge_args_t_gc (void *);
+#define gt_ggc_m_20lto_symtab_entry_def(X) do { \
+ if (X != NULL) gt_ggc_mx_lto_symtab_entry_def (X);\
+ } while (0)
+extern void gt_ggc_mx_lto_symtab_entry_def (void *);
+#define gt_ggc_m_20ssa_operand_memory_d(X) do { \
+ if (X != NULL) gt_ggc_mx_ssa_operand_memory_d (X);\
+ } while (0)
+extern void gt_ggc_mx_ssa_operand_memory_d (void *);
+#define gt_ggc_m_13scev_info_str(X) do { \
+ if (X != NULL) gt_ggc_mx_scev_info_str (X);\
+ } while (0)
+extern void gt_ggc_mx_scev_info_str (void *);
+#define gt_ggc_m_13VEC_gimple_gc(X) do { \
+ if (X != NULL) gt_ggc_mx_VEC_gimple_gc (X);\
+ } while (0)
+extern void gt_ggc_mx_VEC_gimple_gc (void *);
+#define gt_ggc_m_9type_hash(X) do { \
+ if (X != NULL) gt_ggc_mx_type_hash (X);\
+ } while (0)
+extern void gt_ggc_mx_type_hash (void *);
+#define gt_ggc_m_16string_pool_data(X) do { \
+ if (X != NULL) gt_ggc_mx_string_pool_data (X);\
+ } while (0)
+extern void gt_ggc_mx_string_pool_data (void *);
+#define gt_ggc_m_13libfunc_entry(X) do { \
+ if (X != NULL) gt_ggc_mx_libfunc_entry (X);\
+ } while (0)
+extern void gt_ggc_mx_libfunc_entry (void *);
+#define gt_ggc_m_23temp_slot_address_entry(X) do { \
+ if (X != NULL) gt_ggc_mx_temp_slot_address_entry (X);\
+ } while (0)
+extern void gt_ggc_mx_temp_slot_address_entry (void *);
+#define gt_ggc_m_15throw_stmt_node(X) do { \
+ if (X != NULL) gt_ggc_mx_throw_stmt_node (X);\
+ } while (0)
+extern void gt_ggc_mx_throw_stmt_node (void *);
+#define gt_ggc_m_21VEC_eh_landing_pad_gc(X) do { \
+ if (X != NULL) gt_ggc_mx_VEC_eh_landing_pad_gc (X);\
+ } while (0)
+extern void gt_ggc_mx_VEC_eh_landing_pad_gc (void *);
+#define gt_ggc_m_16VEC_eh_region_gc(X) do { \
+ if (X != NULL) gt_ggc_mx_VEC_eh_region_gc (X);\
+ } while (0)
+extern void gt_ggc_mx_VEC_eh_region_gc (void *);
+#define gt_ggc_m_10eh_catch_d(X) do { \
+ if (X != NULL) gt_ggc_mx_eh_catch_d (X);\
+ } while (0)
+extern void gt_ggc_mx_eh_catch_d (void *);
+#define gt_ggc_m_16eh_landing_pad_d(X) do { \
+ if (X != NULL) gt_ggc_mx_eh_landing_pad_d (X);\
+ } while (0)
+extern void gt_ggc_mx_eh_landing_pad_d (void *);
+#define gt_ggc_m_11eh_region_d(X) do { \
+ if (X != NULL) gt_ggc_mx_eh_region_d (X);\
+ } while (0)
+extern void gt_ggc_mx_eh_region_d (void *);
+#define gt_ggc_m_10vcall_insn(X) do { \
+ if (X != NULL) gt_ggc_mx_vcall_insn (X);\
+ } while (0)
+extern void gt_ggc_mx_vcall_insn (void *);
+#define gt_ggc_m_18VEC_vcall_entry_gc(X) do { \
+ if (X != NULL) gt_ggc_mx_VEC_vcall_entry_gc (X);\
+ } while (0)
+extern void gt_ggc_mx_VEC_vcall_entry_gc (void *);
+#define gt_ggc_m_18VEC_dcall_entry_gc(X) do { \
+ if (X != NULL) gt_ggc_mx_VEC_dcall_entry_gc (X);\
+ } while (0)
+extern void gt_ggc_mx_VEC_dcall_entry_gc (void *);
+#define gt_ggc_m_16var_loc_list_def(X) do { \
+ if (X != NULL) gt_ggc_mx_var_loc_list_def (X);\
+ } while (0)
+extern void gt_ggc_mx_var_loc_list_def (void *);
+#define gt_ggc_m_12var_loc_node(X) do { \
+ if (X != NULL) gt_ggc_mx_var_loc_node (X);\
+ } while (0)
+extern void gt_ggc_mx_var_loc_node (void *);
+#define gt_ggc_m_20VEC_die_arg_entry_gc(X) do { \
+ if (X != NULL) gt_ggc_mx_VEC_die_arg_entry_gc (X);\
+ } while (0)
+extern void gt_ggc_mx_VEC_die_arg_entry_gc (void *);
+#define gt_ggc_m_16limbo_die_struct(X) do { \
+ if (X != NULL) gt_ggc_mx_limbo_die_struct (X);\
+ } while (0)
+extern void gt_ggc_mx_limbo_die_struct (void *);
+#define gt_ggc_m_20VEC_pubname_entry_gc(X) do { \
+ if (X != NULL) gt_ggc_mx_VEC_pubname_entry_gc (X);\
+ } while (0)
+extern void gt_ggc_mx_VEC_pubname_entry_gc (void *);
+#define gt_ggc_m_19VEC_dw_attr_node_gc(X) do { \
+ if (X != NULL) gt_ggc_mx_VEC_dw_attr_node_gc (X);\
+ } while (0)
+extern void gt_ggc_mx_VEC_dw_attr_node_gc (void *);
+#define gt_ggc_m_18comdat_type_struct(X) do { \
+ if (X != NULL) gt_ggc_mx_comdat_type_struct (X);\
+ } while (0)
+extern void gt_ggc_mx_comdat_type_struct (void *);
+#define gt_ggc_m_25dw_ranges_by_label_struct(X) do { \
+ if (X != NULL) gt_ggc_mx_dw_ranges_by_label_struct (X);\
+ } while (0)
+extern void gt_ggc_mx_dw_ranges_by_label_struct (void *);
+#define gt_ggc_m_16dw_ranges_struct(X) do { \
+ if (X != NULL) gt_ggc_mx_dw_ranges_struct (X);\
+ } while (0)
+extern void gt_ggc_mx_dw_ranges_struct (void *);
+#define gt_ggc_m_28dw_separate_line_info_struct(X) do { \
+ if (X != NULL) gt_ggc_mx_dw_separate_line_info_struct (X);\
+ } while (0)
+extern void gt_ggc_mx_dw_separate_line_info_struct (void *);
+#define gt_ggc_m_19dw_line_info_struct(X) do { \
+ if (X != NULL) gt_ggc_mx_dw_line_info_struct (X);\
+ } while (0)
+extern void gt_ggc_mx_dw_line_info_struct (void *);
+#define gt_ggc_m_25VEC_deferred_locations_gc(X) do { \
+ if (X != NULL) gt_ggc_mx_VEC_deferred_locations_gc (X);\
+ } while (0)
+extern void gt_ggc_mx_VEC_deferred_locations_gc (void *);
+#define gt_ggc_m_18dw_loc_list_struct(X) do { \
+ if (X != NULL) gt_ggc_mx_dw_loc_list_struct (X);\
+ } while (0)
+extern void gt_ggc_mx_dw_loc_list_struct (void *);
+#define gt_ggc_m_15dwarf_file_data(X) do { \
+ if (X != NULL) gt_ggc_mx_dwarf_file_data (X);\
+ } while (0)
+extern void gt_ggc_mx_dwarf_file_data (void *);
+#define gt_ggc_m_15queued_reg_save(X) do { \
+ if (X != NULL) gt_ggc_mx_queued_reg_save (X);\
+ } while (0)
+extern void gt_ggc_mx_queued_reg_save (void *);
+#define gt_ggc_m_20indirect_string_node(X) do { \
+ if (X != NULL) gt_ggc_mx_indirect_string_node (X);\
+ } while (0)
+extern void gt_ggc_mx_indirect_string_node (void *);
+#define gt_ggc_m_19dw_loc_descr_struct(X) do { \
+ if (X != NULL) gt_ggc_mx_dw_loc_descr_struct (X);\
+ } while (0)
+extern void gt_ggc_mx_dw_loc_descr_struct (void *);
+#define gt_ggc_m_13dw_fde_struct(X) do { \
+ if (X != NULL) gt_ggc_mx_dw_fde_struct (X);\
+ } while (0)
+extern void gt_ggc_mx_dw_fde_struct (void *);
+#define gt_ggc_m_13dw_cfi_struct(X) do { \
+ if (X != NULL) gt_ggc_mx_dw_cfi_struct (X);\
+ } while (0)
+extern void gt_ggc_mx_dw_cfi_struct (void *);
+#define gt_ggc_m_8typeinfo(X) do { \
+ if (X != NULL) gt_ggc_mx_typeinfo (X);\
+ } while (0)
+extern void gt_ggc_mx_typeinfo (void *);
+#define gt_ggc_m_22VEC_alias_set_entry_gc(X) do { \
+ if (X != NULL) gt_ggc_mx_VEC_alias_set_entry_gc (X);\
+ } while (0)
+extern void gt_ggc_mx_VEC_alias_set_entry_gc (void *);
+#define gt_ggc_m_17alias_set_entry_d(X) do { \
+ if (X != NULL) gt_ggc_mx_alias_set_entry_d (X);\
+ } while (0)
+extern void gt_ggc_mx_alias_set_entry_d (void *);
+#define gt_ggc_m_24constant_descriptor_tree(X) do { \
+ if (X != NULL) gt_ggc_mx_constant_descriptor_tree (X);\
+ } while (0)
+extern void gt_ggc_mx_constant_descriptor_tree (void *);
+#define gt_ggc_m_15cgraph_asm_node(X) do { \
+ if (X != NULL) gt_ggc_mx_cgraph_asm_node (X);\
+ } while (0)
+extern void gt_ggc_mx_cgraph_asm_node (void *);
+#define gt_ggc_m_12varpool_node(X) do { \
+ if (X != NULL) gt_ggc_mx_varpool_node (X);\
+ } while (0)
+extern void gt_ggc_mx_varpool_node (void *);
+#define gt_ggc_m_22VEC_cgraph_node_set_gc(X) do { \
+ if (X != NULL) gt_ggc_mx_VEC_cgraph_node_set_gc (X);\
+ } while (0)
+extern void gt_ggc_mx_VEC_cgraph_node_set_gc (void *);
+#define gt_ggc_m_19cgraph_node_set_def(X) do { \
+ if (X != NULL) gt_ggc_mx_cgraph_node_set_def (X);\
+ } while (0)
+extern void gt_ggc_mx_cgraph_node_set_def (void *);
+#define gt_ggc_m_27cgraph_node_set_element_def(X) do { \
+ if (X != NULL) gt_ggc_mx_cgraph_node_set_element_def (X);\
+ } while (0)
+extern void gt_ggc_mx_cgraph_node_set_element_def (void *);
+#define gt_ggc_m_22VEC_cgraph_node_ptr_gc(X) do { \
+ if (X != NULL) gt_ggc_mx_VEC_cgraph_node_ptr_gc (X);\
+ } while (0)
+extern void gt_ggc_mx_VEC_cgraph_node_ptr_gc (void *);
+#define gt_ggc_m_11cgraph_edge(X) do { \
+ if (X != NULL) gt_ggc_mx_cgraph_edge (X);\
+ } while (0)
+extern void gt_ggc_mx_cgraph_edge (void *);
+#define gt_ggc_m_24VEC_ipa_replace_map_p_gc(X) do { \
+ if (X != NULL) gt_ggc_mx_VEC_ipa_replace_map_p_gc (X);\
+ } while (0)
+extern void gt_ggc_mx_VEC_ipa_replace_map_p_gc (void *);
+#define gt_ggc_m_15ipa_replace_map(X) do { \
+ if (X != NULL) gt_ggc_mx_ipa_replace_map (X);\
+ } while (0)
+extern void gt_ggc_mx_ipa_replace_map (void *);
+#define gt_ggc_m_11cgraph_node(X) do { \
+ if (X != NULL) gt_ggc_mx_cgraph_node (X);\
+ } while (0)
+extern void gt_ggc_mx_cgraph_node (void *);
+#define gt_ggc_m_18VEC_basic_block_gc(X) do { \
+ if (X != NULL) gt_ggc_mx_VEC_basic_block_gc (X);\
+ } while (0)
+extern void gt_ggc_mx_VEC_basic_block_gc (void *);
+#define gt_ggc_m_14gimple_bb_info(X) do { \
+ if (X != NULL) gt_ggc_mx_gimple_bb_info (X);\
+ } while (0)
+extern void gt_ggc_mx_gimple_bb_info (void *);
+#define gt_ggc_m_11rtl_bb_info(X) do { \
+ if (X != NULL) gt_ggc_mx_rtl_bb_info (X);\
+ } while (0)
+extern void gt_ggc_mx_rtl_bb_info (void *);
+#define gt_ggc_m_11VEC_edge_gc(X) do { \
+ if (X != NULL) gt_ggc_mx_VEC_edge_gc (X);\
+ } while (0)
+extern void gt_ggc_mx_VEC_edge_gc (void *);
+#define gt_ggc_m_17cselib_val_struct(X) do { \
+ if (X != NULL) gt_ggc_mx_cselib_val_struct (X);\
+ } while (0)
+extern void gt_ggc_mx_cselib_val_struct (void *);
+#define gt_ggc_m_12elt_loc_list(X) do { \
+ if (X != NULL) gt_ggc_mx_elt_loc_list (X);\
+ } while (0)
+extern void gt_ggc_mx_elt_loc_list (void *);
+#define gt_ggc_m_13VEC_loop_p_gc(X) do { \
+ if (X != NULL) gt_ggc_mx_VEC_loop_p_gc (X);\
+ } while (0)
+extern void gt_ggc_mx_VEC_loop_p_gc (void *);
+#define gt_ggc_m_4loop(X) do { \
+ if (X != NULL) gt_ggc_mx_loop (X);\
+ } while (0)
+extern void gt_ggc_mx_loop (void *);
+#define gt_ggc_m_9loop_exit(X) do { \
+ if (X != NULL) gt_ggc_mx_loop_exit (X);\
+ } while (0)
+extern void gt_ggc_mx_loop_exit (void *);
+#define gt_ggc_m_13nb_iter_bound(X) do { \
+ if (X != NULL) gt_ggc_mx_nb_iter_bound (X);\
+ } while (0)
+extern void gt_ggc_mx_nb_iter_bound (void *);
+#define gt_ggc_m_24types_used_by_vars_entry(X) do { \
+ if (X != NULL) gt_ggc_mx_types_used_by_vars_entry (X);\
+ } while (0)
+extern void gt_ggc_mx_types_used_by_vars_entry (void *);
+#define gt_ggc_m_17language_function(X) do { \
+ if (X != NULL) gt_ggc_mx_language_function (X);\
+ } while (0)
+extern void gt_ggc_mx_language_function (void *);
+#define gt_ggc_m_5loops(X) do { \
+ if (X != NULL) gt_ggc_mx_loops (X);\
+ } while (0)
+extern void gt_ggc_mx_loops (void *);
+#define gt_ggc_m_18control_flow_graph(X) do { \
+ if (X != NULL) gt_ggc_mx_control_flow_graph (X);\
+ } while (0)
+extern void gt_ggc_mx_control_flow_graph (void *);
+#define gt_ggc_m_9eh_status(X) do { \
+ if (X != NULL) gt_ggc_mx_eh_status (X);\
+ } while (0)
+extern void gt_ggc_mx_eh_status (void *);
+#define gt_ggc_m_20initial_value_struct(X) do { \
+ if (X != NULL) gt_ggc_mx_initial_value_struct (X);\
+ } while (0)
+extern void gt_ggc_mx_initial_value_struct (void *);
+#define gt_ggc_m_17rtx_constant_pool(X) do { \
+ if (X != NULL) gt_ggc_mx_rtx_constant_pool (X);\
+ } while (0)
+extern void gt_ggc_mx_rtx_constant_pool (void *);
+#define gt_ggc_m_18VEC_temp_slot_p_gc(X) do { \
+ if (X != NULL) gt_ggc_mx_VEC_temp_slot_p_gc (X);\
+ } while (0)
+extern void gt_ggc_mx_VEC_temp_slot_p_gc (void *);
+#define gt_ggc_m_9temp_slot(X) do { \
+ if (X != NULL) gt_ggc_mx_temp_slot (X);\
+ } while (0)
+extern void gt_ggc_mx_temp_slot (void *);
+#define gt_ggc_m_9gimple_df(X) do { \
+ if (X != NULL) gt_ggc_mx_gimple_df (X);\
+ } while (0)
+extern void gt_ggc_mx_gimple_df (void *);
+#define gt_ggc_m_23VEC_call_site_record_gc(X) do { \
+ if (X != NULL) gt_ggc_mx_VEC_call_site_record_gc (X);\
+ } while (0)
+extern void gt_ggc_mx_VEC_call_site_record_gc (void *);
+#define gt_ggc_m_18call_site_record_d(X) do { \
+ if (X != NULL) gt_ggc_mx_call_site_record_d (X);\
+ } while (0)
+extern void gt_ggc_mx_call_site_record_d (void *);
+#define gt_ggc_m_14sequence_stack(X) do { \
+ if (X != NULL) gt_ggc_mx_sequence_stack (X);\
+ } while (0)
+extern void gt_ggc_mx_sequence_stack (void *);
+#define gt_ggc_m_8elt_list(X) do { \
+ if (X != NULL) gt_ggc_mx_elt_list (X);\
+ } while (0)
+extern void gt_ggc_mx_elt_list (void *);
+#define gt_ggc_m_17tree_priority_map(X) do { \
+ if (X != NULL) gt_ggc_mx_tree_priority_map (X);\
+ } while (0)
+extern void gt_ggc_mx_tree_priority_map (void *);
+#define gt_ggc_m_12tree_int_map(X) do { \
+ if (X != NULL) gt_ggc_mx_tree_int_map (X);\
+ } while (0)
+extern void gt_ggc_mx_tree_int_map (void *);
+#define gt_ggc_m_8tree_map(X) do { \
+ if (X != NULL) gt_ggc_mx_tree_map (X);\
+ } while (0)
+extern void gt_ggc_mx_tree_map (void *);
+#define gt_ggc_m_14lang_tree_node(X) do { \
+ if (X != NULL) gt_ggc_mx_lang_tree_node (X);\
+ } while (0)
+extern void gt_ggc_mx_lang_tree_node (void *);
+#define gt_ggc_m_24tree_statement_list_node(X) do { \
+ if (X != NULL) gt_ggc_mx_tree_statement_list_node (X);\
+ } while (0)
+extern void gt_ggc_mx_tree_statement_list_node (void *);
+#define gt_ggc_m_9lang_decl(X) do { \
+ if (X != NULL) gt_ggc_mx_lang_decl (X);\
+ } while (0)
+extern void gt_ggc_mx_lang_decl (void *);
+#define gt_ggc_m_9lang_type(X) do { \
+ if (X != NULL) gt_ggc_mx_lang_type (X);\
+ } while (0)
+extern void gt_ggc_mx_lang_type (void *);
+#define gt_ggc_m_10die_struct(X) do { \
+ if (X != NULL) gt_ggc_mx_die_struct (X);\
+ } while (0)
+extern void gt_ggc_mx_die_struct (void *);
+#define gt_ggc_m_15varray_head_tag(X) do { \
+ if (X != NULL) gt_ggc_mx_varray_head_tag (X);\
+ } while (0)
+extern void gt_ggc_mx_varray_head_tag (void *);
+#define gt_ggc_m_12ptr_info_def(X) do { \
+ if (X != NULL) gt_ggc_mx_ptr_info_def (X);\
+ } while (0)
+extern void gt_ggc_mx_ptr_info_def (void *);
+#define gt_ggc_m_22VEC_constructor_elt_gc(X) do { \
+ if (X != NULL) gt_ggc_mx_VEC_constructor_elt_gc (X);\
+ } while (0)
+extern void gt_ggc_mx_VEC_constructor_elt_gc (void *);
+#define gt_ggc_m_10tree_ann_d(X) do { \
+ if (X != NULL) gt_ggc_mx_tree_ann_d (X);\
+ } while (0)
+extern void gt_ggc_mx_tree_ann_d (void *);
+#define gt_ggc_m_17VEC_alias_pair_gc(X) do { \
+ if (X != NULL) gt_ggc_mx_VEC_alias_pair_gc (X);\
+ } while (0)
+extern void gt_ggc_mx_VEC_alias_pair_gc (void *);
+#define gt_ggc_m_11VEC_tree_gc(X) do { \
+ if (X != NULL) gt_ggc_mx_VEC_tree_gc (X);\
+ } while (0)
+extern void gt_ggc_mx_VEC_tree_gc (void *);
+#define gt_ggc_m_12VEC_uchar_gc(X) do { \
+ if (X != NULL) gt_ggc_mx_VEC_uchar_gc (X);\
+ } while (0)
+extern void gt_ggc_mx_VEC_uchar_gc (void *);
+#define gt_ggc_m_8function(X) do { \
+ if (X != NULL) gt_ggc_mx_function (X);\
+ } while (0)
+extern void gt_ggc_mx_function (void *);
+#define gt_ggc_m_23constant_descriptor_rtx(X) do { \
+ if (X != NULL) gt_ggc_mx_constant_descriptor_rtx (X);\
+ } while (0)
+extern void gt_ggc_mx_constant_descriptor_rtx (void *);
+#define gt_ggc_m_11fixed_value(X) do { \
+ if (X != NULL) gt_ggc_mx_fixed_value (X);\
+ } while (0)
+extern void gt_ggc_mx_fixed_value (void *);
+#define gt_ggc_m_10real_value(X) do { \
+ if (X != NULL) gt_ggc_mx_real_value (X);\
+ } while (0)
+extern void gt_ggc_mx_real_value (void *);
+#define gt_ggc_m_10VEC_rtx_gc(X) do { \
+ if (X != NULL) gt_ggc_mx_VEC_rtx_gc (X);\
+ } while (0)
+extern void gt_ggc_mx_VEC_rtx_gc (void *);
+#define gt_ggc_m_12object_block(X) do { \
+ if (X != NULL) gt_ggc_mx_object_block (X);\
+ } while (0)
+extern void gt_ggc_mx_object_block (void *);
+#define gt_ggc_m_9reg_attrs(X) do { \
+ if (X != NULL) gt_ggc_mx_reg_attrs (X);\
+ } while (0)
+extern void gt_ggc_mx_reg_attrs (void *);
+#define gt_ggc_m_9mem_attrs(X) do { \
+ if (X != NULL) gt_ggc_mx_mem_attrs (X);\
+ } while (0)
+extern void gt_ggc_mx_mem_attrs (void *);
+#define gt_ggc_m_14bitmap_obstack(X) do { \
+ if (X != NULL) gt_ggc_mx_bitmap_obstack (X);\
+ } while (0)
+extern void gt_ggc_mx_bitmap_obstack (void *);
+#define gt_ggc_m_18bitmap_element_def(X) do { \
+ if (X != NULL) gt_ggc_mx_bitmap_element_def (X);\
+ } while (0)
+extern void gt_ggc_mx_bitmap_element_def (void *);
+#define gt_ggc_m_16machine_function(X) do { \
+ if (X != NULL) gt_ggc_mx_machine_function (X);\
+ } while (0)
+extern void gt_ggc_mx_machine_function (void *);
+#define gt_ggc_m_17stack_local_entry(X) do { \
+ if (X != NULL) gt_ggc_mx_stack_local_entry (X);\
+ } while (0)
+extern void gt_ggc_mx_stack_local_entry (void *);
+#define gt_ggc_m_15basic_block_def(X) do { \
+ if (X != NULL) gt_ggc_mx_basic_block_def (X);\
+ } while (0)
+extern void gt_ggc_mx_basic_block_def (void *);
+#define gt_ggc_m_8edge_def(X) do { \
+ if (X != NULL) gt_ggc_mx_edge_def (X);\
+ } while (0)
+extern void gt_ggc_mx_edge_def (void *);
+#define gt_ggc_m_17gimple_seq_node_d(X) do { \
+ if (X != NULL) gt_ggc_mx_gimple_seq_node_d (X);\
+ } while (0)
+extern void gt_ggc_mx_gimple_seq_node_d (void *);
+#define gt_ggc_m_12gimple_seq_d(X) do { \
+ if (X != NULL) gt_ggc_mx_gimple_seq_d (X);\
+ } while (0)
+extern void gt_ggc_mx_gimple_seq_d (void *);
+#define gt_ggc_m_7section(X) do { \
+ if (X != NULL) gt_ggc_mx_section (X);\
+ } while (0)
+extern void gt_ggc_mx_section (void *);
+#define gt_ggc_m_18gimple_statement_d(X) do { \
+ if (X != NULL) gt_ggc_mx_gimple_statement_d (X);\
+ } while (0)
+extern void gt_ggc_mx_gimple_statement_d (void *);
+#define gt_ggc_m_9rtvec_def(X) do { \
+ if (X != NULL) gt_ggc_mx_rtvec_def (X);\
+ } while (0)
+extern void gt_ggc_mx_rtvec_def (void *);
+#define gt_ggc_m_7rtx_def(X) do { \
+ if (X != NULL) gt_ggc_mx_rtx_def (X);\
+ } while (0)
+extern void gt_ggc_mx_rtx_def (void *);
+#define gt_ggc_m_15bitmap_head_def(X) do { \
+ if (X != NULL) gt_ggc_mx_bitmap_head_def (X);\
+ } while (0)
+extern void gt_ggc_mx_bitmap_head_def (void *);
+#define gt_ggc_m_9tree_node(X) do { \
+ if (X != NULL) gt_ggc_mx_tree_node (X);\
+ } while (0)
+#define gt_ggc_mx_tree_node gt_ggc_mx_lang_tree_node
+#define gt_ggc_m_6answer(X) do { \
+ if (X != NULL) gt_ggc_mx_answer (X);\
+ } while (0)
+extern void gt_ggc_mx_answer (void *);
+#define gt_ggc_m_9cpp_macro(X) do { \
+ if (X != NULL) gt_ggc_mx_cpp_macro (X);\
+ } while (0)
+extern void gt_ggc_mx_cpp_macro (void *);
+#define gt_ggc_m_9cpp_token(X) do { \
+ if (X != NULL) gt_ggc_mx_cpp_token (X);\
+ } while (0)
+extern void gt_ggc_mx_cpp_token (void *);
+#define gt_ggc_m_9line_maps(X) do { \
+ if (X != NULL) gt_ggc_mx_line_maps (X);\
+ } while (0)
+extern void gt_ggc_mx_line_maps (void *);
+extern void gt_ggc_m_II17splay_tree_node_s (void *);
+extern void gt_ggc_m_SP9tree_node17splay_tree_node_s (void *);
+extern void gt_ggc_m_P9tree_nodeP9tree_node17splay_tree_node_s (void *);
+extern void gt_ggc_m_IP9tree_node17splay_tree_node_s (void *);
+extern void gt_ggc_m_P13tree_llvm_map4htab (void *);
+extern void gt_ggc_m_P15interface_tuple4htab (void *);
+extern void gt_ggc_m_P16volatilized_type4htab (void *);
+extern void gt_ggc_m_P17string_descriptor4htab (void *);
+extern void gt_ggc_m_P14type_assertion4htab (void *);
+extern void gt_ggc_m_P18treetreehash_entry4htab (void *);
+extern void gt_ggc_m_P17module_htab_entry4htab (void *);
+extern void gt_ggc_m_P16def_pragma_macro4htab (void *);
+extern void gt_ggc_m_P21pending_abstract_type4htab (void *);
+extern void gt_ggc_m_P10spec_entry4htab (void *);
+extern void gt_ggc_m_P16cxx_int_tree_map4htab (void *);
+extern void gt_ggc_m_P17named_label_entry4htab (void *);
+extern void gt_ggc_m_P12tree_int_map4htab (void *);
+extern void gt_ggc_m_P20lto_symtab_entry_def4htab (void *);
+extern void gt_ggc_m_IP9tree_node12splay_tree_s (void *);
+extern void gt_ggc_m_P9tree_nodeP9tree_node12splay_tree_s (void *);
+extern void gt_ggc_m_P12varpool_node4htab (void *);
+extern void gt_ggc_m_P13scev_info_str4htab (void *);
+extern void gt_ggc_m_P23constant_descriptor_rtx4htab (void *);
+extern void gt_ggc_m_P24constant_descriptor_tree4htab (void *);
+extern void gt_ggc_m_P12object_block4htab (void *);
+extern void gt_ggc_m_P7section4htab (void *);
+extern void gt_ggc_m_P17tree_priority_map4htab (void *);
+extern void gt_ggc_m_P8tree_map4htab (void *);
+extern void gt_ggc_m_P9type_hash4htab (void *);
+extern void gt_ggc_m_P13libfunc_entry4htab (void *);
+extern void gt_ggc_m_P23temp_slot_address_entry4htab (void *);
+extern void gt_ggc_m_P15throw_stmt_node4htab (void *);
+extern void gt_ggc_m_P9reg_attrs4htab (void *);
+extern void gt_ggc_m_P9mem_attrs4htab (void *);
+extern void gt_ggc_m_P7rtx_def4htab (void *);
+extern void gt_ggc_m_SP9tree_node12splay_tree_s (void *);
+extern void gt_ggc_m_P10vcall_insn4htab (void *);
+extern void gt_ggc_m_P16var_loc_list_def4htab (void *);
+extern void gt_ggc_m_P10die_struct4htab (void *);
+extern void gt_ggc_m_P15dwarf_file_data4htab (void *);
+extern void gt_ggc_m_P20indirect_string_node4htab (void *);
+extern void gt_ggc_m_P11cgraph_node4htab (void *);
+extern void gt_ggc_m_II12splay_tree_s (void *);
+extern void gt_ggc_m_P27cgraph_node_set_element_def4htab (void *);
+extern void gt_ggc_m_P11cgraph_edge4htab (void *);
+extern void gt_ggc_m_P9loop_exit4htab (void *);
+extern void gt_ggc_m_P24types_used_by_vars_entry4htab (void *);
+extern void gt_ggc_m_P9tree_node4htab (void *);
+
+/* functions code */
+
+void
+gt_ggc_mx_tree_llvm_map (void *x_p)
+{
+ struct tree_llvm_map * const x = (struct tree_llvm_map *)x_p;
+ if (ggc_test_and_set_mark (x))
+ {
+ gt_ggc_m_9tree_node ((*x).base.from);
+ }
+}
+
+void
+gt_ggc_m_P13tree_llvm_map4htab (void *x_p)
+{
+ struct htab * const x = (struct htab *)x_p;
+ if (ggc_test_and_set_mark (x))
+ {
+ if ((*x).entries != NULL) {
+ size_t i0;
+ for (i0 = 0; i0 != (size_t)(((*x)).size); i0++) {
+ gt_ggc_m_13tree_llvm_map ((*x).entries[i0]);
+ }
+ ggc_mark ((*x).entries);
+ }
+ }
+}
+
+/* GC roots. */
+
+EXPORTED_CONST struct ggc_cache_tab gt_ggc_rc__gt_llvm_cache_h[] = {
+ {
+ &llvm_cache,
+ 1,
+ sizeof (llvm_cache),
+ &gt_ggc_mx_tree_llvm_map,
+ NULL,
+ &tree_llvm_map_marked_p
+ },
+ LAST_GGC_CACHE_TAB
+};
+
diff -r -u -N dragonegg-2.9-old/include/dragonegg/Internals.h dragonegg-2.9-new/include/dragonegg/Internals.h
--- dragonegg-2.9-old/include/dragonegg/Internals.h 1970-01-01 01:00:00.000000000 +0100
+++ dragonegg-2.9-new/include/dragonegg/Internals.h 2011-04-09 00:38:28.299623547 +0200
@@ -0,0 +1,866 @@
+//=---- Internals.h - Interface between the backend components ----*- C++ -*-=//
+//
+// Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Chris Lattner,
+// Duncan Sands et al.
+//
+// This file is part of DragonEgg.
+//
+// DragonEgg is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free Software
+// Foundation; either version 2, or (at your option) any later version.
+//
+// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along with
+// DragonEgg; see the file COPYING. If not, write to the Free Software
+// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
+//
+//===----------------------------------------------------------------------===//
+// This file declares the internal interfaces shared among the dragonegg files.
+//===----------------------------------------------------------------------===//
+
+#ifndef DRAGONEGG_INTERNALS_H
+#define DRAGONEGG_INTERNALS_H
+
+// LLVM headers
+#include "llvm/Intrinsics.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/Support/IRBuilder.h"
+#include "llvm/Support/TargetFolder.h"
+
+struct basic_block_def;
+union gimple_statement_d;
+union tree_node;
+
+namespace llvm {
+ class Module;
+ class GlobalVariable;
+ class Function;
+ class GlobalValue;
+ class BasicBlock;
+ class Instruction;
+ class AllocaInst;
+ class BranchInst;
+ class Value;
+ class Constant;
+ class ConstantInt;
+ class Type;
+ class FunctionType;
+ class TargetMachine;
+ class TargetData;
+ class DebugInfo;
+ template<typename> class AssertingVH;
+ template<typename> class TrackingVH;
+}
+using namespace llvm;
+
+typedef IRBuilder<true, TargetFolder> LLVMBuilder;
+
+// Global state.
+
+/// TheModule - This is the current global module that we are compiling into.
+///
+extern llvm::Module *TheModule;
+
+/// TheDebugInfo - This object is responsible for gather all debug information.
+/// If it's value is NULL then no debug information should be gathered.
+extern llvm::DebugInfo *TheDebugInfo;
+
+/// TheTarget - The current target being compiled for.
+///
+extern llvm::TargetMachine *TheTarget;
+
+/// TheFolder - The constant folder to use.
+extern TargetFolder *TheFolder;
+
+/// getTargetData - Return the current TargetData object from TheTarget.
+const TargetData &getTargetData();
+
+/// flag_default_initialize_globals - Whether global variables with no explicit
+/// initial value should be zero initialized.
+extern bool flag_default_initialize_globals;
+
+/// flag_odr - Whether the language being compiled obeys the One Definition Rule
+/// (i.e. if the same function is defined in multiple compilation units, all the
+/// definitions are equivalent).
+extern bool flag_odr;
+
+/// flag_vararg_requires_arguments - Do not consider functions with no arguments
+/// to take a variable number of arguments (...). If set then a function like
+/// "T foo() {}" will be treated like "T foo(void) {}" and not "T foo(...) {}".
+extern bool flag_vararg_requires_arguments;
+
+/// flag_force_vararg_prototypes - Force prototypes to take a variable number of
+/// arguments (...). This is helpful if the language front-end sometimes emits
+/// calls where the call arguments do not match the callee function declaration.
+extern bool flag_force_vararg_prototypes;
+
+/// AttributeUsedGlobals - The list of globals that are marked attribute(used).
+extern SmallSetVector<Constant *,32> AttributeUsedGlobals;
+
+extern Constant* ConvertMetadataStringToGV(const char *str);
+
+/// AddAnnotateAttrsToGlobal - Adds decls that have a
+/// annotate attribute to a vector to be emitted later.
+extern void AddAnnotateAttrsToGlobal(GlobalValue *GV, tree_node *decl);
+
+// Mapping between GCC declarations and LLVM values. The GCC declaration must
+// satisfy HAS_RTL_P.
+
+/// DECL_LLVM - Returns the LLVM declaration of a global variable or function.
+extern Value *make_decl_llvm(tree_node *);
+#define DECL_LLVM(NODE) make_decl_llvm(NODE)
+
+/// SET_DECL_LLVM - Set the DECL_LLVM for NODE to LLVM.
+extern Value *set_decl_llvm(tree_node *, Value *);
+#define SET_DECL_LLVM(NODE, LLVM) set_decl_llvm(NODE, LLVM)
+
+/// DECL_LLVM_IF_SET - The DECL_LLVM for NODE, if it is set, or NULL, if it is
+/// not set.
+extern Value *get_decl_llvm(tree_node *);
+#define DECL_LLVM_IF_SET(NODE) (HAS_RTL_P(NODE) ? get_decl_llvm(NODE) : NULL)
+
+/// DECL_LLVM_SET_P - Returns nonzero if the DECL_LLVM for NODE has already
+/// been set.
+#define DECL_LLVM_SET_P(NODE) (DECL_LLVM_IF_SET(NODE) != NULL)
+
+/// DEFINITION_LLVM - Ensures that the body or initial value of the given GCC
+/// global will be output, and returns a declaration for it.
+Value *make_definition_llvm(tree_node *decl);
+#define DEFINITION_LLVM(NODE) make_definition_llvm(NODE)
+
+// Mapping between GCC declarations and non-negative integers. The GCC
+// declaration must not satisfy HAS_RTL_P.
+
+/// set_decl_index - Associate a non-negative number with the given GCC
+/// declaration.
+int set_decl_index(tree_node *, int);
+
+/// get_decl_index - Get the non-negative number associated with the given GCC
+/// declaration. Returns a negative value if no such association has been made.
+int get_decl_index(tree_node *);
+
+void changeLLVMConstant(Constant *Old, Constant *New);
+void register_ctor_dtor(Function *, int, bool);
+void readLLVMTypesStringTable();
+void writeLLVMTypesStringTable();
+void readLLVMValues();
+void writeLLVMValues();
+void clearTargetBuiltinCache();
+const char *extractRegisterName(tree_node *);
+void handleVisibility(tree_node *decl, GlobalValue *GV);
+Twine getLLVMAssemblerName(tree_node *);
+
+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(tree_node*, unsigned N);
+
+/// TypeConverter - Implement the converter from GCC types to LLVM types.
+///
+class TypeConverter {
+ /// ConvertingStruct - If we are converting a RECORD or UNION to an LLVM type
+ /// we set this flag to true.
+ bool ConvertingStruct;
+
+ /// PointersToReresolve - When ConvertingStruct is true, we handling of
+ /// POINTER_TYPE and REFERENCE_TYPE is changed to return
+ /// opaque*'s instead of recursively calling ConvertType. When this happens,
+ /// we add the POINTER_TYPE to this list.
+ ///
+ std::vector<tree_node*> PointersToReresolve;
+public:
+ TypeConverter() : ConvertingStruct(false) {}
+
+ /// 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).
+ const Type *ConvertType(tree_node *type);
+
+ /// GCCTypeOverlapsWithLLVMTypePadding - Return true if the specified GCC type
+ /// has any data that overlaps with structure padding in the specified LLVM
+ /// type.
+ static bool GCCTypeOverlapsWithLLVMTypePadding(tree_node *t, const Type *Ty);
+
+
+ /// ConvertFunctionType - Convert the specified FUNCTION_TYPE or METHOD_TYPE
+ /// tree to an LLVM type. This does the same thing that ConvertType does, but
+ /// it also returns the function's LLVM calling convention and attributes.
+ const FunctionType *ConvertFunctionType(tree_node *type,
+ tree_node *decl,
+ tree_node *static_chain,
+ CallingConv::ID &CallingConv,
+ AttrListPtr &PAL);
+
+ /// ConvertArgListToFnType - Given a DECL_ARGUMENTS list on an GCC tree,
+ /// return the LLVM type corresponding to the function. This is useful for
+ /// turning "T foo(...)" functions into "T foo(void)" functions.
+ const FunctionType *ConvertArgListToFnType(tree_node *type,
+ tree_node *arglist,
+ tree_node *static_chain,
+ CallingConv::ID &CallingConv,
+ AttrListPtr &PAL);
+
+private:
+ const Type *ConvertRECORD(tree_node *type);
+ bool DecodeStructFields(tree_node *Field, StructTypeConversionInfo &Info);
+ void DecodeStructBitField(tree_node *Field, StructTypeConversionInfo &Info);
+ void SelectUnionMember(tree_node *type, StructTypeConversionInfo &Info);
+};
+
+extern TypeConverter *TheTypeConverter;
+
+/// 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).
+inline const Type *ConvertType(tree_node *type) {
+ return TheTypeConverter->ConvertType(type);
+}
+
+/// getDefaultValue - Return the default value to use for a constant or global
+/// that has no value specified. For example in C like languages such variables
+/// are initialized to zero, while in Ada they hold an undefined value.
+inline Constant *getDefaultValue(const Type *Ty) {
+ return flag_default_initialize_globals ?
+ Constant::getNullValue(Ty) : UndefValue::get(Ty);
+}
+
+/// 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
+/// i16.
+extern const Type *GetUnitType(LLVMContext &C, unsigned NumUnits = 1);
+
+/// GetUnitPointerType - Returns an LLVM pointer type which points to memory one
+/// address unit wide. For example, on a machine which has 16 bit bytes returns
+/// an i16*.
+extern const Type *GetUnitPointerType(LLVMContext &C, unsigned AddrSpace = 0);
+
+/// GetFieldIndex - Return the index of the field in the given LLVM type that
+/// corresponds to the GCC field declaration 'decl'. This means that the LLVM
+/// and GCC fields start in the same byte (if 'decl' is a bitfield, this means
+/// that its first bit is within the byte the LLVM field starts at). Returns
+/// INT_MAX if there is no such LLVM field.
+int GetFieldIndex(tree_node *decl, const Type *Ty);
+
+/// getINTEGER_CSTVal - Return the specified INTEGER_CST value as a uint64_t.
+///
+uint64_t getINTEGER_CSTVal(tree_node *exp);
+
+/// isInt64 - Return true if t is an INTEGER_CST that fits in a 64 bit integer.
+/// If Unsigned is false, returns whether it fits in a int64_t. If Unsigned is
+/// true, returns whether the value is non-negative and fits in a uint64_t.
+/// Always returns false for overflowed constants or if t is NULL.
+bool isInt64(tree_node *t, bool Unsigned);
+
+/// getInt64 - Extract the value of an INTEGER_CST as a 64 bit integer. If
+/// Unsigned is false, the value must fit in a int64_t. If Unsigned is true,
+/// the value must be non-negative and fit in a uint64_t. Must not be used on
+/// overflowed constants. These conditions can be checked by calling isInt64.
+uint64_t getInt64(tree_node *t, bool Unsigned);
+
+/// isPassedByInvisibleReference - Return true if the specified type should be
+/// passed by 'invisible reference'. In other words, instead of passing the
+/// thing by value, pass the address of a temporary.
+bool isPassedByInvisibleReference(tree_node *type);
+
+/// isSequentialCompatible - Return true if the specified gcc array or pointer
+/// type and the corresponding LLVM SequentialType lay out their components
+/// identically in memory, so doing a GEP accesses the right memory location.
+/// We assume that objects without a known size do not.
+extern bool isSequentialCompatible(tree_node *type);
+
+/// OffsetIsLLVMCompatible - Return true if the given field is offset from the
+/// start of the record by a constant amount which is not humongously big.
+extern bool OffsetIsLLVMCompatible(tree_node *field_decl);
+
+/// ArrayLengthOf - Returns the length of the given gcc array type, or ~0ULL if
+/// the array has variable or unknown length.
+extern uint64_t ArrayLengthOf(tree_node *type);
+
+/// isBitfield - Returns whether to treat the specified field as a bitfield.
+bool isBitfield(tree_node *field_decl);
+
+/// getFieldOffsetInBits - Return the bit offset of a FIELD_DECL in a structure.
+extern uint64_t getFieldOffsetInBits(tree_node *field);
+
+/// ValidateRegisterVariable - Check that a static "asm" variable is
+/// well-formed. If not, emit error messages and return true. If so, return
+/// false.
+bool ValidateRegisterVariable(tree_node *decl);
+
+/// MemRef - This struct holds the information needed for a memory access:
+/// a pointer to the memory, its alignment and whether the access is volatile.
+class MemRef {
+public:
+ Value *Ptr;
+ bool Volatile;
+private:
+ unsigned char LogAlign;
+public:
+ explicit MemRef() : Ptr(0), Volatile(false), LogAlign(0) {}
+ explicit MemRef(Value *P, uint32_t A, bool V) : Ptr(P), Volatile(V) {
+ // Forbid alignment 0 along with non-power-of-2 alignment values.
+ assert(isPowerOf2_32(A) && "Alignment not a power of 2!");
+ LogAlign = Log2_32(A);
+ }
+
+ uint32_t getAlignment() const {
+ return 1U << LogAlign;
+ }
+
+ void setAlignment(uint32_t A) {
+ LogAlign = Log2_32(A);
+ }
+};
+
+/// LValue - This struct represents an lvalue in the program. In particular,
+/// the Ptr member indicates the memory that the lvalue lives in. Alignment
+/// is the alignment of the memory (in bytes).If this is a bitfield reference,
+/// BitStart indicates the first bit in the memory that is part of the field
+/// and BitSize indicates the extent.
+///
+/// "LValue" is intended to be a light-weight object passed around by-value.
+class LValue : public MemRef {
+public:
+ unsigned char BitStart;
+ unsigned char BitSize;
+public:
+ explicit LValue() : BitStart(255), BitSize(255) {}
+ explicit LValue(MemRef &M) : MemRef(M), BitStart(255), BitSize(255) {}
+ LValue(Value *P, uint32_t A, bool V = false) :
+ MemRef(P, A, V), BitStart(255), BitSize(255) {}
+ LValue(Value *P, uint32_t A, unsigned BSt, unsigned BSi, bool V = false) :
+ MemRef(P, A, V), BitStart(BSt), BitSize(BSi) {
+ assert(BitStart == BSt && BitSize == BSi &&
+ "Bit values larger than 256?");
+ }
+
+ bool isBitfield() const { return BitStart != 255; }
+};
+
+/// PhiRecord - This struct holds the LLVM PHI node associated with a GCC phi.
+struct PhiRecord {
+ gimple_statement_d *gcc_phi;
+ PHINode *PHI;
+};
+
+/// TreeToLLVM - An instance of this class is created and used to convert the
+/// body of each function to LLVM.
+///
+class TreeToLLVM {
+ // State that is initialized when the function starts.
+ const TargetData &TD;
+ tree_node *FnDecl;
+ Function *Fn;
+ BasicBlock *ReturnBB;
+ unsigned ReturnOffset;
+
+ // State that changes as the function is emitted.
+
+ /// Builder - Instruction creator, the location to insert into is always the
+ /// same as &Fn->back().
+ LLVMBuilder Builder;
+
+ // AllocaInsertionPoint - Place to insert alloca instructions. Lazily created
+ // and managed by CreateTemporary.
+ Instruction *AllocaInsertionPoint;
+
+ // SSAInsertionPoint - Place to insert reads corresponding to SSA default
+ // definitions.
+ Instruction *SSAInsertionPoint;
+
+ /// BasicBlocks - Map from GCC to LLVM basic blocks.
+ DenseMap<basic_block_def *, BasicBlock*> BasicBlocks;
+
+ /// LocalDecls - Map from local declarations to their associated LLVM values.
+ DenseMap<tree_node *, AssertingVH<Value> > LocalDecls;
+
+ /// PendingPhis - Phi nodes which have not yet been populated with operands.
+ SmallVector<PhiRecord, 16> PendingPhis;
+
+ // SSANames - Map from GCC ssa names to the defining LLVM value.
+ DenseMap<tree_node *, TrackingVH<Value> > SSANames;
+
+public:
+
+ //===---------------------- Local Declarations --------------------------===//
+
+ /// DECL_LOCAL - Like DECL_LLVM, returns the LLVM declaration of a variable or
+ /// function. However DECL_LOCAL can be used with declarations local to the
+ /// current function as well as with global declarations.
+ Value *make_decl_local(tree_node *);
+ #define DECL_LOCAL(NODE) make_decl_local(NODE)
+
+ /// DEFINITION_LOCAL - Like DEFINITION_LLVM, ensures that the initial value or
+ /// body of a variable or function will be output. However DEFINITION_LOCAL
+ /// can be used with declarations local to the current function as well as
+ /// with global declarations.
+ Value *make_definition_local(tree_node *);
+ #define DEFINITION_LOCAL(NODE) make_definition_local(NODE)
+
+ /// SET_DECL_LOCAL - Set the DECL_LOCAL for NODE to LLVM.
+ Value *set_decl_local(tree_node *, Value *);
+ #define SET_DECL_LOCAL(NODE, LLVM) set_decl_local(NODE, LLVM)
+
+ /// DECL_LOCAL_IF_SET - The DECL_LOCAL for NODE, if it is set, or NULL, if it
+ /// is not set.
+ Value *get_decl_local(tree_node *);
+ #define DECL_LOCAL_IF_SET(NODE) (HAS_RTL_P(NODE) ? get_decl_local(NODE) : NULL)
+
+ /// DECL_LOCAL_SET_P - Returns nonzero if the DECL_LOCAL for NODE has already
+ /// been set.
+ #define DECL_LOCAL_SET_P(NODE) (DECL_LOCAL_IF_SET(NODE) != NULL)
+
+
+private:
+
+ //===---------------------- Exception Handling --------------------------===//
+
+ /// NormalInvokes - Mapping from landing pad number to the set of invoke
+ /// instructions that unwind to that landing pad.
+ SmallVector<SmallVector<InvokeInst *, 8>, 16> NormalInvokes;
+
+ /// ExceptionPtrs - Mapping from EH region index to the local holding the
+ /// exception pointer for that region.
+ SmallVector<AllocaInst *, 16> ExceptionPtrs;
+
+ /// ExceptionFilters - Mapping from EH region index to the local holding the
+ /// filter value for that region.
+ SmallVector<AllocaInst *, 16> ExceptionFilters;
+
+ /// FailureBlocks - Mapping from the index of a must-not-throw EH region to
+ /// the block containing the failure code for the region (the code that is
+ /// run if an exception is thrown in this region).
+ SmallVector<BasicBlock *, 16> FailureBlocks;
+
+ /// RewindBB - Block containing code that continues unwinding an exception.
+ BasicBlock *RewindBB;
+
+ /// RewindTmp - Local holding the exception to continue unwinding.
+ AllocaInst *RewindTmp;
+
+public:
+ TreeToLLVM(tree_node *fndecl);
+ ~TreeToLLVM();
+
+ /// getFUNCTION_DECL - Return the FUNCTION_DECL node for the current function
+ /// being compiled.
+ tree_node *getFUNCTION_DECL() const { return FnDecl; }
+
+ /// EmitFunction - Convert 'fndecl' to LLVM code.
+ Function *EmitFunction();
+
+ /// EmitBasicBlock - Convert the given basic block.
+ void EmitBasicBlock(basic_block_def *bb);
+
+ /// EmitLV - Convert the specified l-value tree node to LLVM code, returning
+ /// the address of the result.
+ LValue EmitLV(tree_node *exp);
+
+ void TODO(tree_node *exp = 0);
+
+ /// CastToAnyType - Cast the specified value to the specified type regardless
+ /// of the types involved. This is an inferred cast.
+ Value *CastToAnyType (Value *V, bool VSigned, const Type *Ty, bool TySigned);
+
+ /// CastToUIntType - Cast the specified value to the specified type assuming
+ /// that V's type and Ty are integral types. This arbitrates between BitCast,
+ /// Trunc and ZExt.
+ Value *CastToUIntType(Value *V, const Type *Ty);
+
+ /// CastToSIntType - Cast the specified value to the specified type assuming
+ /// that V's type and Ty are integral types. This arbitrates between BitCast,
+ /// Trunc and SExt.
+ Value *CastToSIntType(Value *V, const Type *Ty);
+
+ /// CastToFPType - Cast the specified value to the specified type assuming
+ /// that V's type and Ty are floating point types. This arbitrates between
+ /// BitCast, FPTrunc and FPExt.
+ Value *CastToFPType(Value *V, const Type *Ty);
+
+ /// CreateAnyAdd - Add two LLVM scalar values with the given GCC type. Does
+ /// not support complex numbers. The type is used to set overflow flags.
+ Value *CreateAnyAdd(Value *LHS, Value *RHS, tree_node *type);
+
+ /// CreateAnyMul - Multiply two LLVM scalar values with the given GCC type.
+ /// Does not support complex numbers. The type is used to set overflow flags.
+ Value *CreateAnyMul(Value *LHS, Value *RHS, tree_node *type);
+
+ /// CreateAnyNeg - Negate an LLVM scalar value with the given GCC type. Does
+ /// not support complex numbers. The type is used to set overflow flags.
+ Value *CreateAnyNeg(Value *V, tree_node *type);
+
+ /// CreateAnySub - Subtract two LLVM scalar values with the given GCC type.
+ /// Does not support complex numbers.
+ Value *CreateAnySub(Value *LHS, Value *RHS, tree_node *type);
+
+ /// CreateTemporary - Create a new alloca instruction of the specified type,
+ /// inserting it into the entry block and returning it. The resulting
+ /// instruction's type is a pointer to the specified type.
+ AllocaInst *CreateTemporary(const Type *Ty, unsigned align=0);
+
+ /// CreateTempLoc - Like CreateTemporary, but returns a MemRef.
+ MemRef CreateTempLoc(const Type *Ty);
+
+ /// EmitAggregateCopy - Copy the elements from SrcLoc to DestLoc, using the
+ /// GCC type specified by GCCType to know which elements to copy.
+ void EmitAggregateCopy(MemRef DestLoc, MemRef SrcLoc, tree_node *GCCType);
+
+ /// EmitAggregate - Store the specified tree node into the location given by
+ /// DestLoc.
+ void EmitAggregate(tree_node *exp, const MemRef &DestLoc);
+
+private: // Helper functions.
+
+ /// StartFunctionBody - Start the emission of 'fndecl', outputing all
+ /// declarations for parameters and setting things up.
+ void StartFunctionBody();
+
+ /// FinishFunctionBody - Once the body of the function has been emitted, this
+ /// cleans up and returns the result function.
+ Function *FinishFunctionBody();
+
+ /// PopulatePhiNodes - Populate generated phi nodes with their operands.
+ void PopulatePhiNodes();
+
+ /// getBasicBlock - Find or create the LLVM basic block corresponding to BB.
+ BasicBlock *getBasicBlock(basic_block_def *bb);
+
+ /// getLabelDeclBlock - Lazily get and create a basic block for the specified
+ /// label.
+ BasicBlock *getLabelDeclBlock(tree_node *LabelDecl);
+
+ /// DefineSSAName - Use the given value as the definition of the given SSA
+ /// name. Returns the provided value as a convenience.
+ Value *DefineSSAName(tree_node *reg, Value *Val);
+
+ /// BeginBlock - Add the specified basic block to the end of the function. If
+ /// the previous block falls through into it, add an explicit branch.
+ void BeginBlock(BasicBlock *BB);
+
+ /// EmitAggregateZero - Zero the elements of DestLoc.
+ void EmitAggregateZero(MemRef DestLoc, tree_node *GCCType);
+
+ /// EmitMemCpy/EmitMemMove/EmitMemSet - Emit an llvm.memcpy/llvm.memmove or
+ /// llvm.memset call with the specified operands. Returns DestPtr bitcast
+ /// to i8*.
+ Value *EmitMemCpy(Value *DestPtr, Value *SrcPtr, Value *Size, unsigned Align);
+ Value *EmitMemMove(Value *DestPtr, Value *SrcPtr, Value *Size, unsigned Align);
+ Value *EmitMemSet(Value *DestPtr, Value *SrcVal, Value *Size, unsigned Align);
+
+ /// EmitLandingPads - Emit EH landing pads.
+ void EmitLandingPads();
+
+ /// EmitFailureBlocks - Emit the blocks containing failure code executed when
+ /// an exception is thrown in a must-not-throw region.
+ void EmitFailureBlocks();
+
+ /// EmitRewindBlock - Emit the block containing code to continue unwinding an
+ /// exception.
+ void EmitRewindBlock();
+
+ /// EmitDebugInfo - Return true if debug info is to be emitted for current
+ /// function.
+ bool EmitDebugInfo();
+
+private: // Helpers for exception handling.
+
+ /// getLandingPad - Return the landing pad for the given exception handling
+ /// region, creating it if necessary.
+ BasicBlock *getLandingPad(unsigned RegionNo);
+
+ /// getExceptionPtr - Return the local holding the exception pointer for the
+ /// given exception handling region, creating it if necessary.
+ AllocaInst *getExceptionPtr(unsigned RegionNo);
+
+ /// getExceptionFilter - Return the local holding the filter value for the
+ /// given exception handling region, creating it if necessary.
+ AllocaInst *getExceptionFilter(unsigned RegionNo);
+
+ /// getFailureBlock - Return the basic block containing the failure code for
+ /// the given exception handling region, creating it if necessary.
+ BasicBlock *getFailureBlock(unsigned RegionNo);
+
+private:
+ void EmitAutomaticVariableDecl(tree_node *decl);
+
+ /// EmitAnnotateIntrinsic - Emits call to annotate attr intrinsic
+ void EmitAnnotateIntrinsic(Value *V, tree_node *decl);
+
+ /// EmitTypeGcroot - Emits call to make type a gcroot
+ void EmitTypeGcroot(Value *V);
+
+private:
+
+ //===------------------ Render* - Convert GIMPLE to LLVM ----------------===//
+
+ void RenderGIMPLE_ASM(gimple_statement_d *stmt);
+ void RenderGIMPLE_ASSIGN(gimple_statement_d *stmt);
+ void RenderGIMPLE_CALL(gimple_statement_d *stmt);
+ void RenderGIMPLE_COND(gimple_statement_d *stmt);
+ void RenderGIMPLE_EH_DISPATCH(gimple_statement_d *stmt);
+ void RenderGIMPLE_GOTO(gimple_statement_d *stmt);
+ void RenderGIMPLE_RESX(gimple_statement_d *stmt);
+ void RenderGIMPLE_RETURN(gimple_statement_d *stmt);
+ void RenderGIMPLE_SWITCH(gimple_statement_d *stmt);
+
+ // Render helpers.
+
+ /// EmitAssignRHS - Convert the RHS of a scalar GIMPLE_ASSIGN to LLVM.
+ Value *EmitAssignRHS(gimple_statement_d *stmt);
+
+ /// EmitAssignSingleRHS - Helper for EmitAssignRHS. Handles those RHS that
+ /// are not register expressions.
+ Value *EmitAssignSingleRHS(tree_node *rhs);
+
+ /// OutputCallRHS - Convert the RHS of a GIMPLE_CALL.
+ Value *OutputCallRHS(gimple_statement_d *stmt, const MemRef *DestLoc);
+
+ /// WriteScalarToLHS - Store RHS, a non-aggregate value, into the given LHS.
+ void WriteScalarToLHS(tree_node *lhs, Value *Scalar);
+
+private:
+
+ //===---------- EmitReg* - Convert register expression to LLVM ----------===//
+
+ /// 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.
+ const Type *GetRegType(tree_node *type);
+
+ /// UselesslyTypeConvert - The useless_type_conversion_p predicate implicitly
+ /// defines the GCC middle-end type system. For scalar GCC types inner_type
+ /// and outer_type, if 'useless_type_conversion_p(outer_type, inner_type)' is
+ /// true then the corresponding LLVM inner and outer types (see GetRegType)
+ /// are equal except possibly if they are both pointer types (casts to 'void*'
+ /// are considered useless for example) or types derived from pointer types
+ /// (vector types with pointer element type are the only possibility here).
+ /// This method converts LLVM values of the inner type to the outer type.
+ Value *UselesslyTypeConvert(Value *V, const Type *Ty) {
+ return Builder.CreateBitCast(V, Ty);
+ }
+
+ /// EmitRegister - Convert the specified gimple register or local constant of
+ /// register type to an LLVM value. Only creates code in the entry block.
+ Value *EmitRegister(tree_node *reg);
+
+ /// EmitReg_SSA_NAME - Return the defining value of the given SSA_NAME.
+ /// Only creates code in the entry block.
+ Value *EmitReg_SSA_NAME(tree_node *reg);
+
+ // Unary expressions.
+ Value *EmitReg_ABS_EXPR(tree_node *op);
+ Value *EmitReg_BIT_NOT_EXPR(tree_node *op);
+ Value *EmitReg_CONJ_EXPR(tree_node *op);
+ Value *EmitReg_CONVERT_EXPR(tree_node *type, tree_node *op);
+ Value *EmitReg_NEGATE_EXPR(tree_node *op);
+ Value *EmitReg_PAREN_EXPR(tree_node *exp);
+ Value *EmitReg_TRUTH_NOT_EXPR(tree_node *type, tree_node *op);
+
+ // Comparisons.
+
+ /// EmitCompare - Compare LHS with RHS using the appropriate comparison code.
+ /// The result is an i1 boolean.
+ Value *EmitCompare(tree_node *lhs, tree_node *rhs, unsigned code);
+
+ // Binary expressions.
+ Value *EmitReg_MinMaxExpr(tree_node *type, tree_node *op0, tree_node *op1,
+ unsigned UIPred, unsigned SIPred, unsigned Opc,
+ bool isMax);
+ Value *EmitReg_RotateOp(tree_node *type, tree_node *op0, tree_node *op1,
+ unsigned Opc1, unsigned Opc2);
+ Value *EmitReg_ShiftOp(tree_node *op0, tree_node *op1, unsigned Opc);
+ Value *EmitReg_TruthOp(tree_node *type, tree_node *op0, tree_node *op1,
+ unsigned Opc);
+ Value *EmitReg_BIT_AND_EXPR(tree_node *op0, tree_node *op1);
+ Value *EmitReg_BIT_IOR_EXPR(tree_node *op0, tree_node *op1);
+ Value *EmitReg_BIT_XOR_EXPR(tree_node *op0, tree_node *op1);
+ Value *EmitReg_CEIL_DIV_EXPR(tree_node *type, tree_node *op0, tree_node *op1);
+ Value *EmitReg_COMPLEX_EXPR(tree_node *op0, tree_node *op1);
+ Value *EmitReg_FLOOR_DIV_EXPR(tree_node *type, tree_node *op0,
+ tree_node *op1);
+ Value *EmitReg_FLOOR_MOD_EXPR(tree_node *type, tree_node *op0,
+ tree_node *op1);
+ Value *EmitReg_MINUS_EXPR(tree_node *op0, tree_node *op1);
+ Value *EmitReg_MULT_EXPR(tree_node *op0, tree_node *op1);
+ Value *EmitReg_PLUS_EXPR(tree_node *op0, tree_node *op1);
+ Value *EmitReg_POINTER_PLUS_EXPR(tree_node *type, tree_node *op0,
+ tree_node *op1);
+ Value *EmitReg_RDIV_EXPR(tree_node *op0, tree_node *op1);
+ Value *EmitReg_ROUND_DIV_EXPR(tree_node *type, tree_node *op0,
+ tree_node *op1);
+ Value *EmitReg_TRUNC_DIV_EXPR(tree_node *op0, tree_node *op1, bool isExact);
+ Value *EmitReg_TRUNC_MOD_EXPR(tree_node *op0, tree_node *op1);
+
+ Value *EmitLoadOfLValue(tree_node *exp);
+ Value *EmitOBJ_TYPE_REF(tree_node *exp);
+ Value *EmitADDR_EXPR(tree_node *exp);
+ Value *EmitCallOf(Value *Callee, gimple_statement_d *stmt,
+ const MemRef *DestLoc, const AttrListPtr &PAL);
+ CallInst *EmitSimpleCall(StringRef CalleeName, tree_node *ret_type,
+ /* arguments */ ...) END_WITH_NULL;
+ Value *EmitFieldAnnotation(Value *FieldPtr, tree_node *FieldDecl);
+
+ // Inline Assembly and Register Variables.
+ Value *EmitReadOfRegisterVariable(tree_node *vardecl);
+ void EmitModifyOfRegisterVariable(tree_node *vardecl, Value *RHS);
+
+ // Helpers for Builtin Function Expansion.
+ void EmitMemoryBarrier(bool ll, bool ls, bool sl, bool ss, bool device);
+ Value *BuildVector(const std::vector<Value*> &Elts);
+ Value *BuildVector(Value *Elt, ...);
+ Value *BuildVectorShuffle(Value *InVec1, Value *InVec2, ...);
+ Value *BuildBinaryAtomicBuiltin(gimple_statement_d *stmt, Intrinsic::ID id);
+ Value *BuildCmpAndSwapAtomicBuiltin(gimple_statement_d *stmt, tree_node *type,
+ bool isBool);
+
+ // Builtin Function Expansion.
+ bool EmitBuiltinCall(gimple_statement_d *stmt, tree_node *fndecl,
+ const MemRef *DestLoc, Value *&Result);
+ bool EmitFrontendExpandedBuiltinCall(gimple_statement_d *stmt,
+ tree_node *fndecl, const MemRef *DestLoc,
+ Value *&Result);
+ bool EmitBuiltinUnaryOp(Value *InVal, Value *&Result, Intrinsic::ID Id);
+ Value *EmitBuiltinSQRT(gimple_statement_d *stmt);
+ Value *EmitBuiltinPOWI(gimple_statement_d *stmt);
+ Value *EmitBuiltinPOW(gimple_statement_d *stmt);
+ Value *EmitBuiltinLCEIL(gimple_statement_d *stmt);
+ Value *EmitBuiltinLFLOOR(gimple_statement_d *stmt);
+
+ bool EmitBuiltinConstantP(gimple_statement_d *stmt, Value *&Result);
+ bool EmitBuiltinAlloca(gimple_statement_d *stmt, Value *&Result);
+ bool EmitBuiltinExpect(gimple_statement_d *stmt, Value *&Result);
+ bool EmitBuiltinExtendPointer(gimple_statement_d *stmt, Value *&Result);
+ bool EmitBuiltinVAStart(gimple_statement_d *stmt);
+ bool EmitBuiltinVAEnd(gimple_statement_d *stmt);
+ bool EmitBuiltinVACopy(gimple_statement_d *stmt);
+ bool EmitBuiltinMemCopy(gimple_statement_d *stmt, Value *&Result,
+ bool isMemMove, bool SizeCheck);
+ bool EmitBuiltinMemSet(gimple_statement_d *stmt, Value *&Result,
+ bool SizeCheck);
+ bool EmitBuiltinBZero(gimple_statement_d *stmt, Value *&Result);
+ bool EmitBuiltinPrefetch(gimple_statement_d *stmt);
+ bool EmitBuiltinReturnAddr(gimple_statement_d *stmt, Value *&Result,
+ bool isFrame);
+ bool EmitBuiltinExtractReturnAddr(gimple_statement_d *stmt, Value *&Result);
+ bool EmitBuiltinFrobReturnAddr(gimple_statement_d *stmt, Value *&Result);
+ bool EmitBuiltinStackSave(gimple_statement_d *stmt, Value *&Result);
+ bool EmitBuiltinStackRestore(gimple_statement_d *stmt);
+ bool EmitBuiltinEHPointer(gimple_statement_d *stmt, Value *&Result);
+ bool EmitBuiltinDwarfCFA(gimple_statement_d *stmt, Value *&Result);
+ bool EmitBuiltinDwarfSPColumn(gimple_statement_d *stmt, Value *&Result);
+ bool EmitBuiltinEHReturnDataRegno(gimple_statement_d *stmt, Value *&Result);
+ bool EmitBuiltinEHReturn(gimple_statement_d *stmt, Value *&Result);
+ bool EmitBuiltinInitDwarfRegSizes(gimple_statement_d *stmt, Value *&Result);
+ bool EmitBuiltinUnwindInit(gimple_statement_d *stmt, Value *&Result);
+ bool EmitBuiltinAdjustTrampoline(gimple_statement_d *stmt, Value *&Result);
+ bool EmitBuiltinInitTrampoline(gimple_statement_d *stmt, Value *&Result);
+
+ // Complex Math Expressions.
+ Value *CreateComplex(Value *Real, Value *Imag, tree_node *elt_type);
+ void SplitComplex(Value *Complex, Value *&Real, Value *&Imag,
+ tree_node *elt_type);
+
+ // L-Value Expressions.
+ LValue EmitLV_ARRAY_REF(tree_node *exp);
+ LValue EmitLV_BIT_FIELD_REF(tree_node *exp);
+ LValue EmitLV_COMPONENT_REF(tree_node *exp);
+ LValue EmitLV_DECL(tree_node *exp);
+ LValue EmitLV_INDIRECT_REF(tree_node *exp);
+ LValue EmitLV_VIEW_CONVERT_EXPR(tree_node *exp);
+ LValue EmitLV_WITH_SIZE_EXPR(tree_node *exp);
+ LValue EmitLV_XXXXPART_EXPR(tree_node *exp, unsigned Idx);
+ LValue EmitLV_SSA_NAME(tree_node *exp);
+ LValue EmitLV_TARGET_MEM_REF(tree_node *exp);
+
+ // Constant Expressions.
+ Value *EmitINTEGER_CST(tree_node *exp);
+ Value *EmitREAL_CST(tree_node *exp);
+ Value *EmitCONSTRUCTOR(tree_node *exp, const MemRef *DestLoc);
+
+
+ // Emit helpers.
+
+ /// EmitMinInvariant - The given value is constant in this function. Return
+ /// the corresponding LLVM value. Only creates code in the entry block.
+ Value *EmitMinInvariant(tree_node *reg);
+
+ /// EmitInvariantAddress - The given address is constant in this function.
+ /// Return the corresponding LLVM value. Only creates code in the entry block.
+ Value *EmitInvariantAddress(tree_node *addr);
+
+ /// EmitRegisterConstant - Convert the given global constant of register type
+ /// to an LLVM constant. Creates no code, only constants.
+ Constant *EmitRegisterConstant(tree_node *reg);
+
+ /// EmitComplexRegisterConstant - Turn the given COMPLEX_CST into an LLVM
+ /// constant of the corresponding register type.
+ Constant *EmitComplexRegisterConstant(tree_node *reg);
+
+ /// EmitIntegerRegisterConstant - Turn the given INTEGER_CST into an LLVM
+ /// constant of the corresponding register type.
+ Constant *EmitIntegerRegisterConstant(tree_node *reg);
+
+ /// EmitRealRegisterConstant - Turn the given REAL_CST into an LLVM constant
+ /// of the corresponding register type.
+ Constant *EmitRealRegisterConstant(tree_node *reg);
+
+ /// EmitConstantVectorConstructor - Turn the given constant CONSTRUCTOR into
+ /// an LLVM constant of the corresponding vector register type.
+ Constant *EmitConstantVectorConstructor(tree_node *reg);
+
+ /// EmitVectorRegisterConstant - Turn the given VECTOR_CST into an LLVM
+ /// constant of the corresponding register type.
+ Constant *EmitVectorRegisterConstant(tree_node *reg);
+
+ /// Mem2Reg - Convert a value of in-memory type (that given by ConvertType)
+ /// to in-register type (that given by GetRegType). TODO: Eliminate these
+ /// methods: "memory" values should never be held in registers. Currently
+ /// this is mainly used for marshalling function parameters and return values,
+ /// but that should be completely independent of the reg vs mem value logic.
+ Value *Mem2Reg(Value *V, tree_node *type, LLVMBuilder &Builder);
+ Constant *Mem2Reg(Constant *C, tree_node *type, TargetFolder &Folder);
+
+ /// Reg2Mem - Convert a value of in-register type (that given by GetRegType)
+ /// to in-memory type (that given by ConvertType). TODO: Eliminate this
+ /// method: "memory" values should never be held in registers. Currently
+ /// this is mainly used for marshalling function parameters and return values,
+ /// but that should be completely independent of the reg vs mem value logic.
+ Value *Reg2Mem(Value *V, tree_node *type, LLVMBuilder &Builder);
+
+ /// EmitMemory - Convert the specified gimple register or local constant of
+ /// register type to an LLVM value with in-memory type (given by ConvertType).
+ /// TODO: Eliminate this method, see Mem2Reg and Reg2Mem above.
+ Value *EmitMemory(tree_node *reg);
+
+ /// LoadRegisterFromMemory - Loads a value of the given scalar GCC type from
+ /// the memory location pointed to by Loc. Takes care of adjusting for any
+ /// differences between in-memory and in-register types (the returned value
+ /// is of in-register type, as returned by GetRegType).
+ Value *LoadRegisterFromMemory(MemRef Loc, tree_node *type,
+ LLVMBuilder &Builder);
+
+ /// StoreRegisterToMemory - Stores the given value to the memory pointed to by
+ /// Loc. Takes care of adjusting for any differences between the value's type
+ /// (which is the in-register type given by GetRegType) and the in-memory type.
+ void StoreRegisterToMemory(Value *V, MemRef Loc, tree_node *type,
+ LLVMBuilder &Builder);
+
+private:
+ // Optional target defined builtin intrinsic expanding function.
+ bool TargetIntrinsicLower(gimple_statement_d *stmt,
+ tree_node *fndecl,
+ const MemRef *DestLoc,
+ Value *&Result,
+ const Type *ResultType,
+ std::vector<Value*> &Ops);
+
+public:
+ // Helper for taking the address of a label.
+ Constant *AddressOfLABEL_DECL(tree_node *exp);
+};
+
+#endif /* DRAGONEGG_INTERNALS_H */
diff -r -u -N dragonegg-2.9-old/include/dragonegg/Trees.h dragonegg-2.9-new/include/dragonegg/Trees.h
--- dragonegg-2.9-old/include/dragonegg/Trees.h 1970-01-01 01:00:00.000000000 +0100
+++ dragonegg-2.9-new/include/dragonegg/Trees.h 2011-04-09 00:38:06.630097839 +0200
@@ -0,0 +1,44 @@
+//=---- Trees.h - Utility functions for working with GCC trees ----*- C++ -*-=//
+//
+// Copyright (C) 2010, 2011 Duncan Sands.
+//
+// This file is part of DragonEgg.
+//
+// DragonEgg is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free Software
+// Foundation; either version 2, or (at your option) any later version.
+//
+// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along with
+// DragonEgg; see the file COPYING. If not, write to the Free Software
+// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
+//
+//===----------------------------------------------------------------------===//
+// This file declares utility functions for working with GCC trees.
+//===----------------------------------------------------------------------===//
+
+#ifndef DRAGONEGG_TREES_H
+#define DRAGONEGG_TREES_H
+
+// System headers
+#include <string>
+
+union tree_node;
+
+/// getDescriptiveName - Return a helpful name for the given tree, or an empty
+/// string if no sensible name was found. These names are used to make the IR
+/// more readable, and have no official status.
+std::string getDescriptiveName(union tree_node *t);
+
+/// hasNUW - Return whether overflowing unsigned operations on this type result
+/// in undefined behaviour.
+bool hasNUW(tree_node *type);
+
+/// hasNSW - Return whether overflowing signed operations on this type result
+/// in undefined behaviour.
+bool hasNSW(tree_node *type);
+
+#endif /* DRAGONEGG_TREES_H */
diff -r -u -N dragonegg-2.9-old/Internals.h dragonegg-2.9-new/Internals.h
--- dragonegg-2.9-old/Internals.h 2011-03-29 08:26:30.000000000 +0200
+++ dragonegg-2.9-new/Internals.h 1970-01-01 01:00:00.000000000 +0100
@@ -1,866 +0,0 @@
-//=---- Internals.h - Interface between the backend components ----*- C++ -*-=//
-//
-// Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Chris Lattner,
-// Duncan Sands et al.
-//
-// This file is part of DragonEgg.
-//
-// DragonEgg is free software; you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free Software
-// Foundation; either version 2, or (at your option) any later version.
-//
-// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along with
-// DragonEgg; see the file COPYING. If not, write to the Free Software
-// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
-//
-//===----------------------------------------------------------------------===//
-// This file declares the internal interfaces shared among the dragonegg files.
-//===----------------------------------------------------------------------===//
-
-#ifndef DRAGONEGG_INTERNALS_H
-#define DRAGONEGG_INTERNALS_H
-
-// LLVM headers
-#include "llvm/Intrinsics.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SetVector.h"
-#include "llvm/Support/IRBuilder.h"
-#include "llvm/Support/TargetFolder.h"
-
-struct basic_block_def;
-union gimple_statement_d;
-union tree_node;
-
-namespace llvm {
- class Module;
- class GlobalVariable;
- class Function;
- class GlobalValue;
- class BasicBlock;
- class Instruction;
- class AllocaInst;
- class BranchInst;
- class Value;
- class Constant;
- class ConstantInt;
- class Type;
- class FunctionType;
- class TargetMachine;
- class TargetData;
- class DebugInfo;
- template<typename> class AssertingVH;
- template<typename> class TrackingVH;
-}
-using namespace llvm;
-
-typedef IRBuilder<true, TargetFolder> LLVMBuilder;
-
-// Global state.
-
-/// TheModule - This is the current global module that we are compiling into.
-///
-extern llvm::Module *TheModule;
-
-/// TheDebugInfo - This object is responsible for gather all debug information.
-/// If it's value is NULL then no debug information should be gathered.
-extern llvm::DebugInfo *TheDebugInfo;
-
-/// TheTarget - The current target being compiled for.
-///
-extern llvm::TargetMachine *TheTarget;
-
-/// TheFolder - The constant folder to use.
-extern TargetFolder *TheFolder;
-
-/// getTargetData - Return the current TargetData object from TheTarget.
-const TargetData &getTargetData();
-
-/// flag_default_initialize_globals - Whether global variables with no explicit
-/// initial value should be zero initialized.
-extern bool flag_default_initialize_globals;
-
-/// flag_odr - Whether the language being compiled obeys the One Definition Rule
-/// (i.e. if the same function is defined in multiple compilation units, all the
-/// definitions are equivalent).
-extern bool flag_odr;
-
-/// flag_vararg_requires_arguments - Do not consider functions with no arguments
-/// to take a variable number of arguments (...). If set then a function like
-/// "T foo() {}" will be treated like "T foo(void) {}" and not "T foo(...) {}".
-extern bool flag_vararg_requires_arguments;
-
-/// flag_force_vararg_prototypes - Force prototypes to take a variable number of
-/// arguments (...). This is helpful if the language front-end sometimes emits
-/// calls where the call arguments do not match the callee function declaration.
-extern bool flag_force_vararg_prototypes;
-
-/// AttributeUsedGlobals - The list of globals that are marked attribute(used).
-extern SmallSetVector<Constant *,32> AttributeUsedGlobals;
-
-extern Constant* ConvertMetadataStringToGV(const char *str);
-
-/// AddAnnotateAttrsToGlobal - Adds decls that have a
-/// annotate attribute to a vector to be emitted later.
-extern void AddAnnotateAttrsToGlobal(GlobalValue *GV, tree_node *decl);
-
-// Mapping between GCC declarations and LLVM values. The GCC declaration must
-// satisfy HAS_RTL_P.
-
-/// DECL_LLVM - Returns the LLVM declaration of a global variable or function.
-extern Value *make_decl_llvm(tree_node *);
-#define DECL_LLVM(NODE) make_decl_llvm(NODE)
-
-/// SET_DECL_LLVM - Set the DECL_LLVM for NODE to LLVM.
-extern Value *set_decl_llvm(tree_node *, Value *);
-#define SET_DECL_LLVM(NODE, LLVM) set_decl_llvm(NODE, LLVM)
-
-/// DECL_LLVM_IF_SET - The DECL_LLVM for NODE, if it is set, or NULL, if it is
-/// not set.
-extern Value *get_decl_llvm(tree_node *);
-#define DECL_LLVM_IF_SET(NODE) (HAS_RTL_P(NODE) ? get_decl_llvm(NODE) : NULL)
-
-/// DECL_LLVM_SET_P - Returns nonzero if the DECL_LLVM for NODE has already
-/// been set.
-#define DECL_LLVM_SET_P(NODE) (DECL_LLVM_IF_SET(NODE) != NULL)
-
-/// DEFINITION_LLVM - Ensures that the body or initial value of the given GCC
-/// global will be output, and returns a declaration for it.
-Value *make_definition_llvm(tree_node *decl);
-#define DEFINITION_LLVM(NODE) make_definition_llvm(NODE)
-
-// Mapping between GCC declarations and non-negative integers. The GCC
-// declaration must not satisfy HAS_RTL_P.
-
-/// set_decl_index - Associate a non-negative number with the given GCC
-/// declaration.
-int set_decl_index(tree_node *, int);
-
-/// get_decl_index - Get the non-negative number associated with the given GCC
-/// declaration. Returns a negative value if no such association has been made.
-int get_decl_index(tree_node *);
-
-void changeLLVMConstant(Constant *Old, Constant *New);
-void register_ctor_dtor(Function *, int, bool);
-void readLLVMTypesStringTable();
-void writeLLVMTypesStringTable();
-void readLLVMValues();
-void writeLLVMValues();
-void clearTargetBuiltinCache();
-const char *extractRegisterName(tree_node *);
-void handleVisibility(tree_node *decl, GlobalValue *GV);
-Twine getLLVMAssemblerName(tree_node *);
-
-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(tree_node*, unsigned N);
-
-/// TypeConverter - Implement the converter from GCC types to LLVM types.
-///
-class TypeConverter {
- /// ConvertingStruct - If we are converting a RECORD or UNION to an LLVM type
- /// we set this flag to true.
- bool ConvertingStruct;
-
- /// PointersToReresolve - When ConvertingStruct is true, we handling of
- /// POINTER_TYPE and REFERENCE_TYPE is changed to return
- /// opaque*'s instead of recursively calling ConvertType. When this happens,
- /// we add the POINTER_TYPE to this list.
- ///
- std::vector<tree_node*> PointersToReresolve;
-public:
- TypeConverter() : ConvertingStruct(false) {}
-
- /// 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).
- const Type *ConvertType(tree_node *type);
-
- /// GCCTypeOverlapsWithLLVMTypePadding - Return true if the specified GCC type
- /// has any data that overlaps with structure padding in the specified LLVM
- /// type.
- static bool GCCTypeOverlapsWithLLVMTypePadding(tree_node *t, const Type *Ty);
-
-
- /// ConvertFunctionType - Convert the specified FUNCTION_TYPE or METHOD_TYPE
- /// tree to an LLVM type. This does the same thing that ConvertType does, but
- /// it also returns the function's LLVM calling convention and attributes.
- const FunctionType *ConvertFunctionType(tree_node *type,
- tree_node *decl,
- tree_node *static_chain,
- CallingConv::ID &CallingConv,
- AttrListPtr &PAL);
-
- /// ConvertArgListToFnType - Given a DECL_ARGUMENTS list on an GCC tree,
- /// return the LLVM type corresponding to the function. This is useful for
- /// turning "T foo(...)" functions into "T foo(void)" functions.
- const FunctionType *ConvertArgListToFnType(tree_node *type,
- tree_node *arglist,
- tree_node *static_chain,
- CallingConv::ID &CallingConv,
- AttrListPtr &PAL);
-
-private:
- const Type *ConvertRECORD(tree_node *type);
- bool DecodeStructFields(tree_node *Field, StructTypeConversionInfo &Info);
- void DecodeStructBitField(tree_node *Field, StructTypeConversionInfo &Info);
- void SelectUnionMember(tree_node *type, StructTypeConversionInfo &Info);
-};
-
-extern TypeConverter *TheTypeConverter;
-
-/// 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).
-inline const Type *ConvertType(tree_node *type) {
- return TheTypeConverter->ConvertType(type);
-}
-
-/// getDefaultValue - Return the default value to use for a constant or global
-/// that has no value specified. For example in C like languages such variables
-/// are initialized to zero, while in Ada they hold an undefined value.
-inline Constant *getDefaultValue(const Type *Ty) {
- return flag_default_initialize_globals ?
- Constant::getNullValue(Ty) : UndefValue::get(Ty);
-}
-
-/// 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
-/// i16.
-extern const Type *GetUnitType(LLVMContext &C, unsigned NumUnits = 1);
-
-/// GetUnitPointerType - Returns an LLVM pointer type which points to memory one
-/// address unit wide. For example, on a machine which has 16 bit bytes returns
-/// an i16*.
-extern const Type *GetUnitPointerType(LLVMContext &C, unsigned AddrSpace = 0);
-
-/// GetFieldIndex - Return the index of the field in the given LLVM type that
-/// corresponds to the GCC field declaration 'decl'. This means that the LLVM
-/// and GCC fields start in the same byte (if 'decl' is a bitfield, this means
-/// that its first bit is within the byte the LLVM field starts at). Returns
-/// INT_MAX if there is no such LLVM field.
-int GetFieldIndex(tree_node *decl, const Type *Ty);
-
-/// getINTEGER_CSTVal - Return the specified INTEGER_CST value as a uint64_t.
-///
-uint64_t getINTEGER_CSTVal(tree_node *exp);
-
-/// isInt64 - Return true if t is an INTEGER_CST that fits in a 64 bit integer.
-/// If Unsigned is false, returns whether it fits in a int64_t. If Unsigned is
-/// true, returns whether the value is non-negative and fits in a uint64_t.
-/// Always returns false for overflowed constants or if t is NULL.
-bool isInt64(tree_node *t, bool Unsigned);
-
-/// getInt64 - Extract the value of an INTEGER_CST as a 64 bit integer. If
-/// Unsigned is false, the value must fit in a int64_t. If Unsigned is true,
-/// the value must be non-negative and fit in a uint64_t. Must not be used on
-/// overflowed constants. These conditions can be checked by calling isInt64.
-uint64_t getInt64(tree_node *t, bool Unsigned);
-
-/// isPassedByInvisibleReference - Return true if the specified type should be
-/// passed by 'invisible reference'. In other words, instead of passing the
-/// thing by value, pass the address of a temporary.
-bool isPassedByInvisibleReference(tree_node *type);
-
-/// isSequentialCompatible - Return true if the specified gcc array or pointer
-/// type and the corresponding LLVM SequentialType lay out their components
-/// identically in memory, so doing a GEP accesses the right memory location.
-/// We assume that objects without a known size do not.
-extern bool isSequentialCompatible(tree_node *type);
-
-/// OffsetIsLLVMCompatible - Return true if the given field is offset from the
-/// start of the record by a constant amount which is not humongously big.
-extern bool OffsetIsLLVMCompatible(tree_node *field_decl);
-
-/// ArrayLengthOf - Returns the length of the given gcc array type, or ~0ULL if
-/// the array has variable or unknown length.
-extern uint64_t ArrayLengthOf(tree_node *type);
-
-/// isBitfield - Returns whether to treat the specified field as a bitfield.
-bool isBitfield(tree_node *field_decl);
-
-/// getFieldOffsetInBits - Return the bit offset of a FIELD_DECL in a structure.
-extern uint64_t getFieldOffsetInBits(tree_node *field);
-
-/// ValidateRegisterVariable - Check that a static "asm" variable is
-/// well-formed. If not, emit error messages and return true. If so, return
-/// false.
-bool ValidateRegisterVariable(tree_node *decl);
-
-/// MemRef - This struct holds the information needed for a memory access:
-/// a pointer to the memory, its alignment and whether the access is volatile.
-class MemRef {
-public:
- Value *Ptr;
- bool Volatile;
-private:
- unsigned char LogAlign;
-public:
- explicit MemRef() : Ptr(0), Volatile(false), LogAlign(0) {}
- explicit MemRef(Value *P, uint32_t A, bool V) : Ptr(P), Volatile(V) {
- // Forbid alignment 0 along with non-power-of-2 alignment values.
- assert(isPowerOf2_32(A) && "Alignment not a power of 2!");
- LogAlign = Log2_32(A);
- }
-
- uint32_t getAlignment() const {
- return 1U << LogAlign;
- }
-
- void setAlignment(uint32_t A) {
- LogAlign = Log2_32(A);
- }
-};
-
-/// LValue - This struct represents an lvalue in the program. In particular,
-/// the Ptr member indicates the memory that the lvalue lives in. Alignment
-/// is the alignment of the memory (in bytes).If this is a bitfield reference,
-/// BitStart indicates the first bit in the memory that is part of the field
-/// and BitSize indicates the extent.
-///
-/// "LValue" is intended to be a light-weight object passed around by-value.
-class LValue : public MemRef {
-public:
- unsigned char BitStart;
- unsigned char BitSize;
-public:
- explicit LValue() : BitStart(255), BitSize(255) {}
- explicit LValue(MemRef &M) : MemRef(M), BitStart(255), BitSize(255) {}
- LValue(Value *P, uint32_t A, bool V = false) :
- MemRef(P, A, V), BitStart(255), BitSize(255) {}
- LValue(Value *P, uint32_t A, unsigned BSt, unsigned BSi, bool V = false) :
- MemRef(P, A, V), BitStart(BSt), BitSize(BSi) {
- assert(BitStart == BSt && BitSize == BSi &&
- "Bit values larger than 256?");
- }
-
- bool isBitfield() const { return BitStart != 255; }
-};
-
-/// PhiRecord - This struct holds the LLVM PHI node associated with a GCC phi.
-struct PhiRecord {
- gimple_statement_d *gcc_phi;
- PHINode *PHI;
-};
-
-/// TreeToLLVM - An instance of this class is created and used to convert the
-/// body of each function to LLVM.
-///
-class TreeToLLVM {
- // State that is initialized when the function starts.
- const TargetData &TD;
- tree_node *FnDecl;
- Function *Fn;
- BasicBlock *ReturnBB;
- unsigned ReturnOffset;
-
- // State that changes as the function is emitted.
-
- /// Builder - Instruction creator, the location to insert into is always the
- /// same as &Fn->back().
- LLVMBuilder Builder;
-
- // AllocaInsertionPoint - Place to insert alloca instructions. Lazily created
- // and managed by CreateTemporary.
- Instruction *AllocaInsertionPoint;
-
- // SSAInsertionPoint - Place to insert reads corresponding to SSA default
- // definitions.
- Instruction *SSAInsertionPoint;
-
- /// BasicBlocks - Map from GCC to LLVM basic blocks.
- DenseMap<basic_block_def *, BasicBlock*> BasicBlocks;
-
- /// LocalDecls - Map from local declarations to their associated LLVM values.
- DenseMap<tree_node *, AssertingVH<Value> > LocalDecls;
-
- /// PendingPhis - Phi nodes which have not yet been populated with operands.
- SmallVector<PhiRecord, 16> PendingPhis;
-
- // SSANames - Map from GCC ssa names to the defining LLVM value.
- DenseMap<tree_node *, TrackingVH<Value> > SSANames;
-
-public:
-
- //===---------------------- Local Declarations --------------------------===//
-
- /// DECL_LOCAL - Like DECL_LLVM, returns the LLVM declaration of a variable or
- /// function. However DECL_LOCAL can be used with declarations local to the
- /// current function as well as with global declarations.
- Value *make_decl_local(tree_node *);
- #define DECL_LOCAL(NODE) make_decl_local(NODE)
-
- /// DEFINITION_LOCAL - Like DEFINITION_LLVM, ensures that the initial value or
- /// body of a variable or function will be output. However DEFINITION_LOCAL
- /// can be used with declarations local to the current function as well as
- /// with global declarations.
- Value *make_definition_local(tree_node *);
- #define DEFINITION_LOCAL(NODE) make_definition_local(NODE)
-
- /// SET_DECL_LOCAL - Set the DECL_LOCAL for NODE to LLVM.
- Value *set_decl_local(tree_node *, Value *);
- #define SET_DECL_LOCAL(NODE, LLVM) set_decl_local(NODE, LLVM)
-
- /// DECL_LOCAL_IF_SET - The DECL_LOCAL for NODE, if it is set, or NULL, if it
- /// is not set.
- Value *get_decl_local(tree_node *);
- #define DECL_LOCAL_IF_SET(NODE) (HAS_RTL_P(NODE) ? get_decl_local(NODE) : NULL)
-
- /// DECL_LOCAL_SET_P - Returns nonzero if the DECL_LOCAL for NODE has already
- /// been set.
- #define DECL_LOCAL_SET_P(NODE) (DECL_LOCAL_IF_SET(NODE) != NULL)
-
-
-private:
-
- //===---------------------- Exception Handling --------------------------===//
-
- /// NormalInvokes - Mapping from landing pad number to the set of invoke
- /// instructions that unwind to that landing pad.
- SmallVector<SmallVector<InvokeInst *, 8>, 16> NormalInvokes;
-
- /// ExceptionPtrs - Mapping from EH region index to the local holding the
- /// exception pointer for that region.
- SmallVector<AllocaInst *, 16> ExceptionPtrs;
-
- /// ExceptionFilters - Mapping from EH region index to the local holding the
- /// filter value for that region.
- SmallVector<AllocaInst *, 16> ExceptionFilters;
-
- /// FailureBlocks - Mapping from the index of a must-not-throw EH region to
- /// the block containing the failure code for the region (the code that is
- /// run if an exception is thrown in this region).
- SmallVector<BasicBlock *, 16> FailureBlocks;
-
- /// RewindBB - Block containing code that continues unwinding an exception.
- BasicBlock *RewindBB;
-
- /// RewindTmp - Local holding the exception to continue unwinding.
- AllocaInst *RewindTmp;
-
-public:
- TreeToLLVM(tree_node *fndecl);
- ~TreeToLLVM();
-
- /// getFUNCTION_DECL - Return the FUNCTION_DECL node for the current function
- /// being compiled.
- tree_node *getFUNCTION_DECL() const { return FnDecl; }
-
- /// EmitFunction - Convert 'fndecl' to LLVM code.
- Function *EmitFunction();
-
- /// EmitBasicBlock - Convert the given basic block.
- void EmitBasicBlock(basic_block_def *bb);
-
- /// EmitLV - Convert the specified l-value tree node to LLVM code, returning
- /// the address of the result.
- LValue EmitLV(tree_node *exp);
-
- void TODO(tree_node *exp = 0);
-
- /// CastToAnyType - Cast the specified value to the specified type regardless
- /// of the types involved. This is an inferred cast.
- Value *CastToAnyType (Value *V, bool VSigned, const Type *Ty, bool TySigned);
-
- /// CastToUIntType - Cast the specified value to the specified type assuming
- /// that V's type and Ty are integral types. This arbitrates between BitCast,
- /// Trunc and ZExt.
- Value *CastToUIntType(Value *V, const Type *Ty);
-
- /// CastToSIntType - Cast the specified value to the specified type assuming
- /// that V's type and Ty are integral types. This arbitrates between BitCast,
- /// Trunc and SExt.
- Value *CastToSIntType(Value *V, const Type *Ty);
-
- /// CastToFPType - Cast the specified value to the specified type assuming
- /// that V's type and Ty are floating point types. This arbitrates between
- /// BitCast, FPTrunc and FPExt.
- Value *CastToFPType(Value *V, const Type *Ty);
-
- /// CreateAnyAdd - Add two LLVM scalar values with the given GCC type. Does
- /// not support complex numbers. The type is used to set overflow flags.
- Value *CreateAnyAdd(Value *LHS, Value *RHS, tree_node *type);
-
- /// CreateAnyMul - Multiply two LLVM scalar values with the given GCC type.
- /// Does not support complex numbers. The type is used to set overflow flags.
- Value *CreateAnyMul(Value *LHS, Value *RHS, tree_node *type);
-
- /// CreateAnyNeg - Negate an LLVM scalar value with the given GCC type. Does
- /// not support complex numbers. The type is used to set overflow flags.
- Value *CreateAnyNeg(Value *V, tree_node *type);
-
- /// CreateAnySub - Subtract two LLVM scalar values with the given GCC type.
- /// Does not support complex numbers.
- Value *CreateAnySub(Value *LHS, Value *RHS, tree_node *type);
-
- /// CreateTemporary - Create a new alloca instruction of the specified type,
- /// inserting it into the entry block and returning it. The resulting
- /// instruction's type is a pointer to the specified type.
- AllocaInst *CreateTemporary(const Type *Ty, unsigned align=0);
-
- /// CreateTempLoc - Like CreateTemporary, but returns a MemRef.
- MemRef CreateTempLoc(const Type *Ty);
-
- /// EmitAggregateCopy - Copy the elements from SrcLoc to DestLoc, using the
- /// GCC type specified by GCCType to know which elements to copy.
- void EmitAggregateCopy(MemRef DestLoc, MemRef SrcLoc, tree_node *GCCType);
-
- /// EmitAggregate - Store the specified tree node into the location given by
- /// DestLoc.
- void EmitAggregate(tree_node *exp, const MemRef &DestLoc);
-
-private: // Helper functions.
-
- /// StartFunctionBody - Start the emission of 'fndecl', outputing all
- /// declarations for parameters and setting things up.
- void StartFunctionBody();
-
- /// FinishFunctionBody - Once the body of the function has been emitted, this
- /// cleans up and returns the result function.
- Function *FinishFunctionBody();
-
- /// PopulatePhiNodes - Populate generated phi nodes with their operands.
- void PopulatePhiNodes();
-
- /// getBasicBlock - Find or create the LLVM basic block corresponding to BB.
- BasicBlock *getBasicBlock(basic_block_def *bb);
-
- /// getLabelDeclBlock - Lazily get and create a basic block for the specified
- /// label.
- BasicBlock *getLabelDeclBlock(tree_node *LabelDecl);
-
- /// DefineSSAName - Use the given value as the definition of the given SSA
- /// name. Returns the provided value as a convenience.
- Value *DefineSSAName(tree_node *reg, Value *Val);
-
- /// BeginBlock - Add the specified basic block to the end of the function. If
- /// the previous block falls through into it, add an explicit branch.
- void BeginBlock(BasicBlock *BB);
-
- /// EmitAggregateZero - Zero the elements of DestLoc.
- void EmitAggregateZero(MemRef DestLoc, tree_node *GCCType);
-
- /// EmitMemCpy/EmitMemMove/EmitMemSet - Emit an llvm.memcpy/llvm.memmove or
- /// llvm.memset call with the specified operands. Returns DestPtr bitcast
- /// to i8*.
- Value *EmitMemCpy(Value *DestPtr, Value *SrcPtr, Value *Size, unsigned Align);
- Value *EmitMemMove(Value *DestPtr, Value *SrcPtr, Value *Size, unsigned Align);
- Value *EmitMemSet(Value *DestPtr, Value *SrcVal, Value *Size, unsigned Align);
-
- /// EmitLandingPads - Emit EH landing pads.
- void EmitLandingPads();
-
- /// EmitFailureBlocks - Emit the blocks containing failure code executed when
- /// an exception is thrown in a must-not-throw region.
- void EmitFailureBlocks();
-
- /// EmitRewindBlock - Emit the block containing code to continue unwinding an
- /// exception.
- void EmitRewindBlock();
-
- /// EmitDebugInfo - Return true if debug info is to be emitted for current
- /// function.
- bool EmitDebugInfo();
-
-private: // Helpers for exception handling.
-
- /// getLandingPad - Return the landing pad for the given exception handling
- /// region, creating it if necessary.
- BasicBlock *getLandingPad(unsigned RegionNo);
-
- /// getExceptionPtr - Return the local holding the exception pointer for the
- /// given exception handling region, creating it if necessary.
- AllocaInst *getExceptionPtr(unsigned RegionNo);
-
- /// getExceptionFilter - Return the local holding the filter value for the
- /// given exception handling region, creating it if necessary.
- AllocaInst *getExceptionFilter(unsigned RegionNo);
-
- /// getFailureBlock - Return the basic block containing the failure code for
- /// the given exception handling region, creating it if necessary.
- BasicBlock *getFailureBlock(unsigned RegionNo);
-
-private:
- void EmitAutomaticVariableDecl(tree_node *decl);
-
- /// EmitAnnotateIntrinsic - Emits call to annotate attr intrinsic
- void EmitAnnotateIntrinsic(Value *V, tree_node *decl);
-
- /// EmitTypeGcroot - Emits call to make type a gcroot
- void EmitTypeGcroot(Value *V);
-
-private:
-
- //===------------------ Render* - Convert GIMPLE to LLVM ----------------===//
-
- void RenderGIMPLE_ASM(gimple_statement_d *stmt);
- void RenderGIMPLE_ASSIGN(gimple_statement_d *stmt);
- void RenderGIMPLE_CALL(gimple_statement_d *stmt);
- void RenderGIMPLE_COND(gimple_statement_d *stmt);
- void RenderGIMPLE_EH_DISPATCH(gimple_statement_d *stmt);
- void RenderGIMPLE_GOTO(gimple_statement_d *stmt);
- void RenderGIMPLE_RESX(gimple_statement_d *stmt);
- void RenderGIMPLE_RETURN(gimple_statement_d *stmt);
- void RenderGIMPLE_SWITCH(gimple_statement_d *stmt);
-
- // Render helpers.
-
- /// EmitAssignRHS - Convert the RHS of a scalar GIMPLE_ASSIGN to LLVM.
- Value *EmitAssignRHS(gimple_statement_d *stmt);
-
- /// EmitAssignSingleRHS - Helper for EmitAssignRHS. Handles those RHS that
- /// are not register expressions.
- Value *EmitAssignSingleRHS(tree_node *rhs);
-
- /// OutputCallRHS - Convert the RHS of a GIMPLE_CALL.
- Value *OutputCallRHS(gimple_statement_d *stmt, const MemRef *DestLoc);
-
- /// WriteScalarToLHS - Store RHS, a non-aggregate value, into the given LHS.
- void WriteScalarToLHS(tree_node *lhs, Value *Scalar);
-
-private:
-
- //===---------- EmitReg* - Convert register expression to LLVM ----------===//
-
- /// 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.
- const Type *GetRegType(tree_node *type);
-
- /// UselesslyTypeConvert - The useless_type_conversion_p predicate implicitly
- /// defines the GCC middle-end type system. For scalar GCC types inner_type
- /// and outer_type, if 'useless_type_conversion_p(outer_type, inner_type)' is
- /// true then the corresponding LLVM inner and outer types (see GetRegType)
- /// are equal except possibly if they are both pointer types (casts to 'void*'
- /// are considered useless for example) or types derived from pointer types
- /// (vector types with pointer element type are the only possibility here).
- /// This method converts LLVM values of the inner type to the outer type.
- Value *UselesslyTypeConvert(Value *V, const Type *Ty) {
- return Builder.CreateBitCast(V, Ty);
- }
-
- /// EmitRegister - Convert the specified gimple register or local constant of
- /// register type to an LLVM value. Only creates code in the entry block.
- Value *EmitRegister(tree_node *reg);
-
- /// EmitReg_SSA_NAME - Return the defining value of the given SSA_NAME.
- /// Only creates code in the entry block.
- Value *EmitReg_SSA_NAME(tree_node *reg);
-
- // Unary expressions.
- Value *EmitReg_ABS_EXPR(tree_node *op);
- Value *EmitReg_BIT_NOT_EXPR(tree_node *op);
- Value *EmitReg_CONJ_EXPR(tree_node *op);
- Value *EmitReg_CONVERT_EXPR(tree_node *type, tree_node *op);
- Value *EmitReg_NEGATE_EXPR(tree_node *op);
- Value *EmitReg_PAREN_EXPR(tree_node *exp);
- Value *EmitReg_TRUTH_NOT_EXPR(tree_node *type, tree_node *op);
-
- // Comparisons.
-
- /// EmitCompare - Compare LHS with RHS using the appropriate comparison code.
- /// The result is an i1 boolean.
- Value *EmitCompare(tree_node *lhs, tree_node *rhs, unsigned code);
-
- // Binary expressions.
- Value *EmitReg_MinMaxExpr(tree_node *type, tree_node *op0, tree_node *op1,
- unsigned UIPred, unsigned SIPred, unsigned Opc,
- bool isMax);
- Value *EmitReg_RotateOp(tree_node *type, tree_node *op0, tree_node *op1,
- unsigned Opc1, unsigned Opc2);
- Value *EmitReg_ShiftOp(tree_node *op0, tree_node *op1, unsigned Opc);
- Value *EmitReg_TruthOp(tree_node *type, tree_node *op0, tree_node *op1,
- unsigned Opc);
- Value *EmitReg_BIT_AND_EXPR(tree_node *op0, tree_node *op1);
- Value *EmitReg_BIT_IOR_EXPR(tree_node *op0, tree_node *op1);
- Value *EmitReg_BIT_XOR_EXPR(tree_node *op0, tree_node *op1);
- Value *EmitReg_CEIL_DIV_EXPR(tree_node *type, tree_node *op0, tree_node *op1);
- Value *EmitReg_COMPLEX_EXPR(tree_node *op0, tree_node *op1);
- Value *EmitReg_FLOOR_DIV_EXPR(tree_node *type, tree_node *op0,
- tree_node *op1);
- Value *EmitReg_FLOOR_MOD_EXPR(tree_node *type, tree_node *op0,
- tree_node *op1);
- Value *EmitReg_MINUS_EXPR(tree_node *op0, tree_node *op1);
- Value *EmitReg_MULT_EXPR(tree_node *op0, tree_node *op1);
- Value *EmitReg_PLUS_EXPR(tree_node *op0, tree_node *op1);
- Value *EmitReg_POINTER_PLUS_EXPR(tree_node *type, tree_node *op0,
- tree_node *op1);
- Value *EmitReg_RDIV_EXPR(tree_node *op0, tree_node *op1);
- Value *EmitReg_ROUND_DIV_EXPR(tree_node *type, tree_node *op0,
- tree_node *op1);
- Value *EmitReg_TRUNC_DIV_EXPR(tree_node *op0, tree_node *op1, bool isExact);
- Value *EmitReg_TRUNC_MOD_EXPR(tree_node *op0, tree_node *op1);
-
- Value *EmitLoadOfLValue(tree_node *exp);
- Value *EmitOBJ_TYPE_REF(tree_node *exp);
- Value *EmitADDR_EXPR(tree_node *exp);
- Value *EmitCallOf(Value *Callee, gimple_statement_d *stmt,
- const MemRef *DestLoc, const AttrListPtr &PAL);
- CallInst *EmitSimpleCall(StringRef CalleeName, tree_node *ret_type,
- /* arguments */ ...) END_WITH_NULL;
- Value *EmitFieldAnnotation(Value *FieldPtr, tree_node *FieldDecl);
-
- // Inline Assembly and Register Variables.
- Value *EmitReadOfRegisterVariable(tree_node *vardecl);
- void EmitModifyOfRegisterVariable(tree_node *vardecl, Value *RHS);
-
- // Helpers for Builtin Function Expansion.
- void EmitMemoryBarrier(bool ll, bool ls, bool sl, bool ss, bool device);
- Value *BuildVector(const std::vector<Value*> &Elts);
- Value *BuildVector(Value *Elt, ...);
- Value *BuildVectorShuffle(Value *InVec1, Value *InVec2, ...);
- Value *BuildBinaryAtomicBuiltin(gimple_statement_d *stmt, Intrinsic::ID id);
- Value *BuildCmpAndSwapAtomicBuiltin(gimple_statement_d *stmt, tree_node *type,
- bool isBool);
-
- // Builtin Function Expansion.
- bool EmitBuiltinCall(gimple_statement_d *stmt, tree_node *fndecl,
- const MemRef *DestLoc, Value *&Result);
- bool EmitFrontendExpandedBuiltinCall(gimple_statement_d *stmt,
- tree_node *fndecl, const MemRef *DestLoc,
- Value *&Result);
- bool EmitBuiltinUnaryOp(Value *InVal, Value *&Result, Intrinsic::ID Id);
- Value *EmitBuiltinSQRT(gimple_statement_d *stmt);
- Value *EmitBuiltinPOWI(gimple_statement_d *stmt);
- Value *EmitBuiltinPOW(gimple_statement_d *stmt);
- Value *EmitBuiltinLCEIL(gimple_statement_d *stmt);
- Value *EmitBuiltinLFLOOR(gimple_statement_d *stmt);
-
- bool EmitBuiltinConstantP(gimple_statement_d *stmt, Value *&Result);
- bool EmitBuiltinAlloca(gimple_statement_d *stmt, Value *&Result);
- bool EmitBuiltinExpect(gimple_statement_d *stmt, Value *&Result);
- bool EmitBuiltinExtendPointer(gimple_statement_d *stmt, Value *&Result);
- bool EmitBuiltinVAStart(gimple_statement_d *stmt);
- bool EmitBuiltinVAEnd(gimple_statement_d *stmt);
- bool EmitBuiltinVACopy(gimple_statement_d *stmt);
- bool EmitBuiltinMemCopy(gimple_statement_d *stmt, Value *&Result,
- bool isMemMove, bool SizeCheck);
- bool EmitBuiltinMemSet(gimple_statement_d *stmt, Value *&Result,
- bool SizeCheck);
- bool EmitBuiltinBZero(gimple_statement_d *stmt, Value *&Result);
- bool EmitBuiltinPrefetch(gimple_statement_d *stmt);
- bool EmitBuiltinReturnAddr(gimple_statement_d *stmt, Value *&Result,
- bool isFrame);
- bool EmitBuiltinExtractReturnAddr(gimple_statement_d *stmt, Value *&Result);
- bool EmitBuiltinFrobReturnAddr(gimple_statement_d *stmt, Value *&Result);
- bool EmitBuiltinStackSave(gimple_statement_d *stmt, Value *&Result);
- bool EmitBuiltinStackRestore(gimple_statement_d *stmt);
- bool EmitBuiltinEHPointer(gimple_statement_d *stmt, Value *&Result);
- bool EmitBuiltinDwarfCFA(gimple_statement_d *stmt, Value *&Result);
- bool EmitBuiltinDwarfSPColumn(gimple_statement_d *stmt, Value *&Result);
- bool EmitBuiltinEHReturnDataRegno(gimple_statement_d *stmt, Value *&Result);
- bool EmitBuiltinEHReturn(gimple_statement_d *stmt, Value *&Result);
- bool EmitBuiltinInitDwarfRegSizes(gimple_statement_d *stmt, Value *&Result);
- bool EmitBuiltinUnwindInit(gimple_statement_d *stmt, Value *&Result);
- bool EmitBuiltinAdjustTrampoline(gimple_statement_d *stmt, Value *&Result);
- bool EmitBuiltinInitTrampoline(gimple_statement_d *stmt, Value *&Result);
-
- // Complex Math Expressions.
- Value *CreateComplex(Value *Real, Value *Imag, tree_node *elt_type);
- void SplitComplex(Value *Complex, Value *&Real, Value *&Imag,
- tree_node *elt_type);
-
- // L-Value Expressions.
- LValue EmitLV_ARRAY_REF(tree_node *exp);
- LValue EmitLV_BIT_FIELD_REF(tree_node *exp);
- LValue EmitLV_COMPONENT_REF(tree_node *exp);
- LValue EmitLV_DECL(tree_node *exp);
- LValue EmitLV_INDIRECT_REF(tree_node *exp);
- LValue EmitLV_VIEW_CONVERT_EXPR(tree_node *exp);
- LValue EmitLV_WITH_SIZE_EXPR(tree_node *exp);
- LValue EmitLV_XXXXPART_EXPR(tree_node *exp, unsigned Idx);
- LValue EmitLV_SSA_NAME(tree_node *exp);
- LValue EmitLV_TARGET_MEM_REF(tree_node *exp);
-
- // Constant Expressions.
- Value *EmitINTEGER_CST(tree_node *exp);
- Value *EmitREAL_CST(tree_node *exp);
- Value *EmitCONSTRUCTOR(tree_node *exp, const MemRef *DestLoc);
-
-
- // Emit helpers.
-
- /// EmitMinInvariant - The given value is constant in this function. Return
- /// the corresponding LLVM value. Only creates code in the entry block.
- Value *EmitMinInvariant(tree_node *reg);
-
- /// EmitInvariantAddress - The given address is constant in this function.
- /// Return the corresponding LLVM value. Only creates code in the entry block.
- Value *EmitInvariantAddress(tree_node *addr);
-
- /// EmitRegisterConstant - Convert the given global constant of register type
- /// to an LLVM constant. Creates no code, only constants.
- Constant *EmitRegisterConstant(tree_node *reg);
-
- /// EmitComplexRegisterConstant - Turn the given COMPLEX_CST into an LLVM
- /// constant of the corresponding register type.
- Constant *EmitComplexRegisterConstant(tree_node *reg);
-
- /// EmitIntegerRegisterConstant - Turn the given INTEGER_CST into an LLVM
- /// constant of the corresponding register type.
- Constant *EmitIntegerRegisterConstant(tree_node *reg);
-
- /// EmitRealRegisterConstant - Turn the given REAL_CST into an LLVM constant
- /// of the corresponding register type.
- Constant *EmitRealRegisterConstant(tree_node *reg);
-
- /// EmitConstantVectorConstructor - Turn the given constant CONSTRUCTOR into
- /// an LLVM constant of the corresponding vector register type.
- Constant *EmitConstantVectorConstructor(tree_node *reg);
-
- /// EmitVectorRegisterConstant - Turn the given VECTOR_CST into an LLVM
- /// constant of the corresponding register type.
- Constant *EmitVectorRegisterConstant(tree_node *reg);
-
- /// Mem2Reg - Convert a value of in-memory type (that given by ConvertType)
- /// to in-register type (that given by GetRegType). TODO: Eliminate these
- /// methods: "memory" values should never be held in registers. Currently
- /// this is mainly used for marshalling function parameters and return values,
- /// but that should be completely independent of the reg vs mem value logic.
- Value *Mem2Reg(Value *V, tree_node *type, LLVMBuilder &Builder);
- Constant *Mem2Reg(Constant *C, tree_node *type, TargetFolder &Folder);
-
- /// Reg2Mem - Convert a value of in-register type (that given by GetRegType)
- /// to in-memory type (that given by ConvertType). TODO: Eliminate this
- /// method: "memory" values should never be held in registers. Currently
- /// this is mainly used for marshalling function parameters and return values,
- /// but that should be completely independent of the reg vs mem value logic.
- Value *Reg2Mem(Value *V, tree_node *type, LLVMBuilder &Builder);
-
- /// EmitMemory - Convert the specified gimple register or local constant of
- /// register type to an LLVM value with in-memory type (given by ConvertType).
- /// TODO: Eliminate this method, see Mem2Reg and Reg2Mem above.
- Value *EmitMemory(tree_node *reg);
-
- /// LoadRegisterFromMemory - Loads a value of the given scalar GCC type from
- /// the memory location pointed to by Loc. Takes care of adjusting for any
- /// differences between in-memory and in-register types (the returned value
- /// is of in-register type, as returned by GetRegType).
- Value *LoadRegisterFromMemory(MemRef Loc, tree_node *type,
- LLVMBuilder &Builder);
-
- /// StoreRegisterToMemory - Stores the given value to the memory pointed to by
- /// Loc. Takes care of adjusting for any differences between the value's type
- /// (which is the in-register type given by GetRegType) and the in-memory type.
- void StoreRegisterToMemory(Value *V, MemRef Loc, tree_node *type,
- LLVMBuilder &Builder);
-
-private:
- // Optional target defined builtin intrinsic expanding function.
- bool TargetIntrinsicLower(gimple_statement_d *stmt,
- tree_node *fndecl,
- const MemRef *DestLoc,
- Value *&Result,
- const Type *ResultType,
- std::vector<Value*> &Ops);
-
-public:
- // Helper for taking the address of a label.
- Constant *AddressOfLABEL_DECL(tree_node *exp);
-};
-
-#endif /* DRAGONEGG_INTERNALS_H */
diff -r -u -N dragonegg-2.9-old/linux/dragonegg/OS.h dragonegg-2.9-new/linux/dragonegg/OS.h
--- dragonegg-2.9-old/linux/dragonegg/OS.h 1970-01-01 01:00:00.000000000 +0100
+++ dragonegg-2.9-new/linux/dragonegg/OS.h 2011-04-09 00:38:11.339997171 +0200
@@ -0,0 +1,33 @@
+//===------------- OS.h - Linux specific definitions ------------*- C++ -*-===//
+//
+// Copyright (C) 2009, 2010, 2011 Duncan Sands et al.
+//
+// This file is part of DragonEgg.
+//
+// DragonEgg is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free Software
+// Foundation; either version 2, or (at your option) any later version.
+//
+// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along with
+// DragonEgg; see the file COPYING. If not, write to the Free Software
+// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
+//
+//===----------------------------------------------------------------------===//
+// This file provides Linux specific declarations.
+//===----------------------------------------------------------------------===//
+
+#ifndef DRAGONEGG_OS_H
+#define DRAGONEGG_OS_H
+
+/* Yes, we support PIC codegen for linux targets! */
+#define LLVM_SET_TARGET_OPTIONS(argvec) \
+ if (flag_pic) \
+ argvec.push_back ("--relocation-model=pic"); \
+ else \
+ argvec.push_back ("--relocation-model=static");
+
+#endif /* DRAGONEGG_OS_H */
diff -r -u -N dragonegg-2.9-old/linux/OS.h dragonegg-2.9-new/linux/OS.h
--- dragonegg-2.9-old/linux/OS.h 2011-03-10 17:05:54.000000000 +0100
+++ dragonegg-2.9-new/linux/OS.h 1970-01-01 01:00:00.000000000 +0100
@@ -1,33 +0,0 @@
-//===------------- OS.h - Linux specific definitions ------------*- C++ -*-===//
-//
-// Copyright (C) 2009, 2010, 2011 Duncan Sands et al.
-//
-// This file is part of DragonEgg.
-//
-// DragonEgg is free software; you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free Software
-// Foundation; either version 2, or (at your option) any later version.
-//
-// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along with
-// DragonEgg; see the file COPYING. If not, write to the Free Software
-// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
-//
-//===----------------------------------------------------------------------===//
-// This file provides Linux specific declarations.
-//===----------------------------------------------------------------------===//
-
-#ifndef DRAGONEGG_OS_H
-#define DRAGONEGG_OS_H
-
-/* Yes, we support PIC codegen for linux targets! */
-#define LLVM_SET_TARGET_OPTIONS(argvec) \
- if (flag_pic) \
- argvec.push_back ("--relocation-model=pic"); \
- else \
- argvec.push_back ("--relocation-model=static");
-
-#endif /* DRAGONEGG_OS_H */
diff -r -u -N dragonegg-2.9-old/Makefile dragonegg-2.9-new/Makefile
--- dragonegg-2.9-old/Makefile 2011-03-28 21:44:58.000000000 +0200
+++ dragonegg-2.9-new/Makefile 2011-04-09 00:38:11.339997171 +0200
@@ -52,7 +52,7 @@
-MD -MP \
-DIN_GCC -DREVISION=\"$(REVISION)\" \
-DGCC_MAJOR=$(GCC_MAJOR) -DGCC_MINOR=$(GCC_MINOR) \
- -I$(SRC_DIR) -I$(SRC_DIR)/ADT -I$(GCC_PLUGIN_DIR)/include
+ -I$(SRC_DIR)/include -I$(GCC_PLUGIN_DIR)/include
LD_OPTIONS+=$(shell $(LLVM_CONFIG) --ldflags) $(LDFLAGS)
diff -r -u -N dragonegg-2.9-old/Trees.cpp dragonegg-2.9-new/Trees.cpp
--- dragonegg-2.9-old/Trees.cpp 2011-03-10 17:05:54.000000000 +0100
+++ dragonegg-2.9-new/Trees.cpp 2011-04-09 00:38:11.339997171 +0200
@@ -21,7 +21,7 @@
//===----------------------------------------------------------------------===//
// Plugin headers
-#include "Trees.h"
+#include "dragonegg/Trees.h"
// LLVM headers
#include "llvm/ADT/Twine.h"
diff -r -u -N dragonegg-2.9-old/Trees.h dragonegg-2.9-new/Trees.h
--- dragonegg-2.9-old/Trees.h 2011-03-29 12:46:17.000000000 +0200
+++ dragonegg-2.9-new/Trees.h 1970-01-01 01:00:00.000000000 +0100
@@ -1,44 +0,0 @@
-//=---- Trees.h - Utility functions for working with GCC trees ----*- C++ -*-=//
-//
-// Copyright (C) 2010, 2011 Duncan Sands.
-//
-// This file is part of DragonEgg.
-//
-// DragonEgg is free software; you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free Software
-// Foundation; either version 2, or (at your option) any later version.
-//
-// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along with
-// DragonEgg; see the file COPYING. If not, write to the Free Software
-// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
-//
-//===----------------------------------------------------------------------===//
-// This file declares utility functions for working with GCC trees.
-//===----------------------------------------------------------------------===//
-
-#ifndef DRAGONEGG_TREES_H
-#define DRAGONEGG_TREES_H
-
-// System headers
-#include <string>
-
-union tree_node;
-
-/// getDescriptiveName - Return a helpful name for the given tree, or an empty
-/// string if no sensible name was found. These names are used to make the IR
-/// more readable, and have no official status.
-std::string getDescriptiveName(union tree_node *t);
-
-/// hasNUW - Return whether overflowing unsigned operations on this type result
-/// in undefined behaviour.
-bool hasNUW(tree_node *type);
-
-/// hasNSW - Return whether overflowing signed operations on this type result
-/// in undefined behaviour.
-bool hasNSW(tree_node *type);
-
-#endif /* DRAGONEGG_TREES_H */
diff -r -u -N dragonegg-2.9-old/Types.cpp dragonegg-2.9-new/Types.cpp
--- dragonegg-2.9-old/Types.cpp 2011-03-29 08:26:30.000000000 +0200
+++ dragonegg-2.9-new/Types.cpp 2011-04-09 00:38:11.349996956 +0200
@@ -22,10 +22,10 @@
//===----------------------------------------------------------------------===//
// Plugin headers
-#include "ABI.h"
-#include "Trees.h"
+#include "dragonegg/ABI.h"
+#include "dragonegg/Trees.h"
extern "C" {
-#include "cache.h"
+#include "dragonegg/cache.h"
}
// LLVM headers
diff -r -u -N dragonegg-2.9-old/unknown/dragonegg/OS.h dragonegg-2.9-new/unknown/dragonegg/OS.h
--- dragonegg-2.9-old/unknown/dragonegg/OS.h 1970-01-01 01:00:00.000000000 +0100
+++ dragonegg-2.9-new/unknown/dragonegg/OS.h 2011-04-09 00:38:11.349996956 +0200
@@ -0,0 +1 @@
+#error Unknown target operating system
diff -r -u -N dragonegg-2.9-old/unknown/OS.h dragonegg-2.9-new/unknown/OS.h
--- dragonegg-2.9-old/unknown/OS.h 2011-03-10 17:05:54.000000000 +0100
+++ dragonegg-2.9-new/unknown/OS.h 1970-01-01 01:00:00.000000000 +0100
@@ -1 +0,0 @@
-#error Unknown target operating system
diff -r -u -N dragonegg-2.9-old/x86/dragonegg/Target.h dragonegg-2.9-new/x86/dragonegg/Target.h
--- dragonegg-2.9-old/x86/dragonegg/Target.h 1970-01-01 01:00:00.000000000 +0100
+++ dragonegg-2.9-new/x86/dragonegg/Target.h 2011-04-09 00:38:11.349996956 +0200
@@ -0,0 +1,403 @@
+//==----- Target.h - Target hooks for GCC to LLVM conversion -----*- C++ -*-==//
+//
+// Copyright (C) 2007, 2008, 2009, 2010, 2011 Anton Korobeynikov, Duncan Sands
+// et al.
+//
+// This file is part of DragonEgg.
+//
+// DragonEgg is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free Software
+// Foundation; either version 2, or (at your option) any later version.
+//
+// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along with
+// DragonEgg; see the file COPYING. If not, write to the Free Software
+// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
+//
+//===----------------------------------------------------------------------===//
+// This file declares some target-specific hooks for GCC to LLVM conversion.
+//===----------------------------------------------------------------------===//
+
+#ifndef DRAGONEGG_TARGET_H
+#define DRAGONEGG_TARGET_H
+
+/* LLVM specific stuff for supporting calling convention output */
+#define TARGET_ADJUST_LLVM_CC(CC, type) \
+ { \
+ tree_node *type_attributes = TYPE_ATTRIBUTES (type); \
+ if (lookup_attribute ("stdcall", type_attributes)) { \
+ CC = CallingConv::X86_StdCall; \
+ } else if (lookup_attribute("fastcall", type_attributes)) { \
+ CC = CallingConv::X86_FastCall; \
+ } \
+ }
+
+#define TARGET_ADJUST_LLVM_RETATTR(Rattributes, type) \
+ { \
+ tree_node *type_attributes = TYPE_ATTRIBUTES (type); \
+ if (!TARGET_64BIT && (TARGET_SSEREGPARM || \
+ lookup_attribute("sseregparm", type_attributes)))\
+ RAttributes |= Attribute::InReg; \
+ }
+
+/* LLVM specific stuff for converting gcc's `regparm` attribute to LLVM's
+ `inreg` parameter attribute */
+#define LLVM_TARGET_ENABLE_REGPARM
+
+extern "C" int ix86_regparm;
+
+#define LLVM_TARGET_INIT_REGPARM(local_regparm, local_fp_regparm, type) \
+ { \
+ tree_node *attr; \
+ local_regparm = ix86_regparm; \
+ local_fp_regparm = TARGET_SSEREGPARM ? 3 : 0; \
+ attr = lookup_attribute ("regparm", \
+ TYPE_ATTRIBUTES (type)); \
+ if (attr) { \
+ local_regparm = TREE_INT_CST_LOW (TREE_VALUE \
+ (TREE_VALUE (attr))); \
+ } \
+ attr = lookup_attribute("sseregparm", \
+ TYPE_ATTRIBUTES (type)); \
+ if (attr) \
+ local_fp_regparm = 3; \
+ }
+
+#define LLVM_ADJUST_REGPARM_ATTRIBUTE(PAttribute, Type, Size, \
+ local_regparm, \
+ local_fp_regparm) \
+ { \
+ if (!TARGET_64BIT) { \
+ if (TREE_CODE(Type) == REAL_TYPE && \
+ (TYPE_PRECISION(Type)==32 || \
+ TYPE_PRECISION(Type)==64)) { \
+ local_fp_regparm -= 1; \
+ if (local_fp_regparm >= 0) \
+ PAttribute |= Attribute::InReg; \
+ else \
+ local_fp_regparm = 0; \
+ } else if (INTEGRAL_TYPE_P(Type) || \
+ POINTER_TYPE_P(Type)) { \
+ int words = \
+ (Size + BITS_PER_WORD - 1) / BITS_PER_WORD; \
+ local_regparm -= words; \
+ if (local_regparm>=0) \
+ PAttribute |= Attribute::InReg; \
+ else \
+ local_regparm = 0; \
+ } \
+ } \
+ }
+
+#define LLVM_SET_RED_ZONE_FLAG(disable_red_zone) \
+ if (TARGET_64BIT && TARGET_NO_RED_ZONE) \
+ disable_red_zone = 1;
+
+#ifdef DRAGONEGG_ABI_H
+
+/* On x86-32 objects containing SSE vectors are 16 byte aligned, everything
+ else 4. On x86-64 vectors are 8-byte aligned, everything else can
+ be figured out by the back end. */
+#define LLVM_BYVAL_ALIGNMENT(T) \
+ (TYPE_ALIGN(T) / 8)
+
+extern tree_node *llvm_x86_should_return_selt_struct_as_scalar(tree_node *);
+
+/* Structs containing a single data field plus zero-length fields are
+ considered as if they were the type of the data field. On x86-64,
+ if the element type is an MMX vector, return it as double (which will
+ get it into XMM0). */
+
+#define LLVM_SHOULD_RETURN_SELT_STRUCT_AS_SCALAR(X) \
+ llvm_x86_should_return_selt_struct_as_scalar((X))
+
+extern bool llvm_x86_should_pass_aggregate_in_integer_regs(tree_node *,
+ unsigned*, bool*);
+
+/* LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS - Return true if this aggregate
+ value should be passed in integer registers. This differs from the usual
+ handling in that x86-64 passes 128-bit structs and unions which only
+ contain data in the first 64 bits, as 64-bit objects. (These can be
+ created by abusing __attribute__((aligned)). */
+#define LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS(X, Y, Z) \
+ llvm_x86_should_pass_aggregate_in_integer_regs((X), (Y), (Z))
+
+extern const Type *llvm_x86_scalar_type_for_struct_return(tree_node *type,
+ unsigned *Offset);
+
+/* LLVM_SCALAR_TYPE_FOR_STRUCT_RETURN - Return LLVM Type if X can be
+ returned as a scalar, otherwise return NULL. */
+#define LLVM_SCALAR_TYPE_FOR_STRUCT_RETURN(X, Y) \
+ llvm_x86_scalar_type_for_struct_return((X), (Y))
+
+extern const Type *llvm_x86_aggr_type_for_struct_return(tree_node *type);
+
+/* LLVM_AGGR_TYPE_FOR_STRUCT_RETURN - Return LLVM Type if X can be
+ returned as an aggregate, otherwise return NULL. */
+#define LLVM_AGGR_TYPE_FOR_STRUCT_RETURN(X, CC) \
+ llvm_x86_aggr_type_for_struct_return(X)
+
+extern void llvm_x86_extract_multiple_return_value(Value *Src, Value *Dest,
+ bool isVolatile,
+ LLVMBuilder &B);
+
+/* LLVM_EXTRACT_MULTIPLE_RETURN_VALUE - Extract multiple return value from
+ SRC and assign it to DEST. */
+#define LLVM_EXTRACT_MULTIPLE_RETURN_VALUE(Src,Dest,V,B) \
+ llvm_x86_extract_multiple_return_value((Src),(Dest),(V),(B))
+
+extern bool llvm_x86_should_pass_vector_using_byval_attr(tree_node *);
+
+/* On x86-64, vectors which are not MMX nor SSE should be passed byval. */
+#define LLVM_SHOULD_PASS_VECTOR_USING_BYVAL_ATTR(X) \
+ llvm_x86_should_pass_vector_using_byval_attr((X))
+
+extern bool llvm_x86_should_pass_vector_in_integer_regs(tree_node *);
+
+/* On x86-32, vectors which are not MMX nor SSE should be passed as integers. */
+#define LLVM_SHOULD_PASS_VECTOR_IN_INTEGER_REGS(X) \
+ llvm_x86_should_pass_vector_in_integer_regs((X))
+
+extern tree_node *llvm_x86_should_return_vector_as_scalar(tree_node *, bool);
+
+/* The MMX vector v1i64 is returned in EAX and EDX on Darwin. Communicate
+ this by returning i64 here. Likewise, (generic) vectors such as v2i16
+ are returned in EAX.
+ On Darwin x86-64, MMX vectors are returned in XMM0. Communicate this by
+ returning f64. */
+#define LLVM_SHOULD_RETURN_VECTOR_AS_SCALAR(X,isBuiltin)\
+ llvm_x86_should_return_vector_as_scalar((X), (isBuiltin))
+
+extern bool llvm_x86_should_return_vector_as_shadow(tree_node *, bool);
+
+/* MMX vectors v2i32, v4i16, v8i8, v2f32 are returned using sret on Darwin
+ 32-bit. Vectors bigger than 128 are returned using sret. */
+#define LLVM_SHOULD_RETURN_VECTOR_AS_SHADOW(X,isBuiltin)\
+ llvm_x86_should_return_vector_as_shadow((X),(isBuiltin))
+
+extern bool
+llvm_x86_should_not_return_complex_in_memory(tree_node *type);
+
+/* LLVM_SHOULD_NOT_RETURN_COMPLEX_IN_MEMORY - A hook to allow
+ special _Complex handling. Return true if X should be returned using
+ multiple value return instruction. */
+#define LLVM_SHOULD_NOT_RETURN_COMPLEX_IN_MEMORY(X) \
+ llvm_x86_should_not_return_complex_in_memory((X))
+
+extern bool
+llvm_x86_should_pass_aggregate_as_fca(tree_node *type, const Type *);
+
+/* LLVM_SHOULD_PASS_AGGREGATE_AS_FCA - Return true if an aggregate of the
+ specified type should be passed as a first-class aggregate. */
+#ifndef LLVM_SHOULD_PASS_AGGREGATE_AS_FCA
+#define LLVM_SHOULD_PASS_AGGREGATE_AS_FCA(X, TY) \
+ llvm_x86_should_pass_aggregate_as_fca(X, TY)
+#endif
+
+extern bool llvm_x86_should_pass_aggregate_in_memory(tree_node *, const Type *);
+
+#define LLVM_SHOULD_PASS_AGGREGATE_USING_BYVAL_ATTR(X, TY) \
+ llvm_x86_should_pass_aggregate_in_memory(X, TY)
+
+
+extern bool
+llvm_x86_64_should_pass_aggregate_in_mixed_regs(tree_node *, const Type *Ty,
+ std::vector<const Type*>&);
+extern bool
+llvm_x86_32_should_pass_aggregate_in_mixed_regs(tree_node *, const Type *Ty,
+ std::vector<const Type*>&);
+
+#define LLVM_SHOULD_PASS_AGGREGATE_IN_MIXED_REGS(T, TY, CC, E) \
+ (TARGET_64BIT ? \
+ llvm_x86_64_should_pass_aggregate_in_mixed_regs((T), (TY), (E)) : \
+ llvm_x86_32_should_pass_aggregate_in_mixed_regs((T), (TY), (E)))
+
+extern
+bool llvm_x86_64_aggregate_partially_passed_in_regs(std::vector<const Type*>&,
+ std::vector<const Type*>&,
+ bool);
+
+#define LLVM_AGGREGATE_PARTIALLY_PASSED_IN_REGS(E, SE, ISR, CC) \
+ (TARGET_64BIT ? \
+ llvm_x86_64_aggregate_partially_passed_in_regs((E), (SE), (ISR)) : \
+ false)
+
+#endif /* DRAGONEGG_ABI_H */
+
+/* Register class used for passing given 64bit part of the argument.
+ These represent classes as documented by the PS ABI, with the exception
+ of SSESF, SSEDF classes, that are basically SSE class, just gcc will
+ use SF or DFmode move instead of DImode to avoid reformatting penalties.
+
+ Similarly we play games with INTEGERSI_CLASS to use cheaper SImode moves
+ whenever possible (upper half does contain padding).
+ */
+enum x86_64_reg_class
+ {
+ X86_64_NO_CLASS,
+ X86_64_INTEGER_CLASS,
+ X86_64_INTEGERSI_CLASS,
+ X86_64_SSE_CLASS,
+ X86_64_SSESF_CLASS,
+ X86_64_SSEDF_CLASS,
+ X86_64_SSEUP_CLASS,
+ X86_64_X87_CLASS,
+ X86_64_X87UP_CLASS,
+ X86_64_COMPLEX_X87_CLASS,
+ X86_64_MEMORY_CLASS
+ };
+
+/* LLVM_TARGET_INTRINSIC_PREFIX - Specify what prefix this target uses for its
+ * intrinsics.
+ */
+#define LLVM_TARGET_INTRINSIC_PREFIX "x86"
+
+/* LLVM_TARGET_NAME - This specifies the name of the target, which correlates to
+ * the llvm::InitializeXXXTarget() function.
+ */
+#define LLVM_TARGET_NAME X86
+
+/* Turn -march=xx into a CPU type.
+ */
+#define LLVM_SET_SUBTARGET_FEATURES(F) \
+ { if (TARGET_MACHO && ! strcmp (ix86_arch_string, "apple")) \
+ F.setCPU(TARGET_64BIT ? "core2" : "yonah"); \
+ else \
+ F.setCPU(ix86_arch_string); \
+ \
+ if (TARGET_64BIT) \
+ F.AddFeature("64bit"); \
+ else if (target_flags_explicit & OPTION_MASK_ISA_64BIT) \
+ F.AddFeature("64bit", false); \
+ \
+ if (TARGET_MMX) \
+ F.AddFeature("mmx"); \
+ else if (target_flags_explicit & OPTION_MASK_ISA_MMX) \
+ F.AddFeature("mmx", false); \
+ \
+ if (TARGET_3DNOW) \
+ F.AddFeature("3dnow"); \
+ else if (target_flags_explicit & OPTION_MASK_ISA_3DNOW) \
+ F.AddFeature("3dnow", false); \
+ \
+ if (TARGET_3DNOW_A) \
+ F.AddFeature("3dnowa"); \
+ else if (target_flags_explicit & OPTION_MASK_ISA_3DNOW_A) \
+ F.AddFeature("3dnowa", false); \
+ \
+ if (TARGET_SSE) \
+ F.AddFeature("sse"); \
+ else if (target_flags_explicit & OPTION_MASK_ISA_SSE) \
+ F.AddFeature("sse", false); \
+ \
+ if (TARGET_SSE2) \
+ F.AddFeature("sse2"); \
+ else if (target_flags_explicit & OPTION_MASK_ISA_SSE2) \
+ F.AddFeature("sse2", false); \
+ \
+ if (TARGET_SSE3) \
+ F.AddFeature("sse3"); \
+ else if (target_flags_explicit & OPTION_MASK_ISA_SSE3) \
+ F.AddFeature("sse3", false); \
+ \
+ if (TARGET_SSSE3) \
+ F.AddFeature("ssse3"); \
+ else if (target_flags_explicit & OPTION_MASK_ISA_SSSE3) \
+ F.AddFeature("ssse3", false); \
+ \
+ if (TARGET_SSE4_1) \
+ F.AddFeature("sse41"); \
+ else if (target_flags_explicit & OPTION_MASK_ISA_SSE4_1) \
+ F.AddFeature("sse41", false); \
+ \
+ if (TARGET_SSE4_2) \
+ F.AddFeature("sse42"); \
+ else if (target_flags_explicit & OPTION_MASK_ISA_SSE4_2) \
+ F.AddFeature("sse42", false); \
+ \
+ if (TARGET_AVX) \
+ F.AddFeature("avx"); \
+ else if (target_flags_explicit & OPTION_MASK_ISA_AVX) \
+ F.AddFeature("avx", false); \
+ \
+ if (TARGET_FMA) \
+ F.AddFeature("fma3"); \
+ else if (target_flags_explicit & OPTION_MASK_ISA_FMA) \
+ F.AddFeature("fma3", false); \
+ \
+ if (TARGET_SSE4A) \
+ F.AddFeature("sse4a"); \
+ else if (target_flags_explicit & OPTION_MASK_ISA_SSE4A) \
+ F.AddFeature("sse4a", false); \
+ }
+
+#define LLVM_SET_IMPLICIT_FLOAT(flag_no_implicit_float) \
+ if (!TARGET_80387) \
+ flag_no_implicit_float = 1; \
+ else \
+ flag_no_implicit_float = 0;
+
+/* LLVM ABI definition macros. */
+
+/* When -m64 is specified, set the architecture to x86_64-os-blah even if the
+ * compiler was configured for i[3456]86-os-blah.
+ */
+#define LLVM_OVERRIDE_TARGET_ARCH() \
+ (TARGET_64BIT ? "x86_64" : "i386")
+
+/* LLVM_TARGET_INTRINSIC_LOWER - To handle builtins, we want to expand the
+ * invocation into normal LLVM code. If the target can handle the builtin, this
+ * macro should call the target TreeToLLVM::TargetIntrinsicLower method and
+ * return true.This macro is invoked from a method in the TreeToLLVM class.
+ */
+#define LLVM_TARGET_INTRINSIC_LOWER(STMT, FNDECL, DESTLOC, RESULT, DESTTY, OPS) \
+ TargetIntrinsicLower(STMT, FNDECL, DESTLOC, RESULT, DESTTY, OPS);
+
+/* LLVM_GET_REG_NAME - When extracting a register name for a constraint, use
+ the string extracted from the magic symbol built for that register, rather
+ than reg_names. The latter maps both AH and AL to the same thing, which
+ means we can't distinguish them. */
+#define LLVM_GET_REG_NAME(REG_NAME, REG_NUM) __extension__ \
+ ({ const char *nm = (REG_NAME); \
+ if (nm && (*nm == '%' || *nm == '#')) ++nm; \
+ ((!nm || ISDIGIT (*nm)) ? reg_names[REG_NUM] : nm); })
+
+/* LLVM_CANONICAL_ADDRESS_CONSTRAINTS - Valid x86 memory addresses include
+ symbolic values and immediates. Canonicalize GCC's "p" constraint for
+ memory addresses to allow both memory and immediate operands. */
+#define LLVM_CANONICAL_ADDRESS_CONSTRAINTS "im"
+
+/* Propagate code model setting to backend */
+#define LLVM_SET_MACHINE_OPTIONS(argvec) \
+ do { \
+ switch (ix86_cmodel) { \
+ default: \
+ sorry ("code model %<%s%> not supported yet", \
+ ix86_cmodel_string); \
+ break; \
+ case CM_SMALL: \
+ case CM_SMALL_PIC: \
+ argvec.push_back("--code-model=small"); \
+ break; \
+ case CM_KERNEL: \
+ argvec.push_back("--code-model=kernel"); \
+ break; \
+ case CM_MEDIUM: \
+ case CM_MEDIUM_PIC: \
+ argvec.push_back("--code-model=medium"); \
+ break; \
+ case CM_32: \
+ argvec.push_back("--code-model=default"); \
+ break; \
+ } \
+ if (TARGET_OMIT_LEAF_FRAME_POINTER) \
+ argvec.push_back("--disable-non-leaf-fp-elim"); \
+ \
+ if (ix86_force_align_arg_pointer) \
+ argvec.push_back("-force-align-stack"); \
+ } while (0)
+
+#endif /* DRAGONEGG_TARGET_H */
diff -r -u -N dragonegg-2.9-old/x86/Target.cpp dragonegg-2.9-new/x86/Target.cpp
--- dragonegg-2.9-old/x86/Target.cpp 2011-03-10 17:05:54.000000000 +0100
+++ dragonegg-2.9-new/x86/Target.cpp 2011-04-09 00:38:11.359996741 +0200
@@ -22,8 +22,8 @@
//===----------------------------------------------------------------------===//
// Plugin headers
-#include "ABI.h"
-#include "Target.h"
+#include "dragonegg/ABI.h"
+#include "dragonegg/Target.h"
// LLVM headers
#include "llvm/Module.h"
diff -r -u -N dragonegg-2.9-old/x86/Target.h dragonegg-2.9-new/x86/Target.h
--- dragonegg-2.9-old/x86/Target.h 2011-03-10 17:05:54.000000000 +0100
+++ dragonegg-2.9-new/x86/Target.h 1970-01-01 01:00:00.000000000 +0100
@@ -1,403 +0,0 @@
-//==----- Target.h - Target hooks for GCC to LLVM conversion -----*- C++ -*-==//
-//
-// Copyright (C) 2007, 2008, 2009, 2010, 2011 Anton Korobeynikov, Duncan Sands
-// et al.
-//
-// This file is part of DragonEgg.
-//
-// DragonEgg is free software; you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free Software
-// Foundation; either version 2, or (at your option) any later version.
-//
-// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along with
-// DragonEgg; see the file COPYING. If not, write to the Free Software
-// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
-//
-//===----------------------------------------------------------------------===//
-// This file declares some target-specific hooks for GCC to LLVM conversion.
-//===----------------------------------------------------------------------===//
-
-#ifndef DRAGONEGG_TARGET_H
-#define DRAGONEGG_TARGET_H
-
-/* LLVM specific stuff for supporting calling convention output */
-#define TARGET_ADJUST_LLVM_CC(CC, type) \
- { \
- tree_node *type_attributes = TYPE_ATTRIBUTES (type); \
- if (lookup_attribute ("stdcall", type_attributes)) { \
- CC = CallingConv::X86_StdCall; \
- } else if (lookup_attribute("fastcall", type_attributes)) { \
- CC = CallingConv::X86_FastCall; \
- } \
- }
-
-#define TARGET_ADJUST_LLVM_RETATTR(Rattributes, type) \
- { \
- tree_node *type_attributes = TYPE_ATTRIBUTES (type); \
- if (!TARGET_64BIT && (TARGET_SSEREGPARM || \
- lookup_attribute("sseregparm", type_attributes)))\
- RAttributes |= Attribute::InReg; \
- }
-
-/* LLVM specific stuff for converting gcc's `regparm` attribute to LLVM's
- `inreg` parameter attribute */
-#define LLVM_TARGET_ENABLE_REGPARM
-
-extern "C" int ix86_regparm;
-
-#define LLVM_TARGET_INIT_REGPARM(local_regparm, local_fp_regparm, type) \
- { \
- tree_node *attr; \
- local_regparm = ix86_regparm; \
- local_fp_regparm = TARGET_SSEREGPARM ? 3 : 0; \
- attr = lookup_attribute ("regparm", \
- TYPE_ATTRIBUTES (type)); \
- if (attr) { \
- local_regparm = TREE_INT_CST_LOW (TREE_VALUE \
- (TREE_VALUE (attr))); \
- } \
- attr = lookup_attribute("sseregparm", \
- TYPE_ATTRIBUTES (type)); \
- if (attr) \
- local_fp_regparm = 3; \
- }
-
-#define LLVM_ADJUST_REGPARM_ATTRIBUTE(PAttribute, Type, Size, \
- local_regparm, \
- local_fp_regparm) \
- { \
- if (!TARGET_64BIT) { \
- if (TREE_CODE(Type) == REAL_TYPE && \
- (TYPE_PRECISION(Type)==32 || \
- TYPE_PRECISION(Type)==64)) { \
- local_fp_regparm -= 1; \
- if (local_fp_regparm >= 0) \
- PAttribute |= Attribute::InReg; \
- else \
- local_fp_regparm = 0; \
- } else if (INTEGRAL_TYPE_P(Type) || \
- POINTER_TYPE_P(Type)) { \
- int words = \
- (Size + BITS_PER_WORD - 1) / BITS_PER_WORD; \
- local_regparm -= words; \
- if (local_regparm>=0) \
- PAttribute |= Attribute::InReg; \
- else \
- local_regparm = 0; \
- } \
- } \
- }
-
-#define LLVM_SET_RED_ZONE_FLAG(disable_red_zone) \
- if (TARGET_64BIT && TARGET_NO_RED_ZONE) \
- disable_red_zone = 1;
-
-#ifdef DRAGONEGG_ABI_H
-
-/* On x86-32 objects containing SSE vectors are 16 byte aligned, everything
- else 4. On x86-64 vectors are 8-byte aligned, everything else can
- be figured out by the back end. */
-#define LLVM_BYVAL_ALIGNMENT(T) \
- (TYPE_ALIGN(T) / 8)
-
-extern tree_node *llvm_x86_should_return_selt_struct_as_scalar(tree_node *);
-
-/* Structs containing a single data field plus zero-length fields are
- considered as if they were the type of the data field. On x86-64,
- if the element type is an MMX vector, return it as double (which will
- get it into XMM0). */
-
-#define LLVM_SHOULD_RETURN_SELT_STRUCT_AS_SCALAR(X) \
- llvm_x86_should_return_selt_struct_as_scalar((X))
-
-extern bool llvm_x86_should_pass_aggregate_in_integer_regs(tree_node *,
- unsigned*, bool*);
-
-/* LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS - Return true if this aggregate
- value should be passed in integer registers. This differs from the usual
- handling in that x86-64 passes 128-bit structs and unions which only
- contain data in the first 64 bits, as 64-bit objects. (These can be
- created by abusing __attribute__((aligned)). */
-#define LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS(X, Y, Z) \
- llvm_x86_should_pass_aggregate_in_integer_regs((X), (Y), (Z))
-
-extern const Type *llvm_x86_scalar_type_for_struct_return(tree_node *type,
- unsigned *Offset);
-
-/* LLVM_SCALAR_TYPE_FOR_STRUCT_RETURN - Return LLVM Type if X can be
- returned as a scalar, otherwise return NULL. */
-#define LLVM_SCALAR_TYPE_FOR_STRUCT_RETURN(X, Y) \
- llvm_x86_scalar_type_for_struct_return((X), (Y))
-
-extern const Type *llvm_x86_aggr_type_for_struct_return(tree_node *type);
-
-/* LLVM_AGGR_TYPE_FOR_STRUCT_RETURN - Return LLVM Type if X can be
- returned as an aggregate, otherwise return NULL. */
-#define LLVM_AGGR_TYPE_FOR_STRUCT_RETURN(X, CC) \
- llvm_x86_aggr_type_for_struct_return(X)
-
-extern void llvm_x86_extract_multiple_return_value(Value *Src, Value *Dest,
- bool isVolatile,
- LLVMBuilder &B);
-
-/* LLVM_EXTRACT_MULTIPLE_RETURN_VALUE - Extract multiple return value from
- SRC and assign it to DEST. */
-#define LLVM_EXTRACT_MULTIPLE_RETURN_VALUE(Src,Dest,V,B) \
- llvm_x86_extract_multiple_return_value((Src),(Dest),(V),(B))
-
-extern bool llvm_x86_should_pass_vector_using_byval_attr(tree_node *);
-
-/* On x86-64, vectors which are not MMX nor SSE should be passed byval. */
-#define LLVM_SHOULD_PASS_VECTOR_USING_BYVAL_ATTR(X) \
- llvm_x86_should_pass_vector_using_byval_attr((X))
-
-extern bool llvm_x86_should_pass_vector_in_integer_regs(tree_node *);
-
-/* On x86-32, vectors which are not MMX nor SSE should be passed as integers. */
-#define LLVM_SHOULD_PASS_VECTOR_IN_INTEGER_REGS(X) \
- llvm_x86_should_pass_vector_in_integer_regs((X))
-
-extern tree_node *llvm_x86_should_return_vector_as_scalar(tree_node *, bool);
-
-/* The MMX vector v1i64 is returned in EAX and EDX on Darwin. Communicate
- this by returning i64 here. Likewise, (generic) vectors such as v2i16
- are returned in EAX.
- On Darwin x86-64, MMX vectors are returned in XMM0. Communicate this by
- returning f64. */
-#define LLVM_SHOULD_RETURN_VECTOR_AS_SCALAR(X,isBuiltin)\
- llvm_x86_should_return_vector_as_scalar((X), (isBuiltin))
-
-extern bool llvm_x86_should_return_vector_as_shadow(tree_node *, bool);
-
-/* MMX vectors v2i32, v4i16, v8i8, v2f32 are returned using sret on Darwin
- 32-bit. Vectors bigger than 128 are returned using sret. */
-#define LLVM_SHOULD_RETURN_VECTOR_AS_SHADOW(X,isBuiltin)\
- llvm_x86_should_return_vector_as_shadow((X),(isBuiltin))
-
-extern bool
-llvm_x86_should_not_return_complex_in_memory(tree_node *type);
-
-/* LLVM_SHOULD_NOT_RETURN_COMPLEX_IN_MEMORY - A hook to allow
- special _Complex handling. Return true if X should be returned using
- multiple value return instruction. */
-#define LLVM_SHOULD_NOT_RETURN_COMPLEX_IN_MEMORY(X) \
- llvm_x86_should_not_return_complex_in_memory((X))
-
-extern bool
-llvm_x86_should_pass_aggregate_as_fca(tree_node *type, const Type *);
-
-/* LLVM_SHOULD_PASS_AGGREGATE_AS_FCA - Return true if an aggregate of the
- specified type should be passed as a first-class aggregate. */
-#ifndef LLVM_SHOULD_PASS_AGGREGATE_AS_FCA
-#define LLVM_SHOULD_PASS_AGGREGATE_AS_FCA(X, TY) \
- llvm_x86_should_pass_aggregate_as_fca(X, TY)
-#endif
-
-extern bool llvm_x86_should_pass_aggregate_in_memory(tree_node *, const Type *);
-
-#define LLVM_SHOULD_PASS_AGGREGATE_USING_BYVAL_ATTR(X, TY) \
- llvm_x86_should_pass_aggregate_in_memory(X, TY)
-
-
-extern bool
-llvm_x86_64_should_pass_aggregate_in_mixed_regs(tree_node *, const Type *Ty,
- std::vector<const Type*>&);
-extern bool
-llvm_x86_32_should_pass_aggregate_in_mixed_regs(tree_node *, const Type *Ty,
- std::vector<const Type*>&);
-
-#define LLVM_SHOULD_PASS_AGGREGATE_IN_MIXED_REGS(T, TY, CC, E) \
- (TARGET_64BIT ? \
- llvm_x86_64_should_pass_aggregate_in_mixed_regs((T), (TY), (E)) : \
- llvm_x86_32_should_pass_aggregate_in_mixed_regs((T), (TY), (E)))
-
-extern
-bool llvm_x86_64_aggregate_partially_passed_in_regs(std::vector<const Type*>&,
- std::vector<const Type*>&,
- bool);
-
-#define LLVM_AGGREGATE_PARTIALLY_PASSED_IN_REGS(E, SE, ISR, CC) \
- (TARGET_64BIT ? \
- llvm_x86_64_aggregate_partially_passed_in_regs((E), (SE), (ISR)) : \
- false)
-
-#endif /* DRAGONEGG_ABI_H */
-
-/* Register class used for passing given 64bit part of the argument.
- These represent classes as documented by the PS ABI, with the exception
- of SSESF, SSEDF classes, that are basically SSE class, just gcc will
- use SF or DFmode move instead of DImode to avoid reformatting penalties.
-
- Similarly we play games with INTEGERSI_CLASS to use cheaper SImode moves
- whenever possible (upper half does contain padding).
- */
-enum x86_64_reg_class
- {
- X86_64_NO_CLASS,
- X86_64_INTEGER_CLASS,
- X86_64_INTEGERSI_CLASS,
- X86_64_SSE_CLASS,
- X86_64_SSESF_CLASS,
- X86_64_SSEDF_CLASS,
- X86_64_SSEUP_CLASS,
- X86_64_X87_CLASS,
- X86_64_X87UP_CLASS,
- X86_64_COMPLEX_X87_CLASS,
- X86_64_MEMORY_CLASS
- };
-
-/* LLVM_TARGET_INTRINSIC_PREFIX - Specify what prefix this target uses for its
- * intrinsics.
- */
-#define LLVM_TARGET_INTRINSIC_PREFIX "x86"
-
-/* LLVM_TARGET_NAME - This specifies the name of the target, which correlates to
- * the llvm::InitializeXXXTarget() function.
- */
-#define LLVM_TARGET_NAME X86
-
-/* Turn -march=xx into a CPU type.
- */
-#define LLVM_SET_SUBTARGET_FEATURES(F) \
- { if (TARGET_MACHO && ! strcmp (ix86_arch_string, "apple")) \
- F.setCPU(TARGET_64BIT ? "core2" : "yonah"); \
- else \
- F.setCPU(ix86_arch_string); \
- \
- if (TARGET_64BIT) \
- F.AddFeature("64bit"); \
- else if (target_flags_explicit & OPTION_MASK_ISA_64BIT) \
- F.AddFeature("64bit", false); \
- \
- if (TARGET_MMX) \
- F.AddFeature("mmx"); \
- else if (target_flags_explicit & OPTION_MASK_ISA_MMX) \
- F.AddFeature("mmx", false); \
- \
- if (TARGET_3DNOW) \
- F.AddFeature("3dnow"); \
- else if (target_flags_explicit & OPTION_MASK_ISA_3DNOW) \
- F.AddFeature("3dnow", false); \
- \
- if (TARGET_3DNOW_A) \
- F.AddFeature("3dnowa"); \
- else if (target_flags_explicit & OPTION_MASK_ISA_3DNOW_A) \
- F.AddFeature("3dnowa", false); \
- \
- if (TARGET_SSE) \
- F.AddFeature("sse"); \
- else if (target_flags_explicit & OPTION_MASK_ISA_SSE) \
- F.AddFeature("sse", false); \
- \
- if (TARGET_SSE2) \
- F.AddFeature("sse2"); \
- else if (target_flags_explicit & OPTION_MASK_ISA_SSE2) \
- F.AddFeature("sse2", false); \
- \
- if (TARGET_SSE3) \
- F.AddFeature("sse3"); \
- else if (target_flags_explicit & OPTION_MASK_ISA_SSE3) \
- F.AddFeature("sse3", false); \
- \
- if (TARGET_SSSE3) \
- F.AddFeature("ssse3"); \
- else if (target_flags_explicit & OPTION_MASK_ISA_SSSE3) \
- F.AddFeature("ssse3", false); \
- \
- if (TARGET_SSE4_1) \
- F.AddFeature("sse41"); \
- else if (target_flags_explicit & OPTION_MASK_ISA_SSE4_1) \
- F.AddFeature("sse41", false); \
- \
- if (TARGET_SSE4_2) \
- F.AddFeature("sse42"); \
- else if (target_flags_explicit & OPTION_MASK_ISA_SSE4_2) \
- F.AddFeature("sse42", false); \
- \
- if (TARGET_AVX) \
- F.AddFeature("avx"); \
- else if (target_flags_explicit & OPTION_MASK_ISA_AVX) \
- F.AddFeature("avx", false); \
- \
- if (TARGET_FMA) \
- F.AddFeature("fma3"); \
- else if (target_flags_explicit & OPTION_MASK_ISA_FMA) \
- F.AddFeature("fma3", false); \
- \
- if (TARGET_SSE4A) \
- F.AddFeature("sse4a"); \
- else if (target_flags_explicit & OPTION_MASK_ISA_SSE4A) \
- F.AddFeature("sse4a", false); \
- }
-
-#define LLVM_SET_IMPLICIT_FLOAT(flag_no_implicit_float) \
- if (!TARGET_80387) \
- flag_no_implicit_float = 1; \
- else \
- flag_no_implicit_float = 0;
-
-/* LLVM ABI definition macros. */
-
-/* When -m64 is specified, set the architecture to x86_64-os-blah even if the
- * compiler was configured for i[3456]86-os-blah.
- */
-#define LLVM_OVERRIDE_TARGET_ARCH() \
- (TARGET_64BIT ? "x86_64" : "i386")
-
-/* LLVM_TARGET_INTRINSIC_LOWER - To handle builtins, we want to expand the
- * invocation into normal LLVM code. If the target can handle the builtin, this
- * macro should call the target TreeToLLVM::TargetIntrinsicLower method and
- * return true.This macro is invoked from a method in the TreeToLLVM class.
- */
-#define LLVM_TARGET_INTRINSIC_LOWER(STMT, FNDECL, DESTLOC, RESULT, DESTTY, OPS) \
- TargetIntrinsicLower(STMT, FNDECL, DESTLOC, RESULT, DESTTY, OPS);
-
-/* LLVM_GET_REG_NAME - When extracting a register name for a constraint, use
- the string extracted from the magic symbol built for that register, rather
- than reg_names. The latter maps both AH and AL to the same thing, which
- means we can't distinguish them. */
-#define LLVM_GET_REG_NAME(REG_NAME, REG_NUM) __extension__ \
- ({ const char *nm = (REG_NAME); \
- if (nm && (*nm == '%' || *nm == '#')) ++nm; \
- ((!nm || ISDIGIT (*nm)) ? reg_names[REG_NUM] : nm); })
-
-/* LLVM_CANONICAL_ADDRESS_CONSTRAINTS - Valid x86 memory addresses include
- symbolic values and immediates. Canonicalize GCC's "p" constraint for
- memory addresses to allow both memory and immediate operands. */
-#define LLVM_CANONICAL_ADDRESS_CONSTRAINTS "im"
-
-/* Propagate code model setting to backend */
-#define LLVM_SET_MACHINE_OPTIONS(argvec) \
- do { \
- switch (ix86_cmodel) { \
- default: \
- sorry ("code model %<%s%> not supported yet", \
- ix86_cmodel_string); \
- break; \
- case CM_SMALL: \
- case CM_SMALL_PIC: \
- argvec.push_back("--code-model=small"); \
- break; \
- case CM_KERNEL: \
- argvec.push_back("--code-model=kernel"); \
- break; \
- case CM_MEDIUM: \
- case CM_MEDIUM_PIC: \
- argvec.push_back("--code-model=medium"); \
- break; \
- case CM_32: \
- argvec.push_back("--code-model=default"); \
- break; \
- } \
- if (TARGET_OMIT_LEAF_FRAME_POINTER) \
- argvec.push_back("--disable-non-leaf-fp-elim"); \
- \
- if (ix86_force_align_arg_pointer) \
- argvec.push_back("-force-align-stack"); \
- } while (0)
-
-#endif /* DRAGONEGG_TARGET_H */