| 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), |
| - >_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), |
| + >_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 */ |